ref: d7ad068d56bdec30805a36a9973f5924ad00641b
author: Sigrid Haflínudóttir <[email protected]>
date: Fri Jun 5 12:38:13 EDT 2020
first dirty version of the port
--- /dev/null
+++ b/COPYING.txt
@@ -1,0 +1,345 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+++ b/README.md
@@ -1,0 +1,19 @@
+# minivmac
+
+This is a 9front port of minivmac. You can check out https://cancel.fm/hyperjam to see what you can run with it after installing.
+
+## Installing
+
+Clone the repo, run `./install.rc`. That's it. Now you have `games/vmac` and `games/vmac2`.
+
+Currently `vMac.ROM` (or `MacII.ROM`) are required, you can plumb it while the emulator is running.
+
+## Plumbing
+
+```
+type is text
+data matches '([.a-zA-Z¡-0-9_/+\-]*[a-zA-Z¡-0-9_/+\-])\.(dsk|rom|ROM|DSK)'
+arg isfile $0
+plumb to minivmac
+plumb start minivmac $file
+```
--- /dev/null
+++ b/README.txt
@@ -1,0 +1,21 @@
+MnvM_b36: README
+Paul C. Pratt
+www.gryphel.com
+July 27, 2005
+
+
+MnvM_b36 is the build system for Mini vMac,
+a miniature Macintosh emulator.
+
+Further information may be found at
+"https://www.gryphel.com/c/minivmac/".
+
+
+You can redistribute MnvM_b36 and/or modify it under the terms
+of version 2 of the GNU General Public License as published by
+the Free Software Foundation. See the included file COPYING.
+
+MnvM_b36 is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+license for more details.
--- /dev/null
+++ b/extras/mydriver/disk/README.txt
@@ -1,0 +1,32 @@
+Mini vMac: mydriver/README
+Paul C. Pratt
+www.gryphel.com
+February 23, 2002
+
+The mydriver folder contains source code
+for a replacement disk driver that is patched
+into the emulated rom.
+
+The compiled driver is already in ROMEMDEV.c
+(the initialization of sony_driver variable),
+so this source code is not needed for building
+Mini vMac. It is only needed if you want
+to change this driver.
+
+To compile the driver, use MPW commands
+such as:
+
+set srcdir hd4:Topaz:MinivMac:mydriver:
+asm -case on {srcdir}mydriver.a -o {srcdir}mydriver.a.o
+c {srcdir}mydriver.c -r -b -mbg off -opt full -o {srcdir}mydriver.c.o
+link {srcdir}mydriver.a.o {srcdir}mydriver.c.o -rt DRVR=128 -o {srcdir}mydriver
+
+Then you can use ResEdit to copy the hex data out
+of the DRVR 128 resource, format it a bit, and
+replace the initialization data of the variable
+sony_driver in the file ROMEMDEV.c
+
+(note: this is using the old c compiler, to use
+the current c compiler, use:
+SC {srcdir}mydriver.c -w 17 -proto strict -b -mbg off -opt all -o {srcdir}mydriver.c.o
+)
--- /dev/null
+++ b/extras/mydriver/disk/mydriver.a
@@ -1,0 +1,302 @@
+; mydriver.a
+;
+; Copyright (C) 2004 Paul C. Pratt
+;
+; You can redistribute this file and/or modify it under the terms
+; of version 2 of the GNU General Public License as published by
+; the Free Software Foundation. You should have received a copy
+; of the license along with this file; see the file COPYING.
+;
+; This file is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; license for more details.
+
+; most of this is adapted from sample source code from Apple.
+
+FakeSonyDriver MAIN EXPORT
+ BLANKS ON
+ STRING ASIS
+
+kqLink EQU 0
+kqType EQU 4
+kioTrap EQU 6
+kioCmdAddr EQU 8
+kioCompletion EQU 12
+kioResult EQU 16
+kioNamePtr EQU 18
+kioVRefNum EQU 22
+kioRefNum EQU 24
+kcsCode EQU 26
+kcsParam EQU 28
+kioBuffer EQU 32 ; Buffer to store data into
+kioReqCount EQU 36 ; Requested Number of Bytes
+kioActCount EQU 40 ; Actual Number of Bytes obtained
+kioPosMode EQU 44 ; Positioning Mode
+kioPosOffset EQU 46 ; Position Offset
+
+killCode EQU 1 ; KillIO requested
+noQueueBit EQU 9 ; trap word modifier
+JIODone EQU $08FC
+
+kCmndSonyPrime EQU $0001
+kCmndSonyControl EQU $0002
+kCmndSonyStatus EQU $0003
+kCmndSonyClose EQU $0004
+kCmndSonyOpenA EQU $0005
+kCmndSonyOpenB EQU $0006
+kCmndSonyOpenC EQU $0007
+kCmndSonyMount EQU $0008
+
+DHeader
+DFlags DC.W $4F00 ; need lock, responds to all requests
+DDelay DC.W 0 ; none
+DEMask DC.W 0 ; DA event mask
+DMenu DC.W 0 ; no menu
+ DC.W DOpen - DHeader ; offset to Open
+ DC.W DPrime - DHeader ; offset to Prime
+ DC.W DControl - DHeader ; offset to Control
+ DC.W DStatus - DHeader ; offset to Status
+ DC.W DClose - DHeader ; offset to Close
+Name DC.B 5 ; length of name
+ DC.B '.Sony'
+ ALIGN 2 ; word alignment
+
+DPrime
+ MOVEM.L A0-A1, -(SP) ; push ParmBlkPtr, DCtlPtr for C
+ SUBQ #2, A7 ; result code
+ MOVE.W #kCmndSonyPrime, -(A7)
+ BRA.B DPrimeStatusCommon
+
+DControl
+ MOVEM.L A0-A1, -(SP) ; push ParmBlkPtr, DCtlPtr for C
+ SUBQ #2, A7 ; result code
+ MOVE.W #kCmndSonyControl, -(A7)
+
+ LEA TailData, A0
+ MOVE.L (A0)+, -(A7)
+ MOVEA.L (A0), A0
+ MOVE.L A7, (A0)
+
+ ADDA.W #6, A7
+ MOVE.W (A7)+, D0 ; save result code
+ MOVEM.L (SP)+, A0-A1 ; restore ParmBlkPtr, DCtlPtr
+ CMPI.W #killCode,kcsCode(A0) ; test for KillIO call (special case)
+ BNE.B IOReturn
+ RTS ; KillIO must always return via RTS
+
+DStatus
+ MOVEM.L A0-A1, -(SP) ; push ParmBlkPtr, DCtlPtr for C
+ SUBQ #2, A7 ; result code
+ MOVE.W #kCmndSonyStatus, -(A7)
+DPrimeStatusCommon
+
+ LEA TailData, A0
+ MOVE.L (A0)+, -(A7)
+ MOVEA.L (A0), A0
+ MOVE.L A7, (A0)
+
+ ADDA.W #6, A7
+ MOVE.W (A7)+, D0 ; save result code
+ MOVEM.L (SP)+, A0-A1 ; restore ParmBlkPtr, DCtlPtr
+
+IOReturn
+ MOVE.W kioTrap(A0),D1
+ BTST #noQueueBit,D1 ; immediate calls are not queued, and must RTS
+ BEQ.B @Queued ; branch if queued
+
+@NotQueued
+ TST.W D0 ; test asynchronous return result
+ BLE.B @ImmedRTS ; result must be <= 0
+ CLR.W D0 ; "in progress" result (> 0) not passed back
+
+@ImmedRTS
+ MOVE.W D0,kioResult(A0) ; for immediate calls you must explicitly
+ ; place the result in the ioResult field
+ RTS
+
+@Queued
+ TST.W D0 ; test asynchronous return result
+ BLE.B @MyIODone ; I/O is complete if result <= 0
+ CLR.W D0 ; "in progress" result (> 0) not passed back
+ RTS
+
+@MyIODone
+ MOVE.L JIODone,-(SP) ; push IODone jump vector onto stack
+ RTS
+
+DClose
+ MOVEM.L A0-A1, -(SP) ; push ParmBlkPtr, DCtlPtr for C
+ SUBQ #2, A7 ; result code
+ MOVE.W #kCmndSonyClose, -(A7)
+
+ LEA TailData, A0
+ MOVE.L (A0)+, -(A7)
+ MOVEA.L (A0), A0
+ MOVE.L A7, (A0)
+
+ ADDA.W #6, A7
+ MOVE.W (A7)+, D0 ; save result code
+ MOVEM.L (SP)+, A0-A1 ; restore ParmBlkPtr, DCtlPtr
+ RTS
+
+DUpdate
+ MOVEM.L D0-D2/A0-A1,-(SP)
+ MOVE.L 20(A7),D0 ; data = what was on top of stack before 5 registers pushed
+
+ SUBQ #4, A7 ; room for eventMsg
+ MOVE.L D0,-(A7) ; data
+ SUBQ #2, A7 ; room for result code
+ MOVE.W #kCmndSonyMount, -(A7)
+
+ LEA TailData, A0
+ MOVE.L (A0)+, -(A7)
+ MOVEA.L (A0), A0
+ MOVE.L A7, (A0)
+
+ ADDA.W #6, A7
+ MOVE.W (A7)+, D1 ; result code
+ ADDQ #4, A7 ; skip over data
+ MOVE.L (A7)+, D0 ; eventMsg
+ TST.W D1 ; result code
+ BNE.S @1
+ MOVEA.W #$0007,A0
+ DC.W $A02F ; _PostEvent
+@1
+
+ MOVEM.L (SP)+,D0-D2/A0-A1
+ ADDA.W #4,A7 ; remove arguments from stack
+ RTE
+
+MyAddDrive64k
+
+; This is only needed for the 64k ROM.
+
+DrvQHdr EQU 776
+RomBase EQU $00400000
+
+ Move.L D0,6(A0)
+ Lea.L (DrvQHdr),A1
+ Jmp (RomBase + 2848)
+
+
+NullTaskProc
+ RTS
+
+DOpen
+ MOVEM.L D3-D7/A3,-(A7)
+ MOVEM.L A0-A1, -(SP) ; push ParmBlkPtr, DCtlPtr for C
+
+ SUBQ #6, A7 ; room for result code, L
+ MOVE.W #kCmndSonyOpenA, -(A7)
+
+ LEA TailData, A0
+ MOVE.L (A0)+, -(A7)
+ MOVEA.L (A0), A0
+ MOVE.L A7, (A0)
+
+ ADDA.W #6, A7
+ MOVE.W (A7)+, D0 ; result code
+ MOVE.L (A7)+, D7 ; L
+
+ CMPI.W #$FFCF,D0
+ BNE.S @1
+ ; driver already open, change to no error and leave
+ CLR.W D0
+ BRA @2
+@1
+ TST.W D0
+ BNE @2
+ MOVE.L D7,D0
+ DC.W $A71E ; _NewPtr ,Sys,Clear
+ MOVEA.L A0,A3
+ MOVE.L A3,D0
+ BEQ @6
+
+ SUBA #16, A7 ; room for various results
+ MOVE.L A3, -(A7)
+ MOVE.L D7, -(A7)
+ SUBQ #2, A7 ; room for result code
+ MOVE.W #kCmndSonyOpenB, -(A7)
+
+ LEA TailData, A0
+ MOVE.L (A0)+, -(A7)
+ MOVEA.L (A0), A0
+ MOVE.L A7, (A0)
+
+ ADDA.W #6, A7
+ MOVE.W (A7)+, D0 ; result code
+ ADDA.W #8, A7
+ MOVE.L (A7)+, D7 ; dvl
+ MOVEQ #$00, D3
+ MOVE.W (A7)+, D3 ; step
+ MOVE.W (A7)+, D4 ; n
+ MOVE.W (A7)+, D6 ; i
+ MOVE.W (A7)+, D5 ; driver
+ MOVEA.L (A7)+, A3 ; NullTask
+
+ TST.W D0
+ BNE.S @2
+
+ MOVE.L A3,D0
+ BEQ.S @3
+
+ ; There is apparently a bug in the time manager
+ ; in System 6.0.8, which will cause a crash
+ ; if there are no installed time
+ ; tasks. So create a time task, since
+ ; real disk driver does.
+
+ LEA NullTaskProc,A0 ; id: 102
+ MOVE.L A0,$0006(A3)
+ MOVEA.L A3,A0
+ DC.W $A058 ; _InsTime
+ BRA.S @4
+@3
+ LEA MyAddDrive64k,A0 ; id: 106
+ MOVE.W #$A04E,D0
+ DC.W $A047 ; _SetTrapAddress
+ BRA.S @4
+@5
+ MOVEA.L D7,A0
+
+ MOVE.W D6,D0 ; drive number in high word
+ SWAP D0
+ MOVE.W D5,D0 ; driver in low word
+
+ DC.W $A04E ; _AddDrive
+ ADD.L D3,D7
+ ADDQ.W #$1,D6
+@4
+ DBF D4, @5
+
+ PEA DUpdate
+ SUBQ #2, A7 ; room for result code
+ MOVE.W #kCmndSonyOpenC, -(A7)
+
+ LEA TailData, A0
+ MOVE.L (A0)+, -(A7)
+ MOVEA.L (A0), A0
+ MOVE.L A7, (A0)
+
+ ADDA.W #6, A7
+ MOVE.W (A7)+, D0 ; result code
+ ADDA.W #4, A7
+
+@2
+ ; result code should be in D0 when reach here
+
+ MOVEM.L (A7)+, A0-A1 ; restore ParmBlkPtr, DCtlPtr
+ MOVEM.L (A7)+, D3-D7/A3
+
+ RTS ; open is always immediate, must return via RTS
+@6
+ ; _NewPtr failed
+ MOVE.W #-1, D0
+ BRA.S @2
+
+TailData
+
+ ENDMAIN
+
+ END
--- /dev/null
+++ b/extras/mydriver/video/firmware.a
@@ -1,0 +1,277 @@
+ STRING C
+ MACHINE MC68020
+ PRINT OFF
+ INCLUDE 'SlotEqu.a'
+ INCLUDE 'VideoEqu.a'
+ INCLUDE 'Traps.a'
+ INCLUDE 'SysEqu.a'
+ INCLUDE 'SysErr.a'
+ PRINT ON
+
+VideoDeclROM MAIN
+
+;========================================================================================
+
+; General Directives
+
+ BLANKS ON
+ STRING ASIS
+
+kCmndVideoSetIntEnbl EQU $0003
+kCmndVideoClearInt EQU $0004
+kCmndVideoStatus EQU $0005
+kCmndVideoControl EQU $0006
+
+;========================================================================================
+; Local Vars, definitions, etc...
+;========================================================================================
+
+;This is device storage, a handle to which is stored in the dCtlStorage field of the DCE.
+
+saveSQElPtr EQU 0 ; the SQ element pointer (for
+ ; _SIRemove
+dCtlSize EQU saveSQElPtr+4 ; size of the dCtlStorage
+
+;========================================================================================
+; Video Driver Header
+;========================================================================================
+
+VidDrvr
+ DC.W $4C00 ; ctl,status,needsLock
+ DC.W 0, 0, 0 ; not an ornament
+
+;Entry point offset table
+
+ DC.W VideoOpen - VidDrvr ; open routine
+ DC.W VidDrvr - VidDrvr ; no prime
+ DC.W VideoCtl - VidDrvr ; control
+ DC.W VideoStatus - VidDrvr ; status
+ DC.W VideoClose - VidDrvr ; close
+
+VideoTitle
+ STRING Pascal
+ DC.W '.Display_Video_Sample'
+ STRING ASIS
+ ALIGN 2 ; make sure we're aligned
+ DC.W 0 ; version-0
+
+;========================================================================================
+;VideoOpen allocates private storage for the device in the DCE and locks
+; it down for perpetuity. It installs the interrupt handler and enables
+; the interrupts. It also sets the default gamma table included in the driver.
+;
+;Entry:
+; A0 = param block pointer
+; A1 = DCE pointer
+;
+;Locals:
+; A2 = Saved param block pointer
+; A3 = Saved DCE pointer
+; A4 = Saved interrupt handler ptr
+;========================================================================================
+
+;Save registers
+VideoOpen
+ MOVE.L A0, A2 ; A2 <- param block pointer
+ MOVE.L A1, A3 ; A3 <- DCE pointer
+
+;Allocate private storage
+ MOVEQ #dCtlSize, D0 ; get size of parameters
+ _ResrvMem ,SYS ; make room as low as possible
+ MOVEQ #dCtlSize, D0 ; get size of parameters
+ _NewHandle ,SYS,CLEAR ; get some memory for private
+ ; storage
+ BNE OpError ;=> return an error in open
+ MOVE.L A0, dCtlStorage(A3) ; saved returned handle in DCE
+ _HLock ; and lock it down
+
+;Get and install the interrupt handler
+ LEA BeginIH, A4 ; Save point to interrupt handler
+ MOVEQ #SlotIntQElement.sqHDSize,D0 ; allocate a slot queue element
+ _NewPtr ,SYS,CLEAR ; get it from system heap cleared
+ BNE OpError
+ MOVE.W #SIQType, SlotIntQElement.sqType(A0) ; setup queue ID
+ MOVE.L A4, SlotIntQElement.sqAddr(A0) ; setup int routine address
+ MOVE.L A3, SlotIntQElement.sqParm(A0) ; save slot base addr as A3 parm
+ CLR.L D0
+ MOVE.B dctlSlot(A3), D0 ; setup slot #
+ _SIntInstall ; and do install
+ BNE.S OpError
+
+;Save SQElPtr for removal
+ MOVE.L dCtlStorage(A3), A1 ; Get point to private storage
+ MOVE.L (A1), A1
+ MOVE.L A0, saveSQElPtr(A1) ; Save the SQ element pointer
+
+;Enable interrupts
+
+ MOVE.W #1, -(A7) ; enabled
+ SUBQ #2, A7 ; result code
+ MOVE.W #kCmndVideoSetIntEnbl, -(A7)
+ LEA TailData, A0
+ MOVE.L (A0)+, -(A7)
+ MOVEA.L (A0), A0
+ MOVE.L A7, (A0)
+ ADDA.W #10, A7
+
+ MOVEQ #0, D0 ; no error
+ BRA.S EndOpen
+
+; Error
+OpError
+ MOVE.L #openErr, D0 ; say can't open driver
+EndOpen
+ RTS
+
+;========================================================================================
+; The interrupt handler for the board
+;========================================================================================
+
+; On entry A1 contains DCE
+
+; wrong! : "D0-D3/A0-A3 have been preserved."
+; (comment from Apples sample code.)
+; must preserve registers except A1/D0
+
+BeginIH
+ MOVE.L A0, -(A7)
+
+ ; clear interrupt from card
+
+ SUBQ #2, A7 ; result code
+ MOVE.W #kCmndVideoClearInt, -(A7)
+
+ LEA TailData, A0
+ MOVE.L (A0)+, -(A7)
+ MOVEA.L (A0), A0
+ MOVE.L A7, (A0)
+
+ ADDQ.W #8, A7
+
+ MOVE.L dctlDevBase(A1), D0 ; D0 = $Fsxxxxxx
+ ROL.L #8, D0 ; D0 <- $xxxxxxFs Convert the
+ ; address into
+ AND #$0F, D0 ; D0 <- $xxxx000x the slot
+ ; number
+ MOVE.L JVBLTask, A0 ; call the VBL task manager
+ JSR (A0) ; with slot # in D0
+
+ MOVE.L (A7)+, A0
+ MOVEQ #1, D0 ; signal that int was serviced
+ RTS ; and return to caller
+
+;========================================================================================
+;
+;VideoClose releases the device's private storage.
+;
+;Entry:
+; A0 = param block pointer
+; A1 = DCE pointer
+;
+;Locals:
+; A2 = Saved param block pointer
+; A3 = Saved DCE pointer
+; A4 = Temporary
+;
+;========================================================================================
+
+VideoClose
+
+ MOVE.L A3, -(A7) ; save
+ MOVE.L dCtlStorage(A1), A3; Get pointer to private storage
+
+ MOVE.W #0, -(A7) ; disabled
+ SUBQ #2, A7 ; result code
+ MOVE.W #kCmndVideoSetIntEnbl, -(A7)
+ LEA TailData, A0
+ MOVE.L (A0)+, -(A7)
+ MOVEA.L (A0), A0
+ MOVE.L A7, (A0)
+ ADDA.W #10, A7
+
+ MOVE.L (A3), A0
+ MOVE.L saveSQElPtr(A0), A0 ; Get the SQ element pointer
+ _SIntRemove ; Remove the interrupt handler
+
+ MOVE.L A3, A0 ; Dispose of the private storage
+ _DisposHandle
+ MOVEQ #0, D0 ; get error into D0
+
+ MOVE.L (A7)+, A3 ; restore A3
+ RTS ; return to caller
+
+;========================================================================================
+;
+;Video Driver Control Call Handler.
+;
+; Entry:
+; A0 = param block pointer
+; A1 = DCE pointer
+; Uses:
+; A2 = cs paramaters (i.e. A2 <- csParam(A0)) (must be preserved)
+; A3 = scratch (doesn't need to be preserved)
+; A4 = scratch (must be preserved)
+; D0-D3 = scratch (don't need to be preserved)
+;
+; Exit: D0 = error code
+;
+;========================================================================================
+
+;Decode the call
+VideoCtl
+ MOVE.L A0, -(A7)
+ SUBQ #2, A7 ; result code
+ MOVE.W #kCmndVideoControl, -(A7)
+ BRA.S VideoStatusControlCommon
+
+;========================================================================================
+;
+;Video DriverStatus Call Handler. Right now there are three calls:
+;
+; (2) GetMode
+; (4) GetPage
+; (5) GetPageBase
+;
+; Entry:
+; A0 = param block
+; A1 = DCE pointer
+; Uses:
+; A2 = cs paramaters (i.e. A2 <- csParam(A0)) (must be preserved)
+; A3 = scratch (doesn't need to be preserved)
+; D0-D3 = scratch (don't need to be preserved)
+;
+; Exit: D0 = error code
+;
+;========================================================================================
+
+VideoStatus
+ MOVE.L A0, -(A7)
+ SUBQ #2, A7 ; result code
+ MOVE.W #kCmndVideoStatus, -(A7)
+VideoStatusControlCommon
+ LEA TailData, A0
+ MOVE.L (A0)+, -(A7)
+ MOVEA.L (A0), A0
+ MOVE.L A7, (A0)
+
+ ADDA.W #6, A7
+ MOVE.W (A7)+, D0 ; save result code
+ MOVE.L (A7)+, A0 ; restore A0
+
+;========================================================================================
+; Exit from control or status
+;========================================================================================
+
+ BTST #NoQueueBit,ioTrap(A0) ;no queue bit set?
+ BEQ.S GoIODone ;=> no, not immediate
+ RTS ;otherwise, it was an immediate call
+
+GoIODone
+ MOVE.L JIODone,A0 ;get the IODone address
+ JMP (A0)
+
+TailData
+
+ ENDP
+
+ END
--- /dev/null
+++ b/extras/trans.txt
@@ -1,0 +1,32 @@
+# Some source files are simple transformations of other source
+# files. Here are some MPW scripts to help keep them in sync.
+
+Set x "rd:t1.txt"
+
+
+Catenate "{my_project_d}"data:src:VIAEMDEV.c > "{x}"
+Open "{x}"
+Set CaseSensitive 1
+Find � "{x}"
+Replace -c � /'VIA1'/ 'VIA2' "{x}"
+Find � "{x}"
+Replace -c � /'VIAEMDEV'/ 'VIA2EMDV' "{x}"
+Find � "{x}"
+Replace -c � /'0x04'([0-9A-FX][0-9A-FX])�1/ '0x05'�1 "{x}"
+Unset SearchType
+
+Compare "{my_project_d}"data:src:VIA2EMDV.c "{x}"
+
+
+Catenate "{my_project_d}"data:src:VIA2EMDV.c > "{x}"
+Open "{x}"
+Set CaseSensitive 1
+Find � "{x}"
+Replace -c � /'VIA2EMDV'/ 'VIAEMDEV' "{x}"
+Find � "{x}"
+Replace -c � /'VIA2'/ 'VIA1' "{x}"
+Find � "{x}"
+Replace -c � /'0x05'([0-9A-FX][0-9A-FX])�1/ '0x04'�1 "{x}"
+Unset SearchType
+
+Compare "{my_project_d}"data:src:VIAEMDEV.c "{x}"
--- /dev/null
+++ b/install.rc
@@ -1,0 +1,13 @@
+#!/bin/rc
+rfork ne
+
+cd setup
+mk clean
+mk all
+cd ..
+rm -rf bld cfg
+./setup/6.out -t 9x64 -an vmac | my_project_d='' my_obj_d='' rc
+mk install
+rm -rf bld cfg
+./setup/6.out -t 9x64 -an vmac2 -m II | my_project_d='' my_obj_d='' rc
+mk install
--- /dev/null
+++ b/setup/BLDUTIL3.i
@@ -1,0 +1,1252 @@
+/*
+ BLDUTIL3.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ BuiLD system UTILities part 3
+*/
+
+
+#define src_d_name "src"
+#define cfg_d_name "cfg"
+
+#define obj_d_name "bld"
+ /* not "obj", so as to work in freebsd make */
+
+LOCALVAR blnr HaveAltSrc;
+
+LOCALPROC WritepDtString(void)
+{
+ WriteCStrToDestFile((char *)pDt);
+}
+
+LOCALPROC WriteMaintainerName(void)
+{
+ WriteCStrToDestFile(kMaintainerName);
+}
+
+LOCALPROC WriteHomePage(void)
+{
+ WriteCStrToDestFile(kStrHomePage);
+}
+
+/* end of default value of options */
+
+LOCALPROC WriteVersionStr(void)
+{
+ WriteDec2CharToOutput(MajorVersion);
+ WriteCStrToDestFile(".");
+ WriteDec2CharToOutput(MinorVersion);
+}
+
+LOCALPROC WriteAppVariationStr(void)
+{
+ WriteCStrToDestFile(vVariationName);
+}
+
+LOCALPROC WriteAppCopyrightYearStr(void)
+{
+ WriteCStrToDestFile(kStrCopyrightYear);
+}
+
+LOCALPROC WriteGetInfoString(void)
+{
+ WriteAppVariationStr();
+ WriteCStrToDestFile(", Copyright ");
+ WriteAppCopyrightYearStr();
+ WriteCStrToDestFile(" maintained by ");
+ WriteMaintainerName();
+ WriteCStrToDestFile(".");
+}
+
+LOCALPROC WriteLProjName(void)
+{
+ WriteCStrToDestFile(GetLProjName(gbo_lang));
+}
+
+/* --- XML utilities --- */
+
+LOCALPROC WriteXMLtagBegin(char *s)
+{
+ WriteCStrToDestFile("<");
+ WriteCStrToDestFile(s);
+ WriteCStrToDestFile(">");
+}
+
+LOCALPROC WriteXMLtagEnd(char *s)
+{
+ WriteCStrToDestFile("</");
+ WriteCStrToDestFile(s);
+ WriteCStrToDestFile(">");
+}
+
+LOCALPROC WriteBeginXMLtagLine(char *s)
+{
+ WriteBgnDestFileLn();
+ WriteXMLtagBegin(s);
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+}
+
+LOCALPROC WriteEndXMLtagLine(char *s)
+{
+ --DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteXMLtagEnd(s);
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteXMLtagBeginValEndLine(char *t, char *v)
+{
+ WriteBgnDestFileLn();
+ WriteXMLtagBegin(t);
+ WriteCStrToDestFile(v);
+ WriteXMLtagEnd(t);
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteXMLtagBeginProcValEndLine(char *t, MyProc v)
+{
+ WriteBgnDestFileLn();
+ WriteXMLtagBegin(t);
+ v();
+ WriteXMLtagEnd(t);
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteXMLtaggedLines(char *s, MyProc p)
+{
+ WriteBeginXMLtagLine(s);
+ if (NULL != p) {
+ p();
+ }
+ WriteEndXMLtagLine(s);
+}
+
+LOCALPROC WriteXMLtaglinewithprops(char *s, MyProc p)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<");
+ WriteCStrToDestFile(s);
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ if (NULL != p) {
+ p();
+ }
+ --DestFileIndent;
+ WriteDestFileLn("/>");
+}
+
+LOCALPROC WriteXMLtaggedLinesWithProps(char *s, MyProc pp, MyProc p)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<");
+ WriteCStrToDestFile(s);
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ if (NULL != pp) {
+ pp();
+ }
+ WriteDestFileLn(">");
+ if (NULL != p) {
+ p();
+ }
+ WriteEndXMLtagLine(s);
+}
+
+LOCALPROC WriteXMLtaggedLinesWith1LnProps(char *s, MyProc pp, MyProc p)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<");
+ WriteCStrToDestFile(s);
+ if (NULL != pp) {
+ pp();
+ }
+ WriteCStrToDestFile(">");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ if (NULL != p) {
+ p();
+ }
+ WriteEndXMLtagLine(s);
+}
+
+/* --- end XML utilities --- */
+
+/* --- c preprocessor utilities --- */
+
+LOCALPROC WriteCompCondBool(char *s, blnr v)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define ");
+ WriteCStrToDestFile(s);
+ if (v) {
+ WriteCStrToDestFile(" 1");
+ } else {
+ WriteCStrToDestFile(" 0");
+ }
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteDefineUimr(char *s, uimr v)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define ");
+ WriteCStrToDestFile(s);
+ WriteSpaceToDestFile();
+ WriteUnsignedToOutput(v);
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteCDefQuote(char *s, MyProc p)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define ");
+ WriteCStrToDestFile(s);
+ WriteSpaceToDestFile();
+ WriteQuoteToDestFile();
+ p();
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteWrongCNFGGLOB(void)
+{
+ WriteDestFileLn("#error \"wrong CNFGGLOB.h\"");
+}
+
+LOCALPROC WriteCheckPreDef(char *s)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#ifndef ");
+ WriteCStrToDestFile(s);
+ WriteEndDestFileLn();
+ WriteWrongCNFGGLOB();
+ WriteDestFileLn("#endif");
+}
+
+LOCALPROC WriteCheckPreNDef(char *s)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#ifdef ");
+ WriteCStrToDestFile(s);
+ WriteEndDestFileLn();
+ WriteWrongCNFGGLOB();
+ WriteDestFileLn("#endif");
+}
+
+/* --- end c preprocessor utilities --- */
+
+LOCALPROC WritePathInDirToDestFile0(MyProc p, MyProc ps,
+ blnr isdir)
+{
+ switch (cur_ide) {
+ case gbk_ide_mpw:
+ case gbk_ide_mw8:
+ if (p != NULL) {
+ p();
+ } else {
+ WriteCStrToDestFile(":");
+ }
+ ps();
+ if (isdir) {
+ WriteCStrToDestFile(":");
+ }
+ break;
+ case gbk_ide_bgc:
+ case gbk_ide_mvc:
+ case gbk_ide_cyg:
+ case gbk_ide_xcd:
+ case gbk_ide_snc:
+ case gbk_ide_dkp:
+ case gbk_ide_ccc:
+ case gbk_ide_9pc:
+ if (p != NULL) {
+ p();
+ }
+ ps();
+ if (isdir) {
+ WriteCStrToDestFile("/");
+ }
+ break;
+ case gbk_ide_msv:
+ case gbk_ide_lcc:
+ case gbk_ide_dmc:
+ case gbk_ide_plc:
+ if (p != NULL) {
+ p();
+ WriteBackSlashToDestFile();
+ } else {
+ if (gbk_ide_lcc == cur_ide) {
+ if (! UseCmndLine) {
+ WriteCStrToDestFile("c:\\output\\");
+ }
+ } else if ((gbk_ide_msv == cur_ide)
+ && (ide_vers >= 7100)
+ && (ide_vers < 10000))
+ {
+ WriteCStrToDestFile(".\\");
+ }
+ }
+ ps();
+ break;
+ case gbk_ide_mgw:
+ if (p != NULL) {
+ p();
+ WriteCStrToDestFile("/");
+ }
+ ps();
+ break;
+ case gbk_ide_dvc:
+ if (p != NULL) {
+ p();
+ if (UseCmndLine) {
+ WriteCStrToDestFile("/");
+ } else {
+ WriteBackSlashToDestFile();
+ }
+ }
+ ps();
+ break;
+ }
+}
+
+LOCALPROC WriteFileInDirToDestFile0(MyProc p, MyProc ps)
+{
+ WritePathInDirToDestFile0(p, ps, falseblnr);
+}
+
+LOCALPROC WriteSubDirToDestFile(MyProc p, MyProc ps)
+{
+ WritePathInDirToDestFile0(p, ps, trueblnr);
+}
+
+LOCALPROC Write_toplevel_f_ToDestFile(MyProc ps)
+{
+ WritePathInDirToDestFile0(NULL, ps, falseblnr);
+}
+
+LOCALPROC Write_toplevel_d_ToDestFile(MyProc ps)
+{
+ WritePathInDirToDestFile0(NULL, ps, trueblnr);
+}
+
+LOCALPROC Write_src_d_Name(void)
+{
+ WriteCStrToDestFile(src_d_name);
+}
+
+LOCALPROC Write_src_d_ToDestFile(void)
+{
+ Write_toplevel_d_ToDestFile(Write_src_d_Name);
+}
+
+LOCALPROC Write_cfg_d_Name(void)
+{
+ WriteCStrToDestFile(cfg_d_name);
+}
+
+LOCALPROC Write_cfg_d_ToDestFile(void)
+{
+ Write_toplevel_d_ToDestFile(Write_cfg_d_Name);
+}
+
+LOCALPROC Write_obj_d_Name(void)
+{
+ WriteCStrToDestFile(obj_d_name);
+}
+
+LOCALPROC Write_obj_d_ToDestFile(void)
+{
+ Write_toplevel_d_ToDestFile(Write_obj_d_Name);
+}
+
+LOCALPROC WriteLProjFolderName(void)
+{
+ WriteLProjName();
+ WriteCStrToDestFile(".lproj");
+}
+
+LOCALPROC WriteLProjFolderPath(void)
+{
+ WriteSubDirToDestFile(Write_cfg_d_ToDestFile,
+ WriteLProjFolderName);
+}
+
+LOCALPROC WriteStrAppAbbrev(void)
+{
+ WriteCStrToDestFile(vStrAppAbbrev);
+}
+
+LOCALPROC WriteAppNameStr(void)
+{
+ WriteStrAppAbbrev();
+ switch (gbo_targfam) {
+ case gbk_targfam_mach:
+ case gbk_targfam_carb:
+ if (HaveMacBundleApp) {
+ WriteCStrToDestFile(".app");
+ }
+ break;
+ case gbk_targfam_mswn:
+ case gbk_targfam_wnce:
+ case gbk_targfam_cygw:
+ WriteCStrToDestFile(".exe");
+ break;
+ case gbk_targfam_lnds:
+ WriteCStrToDestFile(".nds");
+ break;
+ default:
+ break;
+ }
+}
+
+LOCALPROC WriteAppNamePath(void)
+{
+ if (HaveMacBundleApp) {
+ Write_toplevel_d_ToDestFile(WriteAppNameStr);
+ } else {
+ Write_toplevel_f_ToDestFile(WriteAppNameStr);
+ }
+}
+
+LOCALPROC WriteStrAppUnabrevName(void)
+{
+ WriteCStrToDestFile(kStrAppName);
+}
+
+LOCALPROC Write_contents_d_Name(void)
+{
+ WriteCStrToDestFile("Contents");
+}
+
+LOCALPROC Write_machocontents_d_ToDestFile(void)
+{
+ WriteSubDirToDestFile(WriteAppNamePath,
+ Write_contents_d_Name);
+}
+
+LOCALPROC Write_macos_d_Name(void)
+{
+ WriteCStrToDestFile("MacOS");
+}
+
+LOCALPROC Write_machomac_d_ToDestFile(void)
+{
+ WriteSubDirToDestFile(Write_machocontents_d_ToDestFile,
+ Write_macos_d_Name);
+}
+
+LOCALPROC Write_resources_d_Name(void)
+{
+ WriteCStrToDestFile("Resources");
+}
+
+LOCALPROC Write_machores_d_ToDestFile(void)
+{
+ WriteSubDirToDestFile(Write_machocontents_d_ToDestFile,
+ Write_resources_d_Name);
+}
+
+LOCALPROC WriteBinElfObjName(void)
+{
+ WriteStrAppAbbrev();
+ WriteCStrToDestFile(".elf");
+}
+
+LOCALPROC WriteBinElfObjObjPath(void)
+{
+ WriteFileInDirToDestFile0(Write_obj_d_ToDestFile,
+ WriteBinElfObjName);
+}
+
+LOCALPROC WriteBinArmObjName(void)
+{
+ WriteStrAppAbbrev();
+ WriteCStrToDestFile(".arm9");
+}
+
+LOCALPROC WriteBinArmObjObjPath(void)
+{
+ WriteFileInDirToDestFile0(Write_obj_d_ToDestFile,
+ WriteBinArmObjName);
+}
+
+LOCALPROC Write_machobinpath_ToDestFile(void)
+{
+ if (HaveMacBundleApp) {
+ WriteFileInDirToDestFile0(Write_machomac_d_ToDestFile,
+ WriteStrAppAbbrev);
+ } else {
+ WriteAppNamePath();
+ }
+}
+
+LOCALPROC Write_tmachobun_d_Name(void)
+{
+ WriteCStrToDestFile("AppTemp");
+}
+
+LOCALPROC Write_tmachobun_d_ToDestFile(void)
+{
+ Write_toplevel_d_ToDestFile(Write_tmachobun_d_Name);
+}
+
+LOCALPROC Write_tmachocontents_d_ToDestFile(void)
+{
+ WriteSubDirToDestFile(Write_tmachobun_d_ToDestFile,
+ Write_contents_d_Name);
+}
+
+LOCALPROC Write_tmachomac_d_ToDestFile(void)
+{
+ WriteSubDirToDestFile(Write_tmachocontents_d_ToDestFile,
+ Write_macos_d_Name);
+}
+
+LOCALPROC Write_tmachores_d_ToDestFile(void)
+{
+ WriteSubDirToDestFile(Write_tmachocontents_d_ToDestFile,
+ Write_resources_d_Name);
+}
+
+LOCALPROC Write_tmacholang_d_ToDestFile(void)
+{
+ WriteSubDirToDestFile(Write_tmachores_d_ToDestFile,
+ WriteLProjFolderName);
+}
+
+LOCALPROC Write_tmachobinpath_ToDestFile(void)
+{
+ WriteFileInDirToDestFile0(Write_tmachomac_d_ToDestFile,
+ WriteStrAppAbbrev);
+}
+
+LOCALPROC Write_umachobun_d_Name(void)
+{
+ WriteStrAppAbbrev();
+ WriteCStrToDestFile("_u.app");
+}
+
+LOCALPROC Write_umachobun_d_ToDestFile(void)
+{
+ Write_toplevel_d_ToDestFile(Write_umachobun_d_Name);
+}
+
+LOCALPROC Write_umachocontents_d_ToDestFile(void)
+{
+ WriteSubDirToDestFile(Write_umachobun_d_ToDestFile,
+ Write_contents_d_Name);
+}
+
+LOCALPROC Write_umachomac_d_ToDestFile(void)
+{
+ WriteSubDirToDestFile(Write_umachocontents_d_ToDestFile,
+ Write_macos_d_Name);
+}
+
+LOCALPROC Write_umachobinpath_ToDestFile(void)
+{
+ WriteFileInDirToDestFile0(Write_umachomac_d_ToDestFile,
+ WriteStrAppAbbrev);
+}
+
+LOCALPROC WriteInfoPlistFileName(void)
+{
+ WriteCStrToDestFile("Info.plist");
+}
+
+LOCALPROC WriteInfoPlistFilePath(void)
+{
+ WriteFileInDirToDestFile0(Write_cfg_d_ToDestFile,
+ WriteInfoPlistFileName);
+}
+
+LOCALPROC WriteDummyLangFileName(void)
+{
+ WriteCStrToDestFile("dummy.txt");
+}
+
+LOCALPROC Write_tmachoLangDummyPath(void)
+{
+ WriteFileInDirToDestFile0(Write_tmacholang_d_ToDestFile,
+ WriteDummyLangFileName);
+}
+
+LOCALPROC Write_tmachoLangDummyContents(void)
+{
+ WriteCStrToDestFile("dummy");
+}
+
+LOCALPROC Write_tmachoPkgInfoName(void)
+{
+ WriteCStrToDestFile("PkgInfo");
+}
+
+LOCALPROC Write_tmachoPkgInfoPath(void)
+{
+ WriteFileInDirToDestFile0(Write_tmachocontents_d_ToDestFile,
+ Write_tmachoPkgInfoName);
+}
+
+LOCALPROC Write_MacCreatorSigOrGeneric(void)
+{
+ if (WantIconMaster) {
+ WriteCStrToDestFile(kMacCreatorSig);
+ } else {
+ WriteCStrToDestFile("????");
+ }
+}
+
+LOCALPROC Write_tmachoPkgInfoContents(void)
+{
+ WriteCStrToDestFile("APPL");
+ Write_MacCreatorSigOrGeneric();
+}
+
+LOCALPROC Write_machoRsrcName(void)
+{
+ WriteStrAppAbbrev();
+ WriteCStrToDestFile(".rsrc");
+}
+
+LOCALPROC Write_machoRsrcPath(void)
+{
+ WriteFileInDirToDestFile0(Write_machores_d_ToDestFile,
+ Write_machoRsrcName);
+}
+
+LOCALPROC Write_AppIconName(void)
+{
+ WriteCStrToDestFile("ICONAPPO.icns");
+}
+
+LOCALPROC Write_machoAppIconPath(void)
+{
+ WriteFileInDirToDestFile0(Write_machores_d_ToDestFile,
+ Write_AppIconName);
+}
+
+LOCALPROC Write_srcAppIconPath(void)
+{
+ WriteFileInDirToDestFile0(Write_src_d_ToDestFile,
+ Write_AppIconName);
+}
+
+LOCALPROC WriteMainRsrcName(void)
+{
+ switch (cur_ide) {
+ case gbk_ide_msv:
+ case gbk_ide_dvc:
+ case gbk_ide_cyg:
+ case gbk_ide_mgw:
+ case gbk_ide_lcc:
+ case gbk_ide_dmc:
+ case gbk_ide_dkp:
+ case gbk_ide_plc:
+ WriteCStrToDestFile("main.rc");
+ break;
+ case gbk_ide_mvc:
+ switch (gbo_targfam) {
+ case gbk_targfam_mswn:
+ case gbk_targfam_wnce:
+ WriteCStrToDestFile("main.rc");
+ break;
+ default:
+ WriteCStrToDestFile("main.r");
+ break;
+ }
+ break;
+ default:
+ WriteCStrToDestFile("main.r");
+ break;
+ }
+}
+
+LOCALPROC Write_Rsrc_d_ToDestFile(void)
+{
+ if ((gbk_targfam_mswn == gbo_targfam)
+ || (gbk_targfam_wnce == gbo_targfam))
+ {
+ Write_cfg_d_ToDestFile();
+ } else
+ {
+ Write_src_d_ToDestFile();
+ }
+}
+
+LOCALPROC WriteMainRsrcSrcPath(void)
+{
+ WriteFileInDirToDestFile0(Write_Rsrc_d_ToDestFile,
+ WriteMainRsrcName);
+}
+
+LOCALPROC WriteMainRsrcObjName(void)
+{
+#if (gbk_ide_msv == cur_ide) \
+ || (gbk_ide_lcc == cur_ide) \
+ || (gbk_ide_dvc == cur_ide) \
+ || (gbk_ide_cyg == cur_ide) \
+ || (gbk_ide_mgw == cur_ide) \
+ || (gbk_ide_mvc == cur_ide) \
+ || (gbk_ide_dmc == cur_ide) \
+ || (gbk_ide_dkp == cur_ide) \
+ || (gbk_ide_plc == cur_ide)
+ WriteCStrToDestFile("main.res");
+#endif
+
+#if (gbk_ide_mpw == cur_ide)
+ WriteCStrToDestFile("main.rsrc");
+#endif
+}
+
+LOCALPROC WriteMainRsrcObjPath(void)
+{
+ WriteFileInDirToDestFile0(Write_obj_d_ToDestFile,
+ WriteMainRsrcObjName);
+}
+
+LOCALPROC WriteCNFGGLOBName(void)
+{
+ WriteCStrToDestFile("CNFGGLOB.h");
+}
+
+LOCALPROC WriteCNFGGLOBPath(void)
+{
+ WriteFileInDirToDestFile0(Write_cfg_d_ToDestFile,
+ WriteCNFGGLOBName);
+}
+
+LOCALPROC WriteCNFGRAPIName(void)
+{
+ WriteCStrToDestFile("CNFGRAPI.h");
+}
+
+LOCALPROC WriteCNFGRAPIPath(void)
+{
+ WriteFileInDirToDestFile0(Write_cfg_d_ToDestFile,
+ WriteCNFGRAPIName);
+}
+
+LOCALPROC WritePathArgInMakeCmnd(MyProc p)
+{
+ switch (cur_ide) {
+ case gbk_ide_mpw:
+ case gbk_ide_bgc:
+ case gbk_ide_mvc:
+ case gbk_ide_cyg:
+ case gbk_ide_snc:
+ case gbk_ide_xcd:
+ case gbk_ide_msv:
+ case gbk_ide_dkp:
+ case gbk_ide_ccc:
+ WriteSpaceToDestFile();
+ WriteQuoteToDestFile();
+ p();
+ WriteQuoteToDestFile();
+ break;
+ case gbk_ide_lcc:
+ /* saw some glitches with quotes */
+ case gbk_ide_dmc:
+ case gbk_ide_plc:
+ case gbk_ide_dvc:
+ case gbk_ide_mgw:
+ case gbk_ide_9pc:
+ WriteSpaceToDestFile();
+ p();
+ break;
+ default:
+ break;
+ }
+}
+
+LOCALPROC WriteMakeVar(char *s)
+{
+ switch (cur_ide) {
+ case gbk_ide_mpw:
+ WriteCStrToDestFile("{");
+ WriteCStrToDestFile(s);
+ WriteCStrToDestFile("}");
+ break;
+ case gbk_ide_bgc:
+ case gbk_ide_mvc:
+ case gbk_ide_cyg:
+ case gbk_ide_snc:
+ case gbk_ide_xcd:
+ case gbk_ide_msv:
+ case gbk_ide_lcc:
+ case gbk_ide_dvc:
+ case gbk_ide_mgw:
+ case gbk_ide_dmc:
+ case gbk_ide_plc:
+ case gbk_ide_dkp:
+ case gbk_ide_ccc:
+ WriteCStrToDestFile("$(");
+ WriteCStrToDestFile(s);
+ WriteCStrToDestFile(")");
+ break;
+ case gbk_ide_9pc:
+ WriteCStrToDestFile("$");
+ WriteCStrToDestFile(s);
+ break;
+ default:
+ break;
+ }
+}
+
+LOCALPROC WriteMakeDependFile(MyProc p)
+{
+ switch (cur_ide) {
+ case gbk_ide_msv:
+ case gbk_ide_mpw:
+ WriteSpaceToDestFile();
+ WriteQuoteToDestFile();
+ p();
+ WriteQuoteToDestFile();
+ break;
+ case gbk_ide_bgc:
+ case gbk_ide_mvc:
+ case gbk_ide_cyg:
+ case gbk_ide_snc:
+ case gbk_ide_xcd:
+ case gbk_ide_lcc:
+ case gbk_ide_dvc:
+ case gbk_ide_mgw:
+ case gbk_ide_dmc:
+ case gbk_ide_plc:
+ case gbk_ide_dkp:
+ case gbk_ide_ccc:
+ case gbk_ide_9pc:
+ WriteSpaceToDestFile();
+ p();
+ default:
+ break;
+ }
+}
+
+LOCALPROC WriteMainRsrcObjMSCdeps(void)
+{
+ WriteMakeDependFile(WriteMainRsrcSrcPath);
+}
+
+LOCALPROC WriteMakeRule(MyProc ptarg,
+ MyProc pdeps, MyProc pbody)
+{
+ WriteBgnDestFileLn();
+ switch (cur_ide) {
+ case gbk_ide_mpw:
+ WriteQuoteToDestFile();
+ ptarg();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" \304");
+ pdeps();
+ break;
+ case gbk_ide_bgc:
+ case gbk_ide_mvc:
+ case gbk_ide_cyg:
+ case gbk_ide_snc:
+ case gbk_ide_xcd:
+ case gbk_ide_ccc:
+ ptarg();
+ WriteCStrToDestFile(" :");
+ pdeps();
+ break;
+ case gbk_ide_9pc:
+ ptarg();
+ WriteCStrToDestFile(": ");
+ pdeps();
+ break;
+ case gbk_ide_msv:
+ WriteQuoteToDestFile();
+ ptarg();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" :");
+ pdeps();
+ break;
+ case gbk_ide_lcc:
+ case gbk_ide_dvc:
+ case gbk_ide_mgw:
+ case gbk_ide_dmc:
+ case gbk_ide_plc:
+ case gbk_ide_dkp:
+ ptarg();
+ WriteCStrToDestFile(":");
+ pdeps();
+ break;
+ default:
+ break;
+ }
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ pbody();
+ --DestFileIndent;
+}
+
+LOCALPROC WriteMkDir(MyProc p)
+{
+ WriteBgnDestFileLn();
+ switch (cur_ide) {
+ case gbk_ide_mpw:
+ WriteCStrToDestFile("NewFolder");
+ break;
+ case gbk_ide_bgc:
+ case gbk_ide_mvc:
+ case gbk_ide_cyg:
+ case gbk_ide_snc:
+ case gbk_ide_xcd:
+ case gbk_ide_ccc:
+ case gbk_ide_9pc:
+ case gbk_ide_dkp:
+ WriteCStrToDestFile("mkdir");
+ break;
+ default:
+ break;
+ }
+ WritePathArgInMakeCmnd(p);
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteRmDir(MyProc p)
+{
+ WriteBgnDestFileLn();
+ switch (cur_ide) {
+ case gbk_ide_mpw:
+ WriteCStrToDestFile("Delete -i -y");
+ break;
+ case gbk_ide_bgc:
+ case gbk_ide_mvc:
+ case gbk_ide_cyg:
+ case gbk_ide_snc:
+ case gbk_ide_xcd:
+ case gbk_ide_ccc:
+ case gbk_ide_9pc:
+ case gbk_ide_dkp:
+ WriteCStrToDestFile("rm -fr");
+ break;
+ default:
+ break;
+ }
+ WritePathArgInMakeCmnd(p);
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteRmFile(MyProc p)
+{
+ WriteBgnDestFileLn();
+ switch (cur_ide) {
+ case gbk_ide_mpw:
+ WriteCStrToDestFile("Delete -i");
+ break;
+ case gbk_ide_bgc:
+ case gbk_ide_mvc:
+ case gbk_ide_cyg:
+ case gbk_ide_snc:
+ case gbk_ide_xcd:
+ case gbk_ide_dvc:
+ case gbk_ide_mgw:
+ case gbk_ide_dkp:
+ case gbk_ide_ccc:
+ case gbk_ide_9pc:
+ WriteCStrToDestFile("rm -f");
+ break;
+ case gbk_ide_msv:
+ WriteCStrToDestFile("-@erase");
+ break;
+ case gbk_ide_lcc:
+ case gbk_ide_dmc:
+ case gbk_ide_plc:
+ WriteCStrToDestFile("del");
+ break;
+ default:
+ break;
+ }
+ WritePathArgInMakeCmnd(p);
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteCopyFile(MyProc pfrom, MyProc pto)
+{
+ WriteBgnDestFileLn();
+ switch (cur_ide) {
+ case gbk_ide_mpw:
+ WriteCStrToDestFile("Duplicate");
+ break;
+ case gbk_ide_bgc:
+ case gbk_ide_mvc:
+ case gbk_ide_cyg:
+ case gbk_ide_snc:
+ case gbk_ide_xcd:
+ case gbk_ide_dkp:
+ case gbk_ide_ccc:
+ case gbk_ide_9pc:
+ WriteCStrToDestFile("cp");
+ break;
+ default:
+ break;
+ }
+ WritePathArgInMakeCmnd(pfrom);
+ WritePathArgInMakeCmnd(pto);
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteMoveDir(MyProc pfrom, MyProc pto)
+{
+ WriteBgnDestFileLn();
+ switch (cur_ide) {
+ case gbk_ide_mpw:
+ WriteCStrToDestFile("Move");
+ break;
+ case gbk_ide_bgc:
+ case gbk_ide_mvc:
+ case gbk_ide_cyg:
+ case gbk_ide_snc:
+ case gbk_ide_xcd:
+ case gbk_ide_dkp:
+ case gbk_ide_ccc:
+ case gbk_ide_9pc:
+ WriteCStrToDestFile("mv");
+ break;
+ default:
+ break;
+ }
+ WritePathArgInMakeCmnd(pfrom);
+ WritePathArgInMakeCmnd(pto);
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteEchoToNewFile(MyProc ptext, MyProc pto, blnr newline)
+{
+ WriteBgnDestFileLn();
+ switch (cur_ide) {
+ case gbk_ide_mpw:
+ WriteCStrToDestFile("Echo");
+ if (! newline) {
+ WriteCStrToDestFile(" -n");
+ }
+ WriteCStrToDestFile(" \"");
+ ptext();
+ WriteCStrToDestFile("\" >");
+ WritePathArgInMakeCmnd(pto);
+ break;
+ break;
+ case gbk_ide_cyg:
+ case gbk_ide_snc:
+ case gbk_ide_dkp:
+ case gbk_ide_ccc:
+ WriteCStrToDestFile("echo");
+ if (! newline) {
+ WriteCStrToDestFile(" -n");
+ }
+ WriteCStrToDestFile(" \"");
+ ptext();
+ WriteCStrToDestFile("\" >");
+ WritePathArgInMakeCmnd(pto);
+ break;
+ case gbk_ide_9pc:
+ WriteCStrToDestFile("echo");
+ if (! newline) {
+ WriteCStrToDestFile(" -n");
+ }
+ WriteCStrToDestFile(" '");
+ ptext();
+ WriteCStrToDestFile("' >");
+ WritePathArgInMakeCmnd(pto);
+ break;
+ case gbk_ide_bgc:
+ case gbk_ide_mvc:
+ case gbk_ide_xcd:
+ WriteCStrToDestFile("printf \"");
+ ptext();
+ if (newline) {
+ WriteCStrToDestFile("\\n");
+ }
+ WriteCStrToDestFile("\" >");
+ WritePathArgInMakeCmnd(pto);
+ break;
+ default:
+ break;
+ }
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteCompileCExec(void)
+{
+ switch (cur_ide) {
+ case gbk_ide_9pc:
+ WriteCStrToDestFile("$CC");
+ break;
+ case gbk_ide_mpw:
+ if (gbk_cpufam_68k == gbo_cpufam) {
+ WriteCStrToDestFile("SC");
+ } else if (gbk_cpufam_ppc == gbo_cpufam) {
+ WriteCStrToDestFile("MrC");
+ }
+ break;
+ case gbk_ide_bgc:
+ case gbk_ide_mvc:
+ case gbk_ide_cyg:
+ case gbk_ide_xcd:
+ WriteCStrToDestFile("gcc");
+ break;
+ case gbk_ide_snc:
+ case gbk_ide_ccc:
+ WriteCStrToDestFile("cc");
+ break;
+ case gbk_ide_msv:
+ if (gbk_cpufam_arm == gbo_cpufam) {
+ WriteCStrToDestFile("clarm.exe");
+ } else {
+ WriteCStrToDestFile("cl.exe");
+ }
+ break;
+ case gbk_ide_lcc:
+ WriteCStrToDestFile("lcc.exe");
+ break;
+ case gbk_ide_dvc:
+ case gbk_ide_mgw:
+ WriteCStrToDestFile("gcc.exe");
+ break;
+ case gbk_ide_dkp:
+ WriteCStrToDestFile("$(DEVKITARM)/bin/arm-eabi-gcc.exe");
+ break;
+ case gbk_ide_dmc:
+ WriteCStrToDestFile("dmc.exe");
+ break;
+ case gbk_ide_plc:
+ WriteCStrToDestFile("pocc.exe");
+ break;
+ default:
+ break;
+ }
+}
+
+LOCALPROC WriteCompileC(MyProc psrc, MyProc pobj,
+ blnr UseAPI)
+{
+ WriteBgnDestFileLn();
+ switch (cur_ide) {
+ case gbk_ide_9pc:
+ WriteCompileCExec();
+ WriteCStrToDestFile(" -o");
+ WritePathArgInMakeCmnd(pobj);
+ WriteCStrToDestFile(" $CFLAGS");
+ WritePathArgInMakeCmnd(psrc);
+ break;
+ case gbk_ide_mpw:
+ case gbk_ide_bgc:
+ case gbk_ide_cyg:
+ case gbk_ide_xcd:
+ case gbk_ide_snc:
+ case gbk_ide_dvc:
+ case gbk_ide_mgw:
+ case gbk_ide_dkp:
+ case gbk_ide_ccc:
+ WriteCompileCExec();
+ WritePathArgInMakeCmnd(psrc);
+ WriteCStrToDestFile(" -o");
+ WritePathArgInMakeCmnd(pobj);
+ WriteSpaceToDestFile();
+ if (! UseAPI) {
+ WriteMakeVar("mk_COptions");
+ } else {
+ if (gbk_ide_xcd == cur_ide)
+ {
+ WriteMakeVar("mk_COptionsOSGLU");
+ } else {
+ WriteMakeVar("mk_COptions");
+ }
+ if (gbk_apifam_xwn == gbo_apifam) {
+#if 0
+ if (gbk_targfam_fbsd == gbo_targfam) {
+ WriteCStrToDestFile(" -I/usr/local/include");
+ /*
+ this is location in latest PC-BSD,
+ but in old PC-BSD need
+ /usr/X11R6/include/
+ and in latest PC-BSD
+ /usr/X11R6/ links to /usr/local/
+ so just use old location.
+ */
+ }
+#endif
+ if ((gbk_ide_xcd == cur_ide)
+ || (gbk_targfam_fbsd == gbo_targfam)
+ || (gbk_targfam_obsd == gbo_targfam)
+ || (gbk_targfam_oind == gbo_targfam))
+ {
+ WriteCStrToDestFile(" -I/usr/X11R6/include/");
+ } else if (gbk_targfam_nbsd == gbo_targfam) {
+ WriteCStrToDestFile(" -I/usr/X11R7/include/");
+ } else if (gbk_targfam_dbsd == gbo_targfam) {
+ WriteCStrToDestFile(" -I/usr/pkg/include/");
+ } else if (gbk_targfam_minx == gbo_targfam) {
+ WriteCStrToDestFile(
+ " -I/usr/pkg/X11R6/include/");
+ }
+ } else if (gbk_apifam_sdl == gbo_apifam) {
+ if (gbk_targfam_mach == gbo_targfam) {
+ WriteCStrToDestFile(" -I/usr/local/include/"
+ " -D_GNU_SOURCE=1 -D_THREAD_SAFE");
+ }
+ } else if (gbk_apifam_sd2 == gbo_apifam) {
+ if (gbk_targfam_mach == gbo_targfam) {
+ WriteCStrToDestFile(
+ " -D_GNU_SOURCE=1 -D_THREAD_SAFE");
+ }
+ } else if (gbk_apifam_nds == gbo_apifam) {
+ WriteCStrToDestFile(
+ " -I$(DEVKITPRO)/libnds/include");
+ } else if (gbk_apifam_gtk == gbo_apifam) {
+ WriteCStrToDestFile(
+ " `pkg-config --cflags gtk+-2.0`");
+ }
+ }
+ break;
+ case gbk_ide_msv:
+ WriteCompileCExec();
+ WritePathArgInMakeCmnd(psrc);
+ WriteSpaceToDestFile();
+ WriteMakeVar("mk_COptions");
+ break;
+ case gbk_ide_lcc:
+ WriteCompileCExec();
+ WritePathArgInMakeCmnd(psrc);
+ WriteCStrToDestFile(" -Fo");
+ pobj();
+ WriteSpaceToDestFile();
+ WriteMakeVar("mk_COptions");
+ break;
+ case gbk_ide_dmc:
+ WriteCompileCExec();
+ WritePathArgInMakeCmnd(psrc);
+ WriteCStrToDestFile(" -o");
+ pobj();
+ WriteSpaceToDestFile();
+ WriteMakeVar("mk_COptions");
+ break;
+ case gbk_ide_plc:
+ WriteCompileCExec();
+ WritePathArgInMakeCmnd(psrc);
+ WriteCStrToDestFile(" -Fo");
+ WriteQuoteToDestFile();
+ pobj();
+ WriteQuoteToDestFile();
+ WriteSpaceToDestFile();
+ WriteMakeVar("mk_COptions");
+ break;
+ default:
+ break;
+ }
+ WriteEndDestFileLn();
+}
--- /dev/null
+++ b/setup/BLDUTIL4.i
@@ -1,0 +1,303 @@
+/*
+ BLDUTIL4.i
+ Copyright (C) 2009 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ BuiLD system UTILities part 4
+*/
+
+LOCALPROC WriteOutDummyContents(void)
+{
+ WriteDestFileLn(
+ "This file is here because some archive extraction");
+ WriteDestFileLn("software will not create an empty directory.");
+}
+
+LOCALPROC WriteMakeOutputDirectories(void)
+{
+ if ((gbk_ide_xcd == cur_ide) && (! UseCmndLine)) {
+ } else
+ if (gbk_ide_mw8 == cur_ide) {
+ } else {
+ WriteSectionCommentDestFile("make output directory");
+
+ MakeSubDirectory("my_obj_d", "my_project_d", obj_d_name, "");
+
+ WriteADstFile1("my_obj_d",
+ "dummy", ".txt", "Dummy",
+ WriteOutDummyContents);
+ }
+}
+
+LOCALPROC WriteIdeSpecificFiles(void)
+{
+#if gbk_ide_mpw == cur_ide
+ WriteMPWSpecificFiles();
+#endif
+
+#if gbk_ide_mvc == cur_ide
+ WriteMVCSpecificFiles();
+#endif
+
+#if (gbk_ide_bgc == cur_ide) \
+ || (gbk_ide_cyg == cur_ide) \
+ || (gbk_ide_mgw == cur_ide) \
+ || (gbk_ide_dkp == cur_ide)
+ WriteBashGccSpecificFiles();
+#endif
+
+#if gbk_ide_mw8 == cur_ide
+ WriteMetrowerksSpecificFiles();
+#endif
+
+#if gbk_ide_snc == cur_ide
+ WriteSncSpecificFiles();
+#endif
+
+#if gbk_ide_msv == cur_ide
+ WriteMsvSpecificFiles();
+#endif
+
+#if gbk_ide_lcc == cur_ide
+ if (UseCmndLine) {
+ WriteLccW32clSpecificFiles();
+ } else {
+ WriteLccW32SpecificFiles();
+ }
+#endif
+
+#if gbk_ide_dvc == cur_ide
+ if (UseCmndLine) {
+ WriteBashGccSpecificFiles();
+ } else {
+ WriteDevCSpecificFiles();
+ }
+#endif
+
+#if gbk_ide_xcd == cur_ide
+ if (UseCmndLine) {
+ WriteBashGccSpecificFiles();
+ } else {
+ WriteXCDSpecificFiles();
+ }
+#endif
+
+#if gbk_ide_dmc == cur_ide
+ WriteDMCSpecificFiles();
+#endif
+
+#if gbk_ide_plc == cur_ide
+ if (UseCmndLine) {
+ WritePLCclSpecificFiles();
+ } else {
+ WritePLCSpecificFiles();
+ }
+#endif
+
+#if gbk_ide_ccc == cur_ide
+ WriteCccSpecificFiles();
+#endif
+
+#if gbk_ide_9pc == cur_ide
+ Write9pcSpecificFiles();
+#endif
+}
+
+LOCALPROC ResetAllCommandLineParameters(void)
+{
+ GNResetCommandLineParameters();
+ GNDevResetCommandLineParameters();
+#ifdef Have_SPBLDOPT
+ SPResetCommandLineParameters();
+#endif
+ olv_cur = 1;
+ OnlyUserOptions = falseblnr;
+}
+
+LOCALFUNC tMyErr TryAsAtOptionNot(void)
+{
+ tMyErr err;
+
+ if (! CurArgIsCStr_v2("@")) {
+ err = kMyErrNoMatch;
+ } else
+ if (OnlyUserOptions) {
+ err = ReportParseFailure("Already have @");
+ } else
+ if (kMyErr_noErr != (err = AdvanceTheArg())) {
+ /* fail */
+ } else
+ {
+ OnlyUserOptions = trueblnr;
+ err = kMyErr_noErr;
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr TryAsXClmOptionNot(void)
+{
+ tMyErr err;
+
+ if (! CurArgIsCStr_v2("!")) {
+ err = kMyErrNoMatch;
+ } else
+ if (kMyErr_noErr != (err = AdvanceTheArg())) {
+ /* fail */
+ } else
+ {
+ err = kMyErr_noErr;
+ ++olv_cur;
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr ReportUnknownSwitch(void)
+{
+ MyPStr t0;
+ MyPStr t;
+
+ GetCurArgAsPStr(t0);
+ PStrFromCStr(t, "unknown switch : ");
+ PStrAppend(t, t0);
+
+ return ReportParseFailPStr(t);
+}
+
+LOCALFUNC tMyErr ProcessCommandLineArguments(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ while ((! The_arg_end) && (kMyErr_noErr == err)) {
+ if (kMyErrNoMatch == (err = TryAsGNOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsGNDevOptionNot()))
+#ifdef Have_SPBLDOPT
+ if (kMyErrNoMatch == (err = TryAsSPOptionNot()))
+#endif
+ if (kMyErrNoMatch == (err = TryAsAtOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsXClmOptionNot()))
+ {
+ err = ReportUnknownSwitch();
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC DoDocTypeAddToMainRC(void)
+{
+ WriteBgnDestFileLn();
+ WriteUnsignedToOutput(256 + DocTypeCounter);
+ WriteCStrToDestFile(
+ " ICON DISCARDABLE ");
+ WriteQuoteToDestFile();
+ WriteDocTypeIconFileName();
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteWinMainRCcontents(void)
+{
+ DoAllDocTypesWithSetup(DoDocTypeAddToMainRC);
+}
+
+LOCALPROC WriteWinMainRC(void)
+{
+ WriteADstFile1("my_config_d",
+ "main", ".rc", "Resource Configuration file",
+ WriteWinMainRCcontents);
+}
+
+LOCALPROC WriteConfigFiles(void)
+{
+ WriteAppSpecificConfigFiles();
+
+ if (HaveMacRrscs) {
+ WriteCommonCNFGRSRC();
+ }
+
+ if (gbk_apifam_win == gbo_apifam) {
+ WriteWinMainRC();
+ }
+}
+
+
+LOCALPROC MakeConfigFolder(void)
+{
+ WriteSectionCommentDestFile("make configuration folder");
+
+ MakeSubDirectory("my_config_d", "my_project_d", cfg_d_name, "");
+}
+
+#if WantWriteVarName
+LOCALPROC WriteAppVariationStr1(void)
+{
+ WriteBgnDestFileLn();
+ WriteAppVariationStr();
+ WriteEndDestFileLn();
+}
+#endif
+
+#if WantWriteBldOpts
+LOCALPROC WriteBldOpts1(void)
+{
+ WriteBgnDestFileLn();
+ WriteBldOpts();
+ WriteEndDestFileLn();
+}
+#endif
+
+LOCALFUNC tMyErr DoTheCommand(void)
+{
+ tMyErr err;
+
+ ResetAllCommandLineParameters();
+
+ if (kMyErr_noErr == (err = ProcessCommandLineArguments()))
+ if (kMyErr_noErr == (err = AutoChooseGNSettings()))
+ if (kMyErr_noErr == (err = AutoChooseGNDevSettings()))
+#ifdef Have_SPBLDOPT
+ if (kMyErr_noErr == (err = AutoChooseSPSettings()))
+#endif
+ {
+ WriteScriptLangHeader();
+
+ WriteMakeOutputDirectories();
+
+ MakeConfigFolder();
+
+ WriteConfigFiles();
+
+ if (CurPrintCFiles) {
+ WriteCFilesList();
+ }
+
+#if WantWriteVarName
+ WriteADstFile1("my_project_d",
+ "var_name", "", "variation name",
+ WriteAppVariationStr1);
+#endif
+#if WantWriteBldOpts
+ WriteADstFile1("my_project_d",
+ "bld_opts", "", "build options",
+ WriteBldOpts1);
+#endif
+
+ WriteIdeSpecificFiles();
+ }
+
+ return err;
+}
--- /dev/null
+++ b/setup/CMDARGT1.i
@@ -1,0 +1,101 @@
+/*
+ CMDARGT1.i
+ Copyright (C) 2009 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ CoMmandD ARGument Tool part 1
+
+ allows code used with CMDARGW1 to also be
+ used to make an MPW tool.
+*/
+
+
+LOCALVAR int The_argc;
+LOCALVAR int The_argi;
+typedef char **The_argvt;
+LOCALVAR The_argvt The_argv;
+LOCALVAR char *Cur_args;
+LOCALVAR blnr The_arg_end;
+
+GLOBALFUNC tMyErr AdvanceTheArg(void)
+{
+ ++The_argi;
+ if (The_argi < The_argc) {
+ Cur_args = The_argv[The_argi];
+ } else {
+ The_arg_end = trueblnr;
+ }
+
+ return kMyErr_noErr;
+}
+
+GLOBALFUNC blnr CurArgIsCStr_v2(char *s)
+{
+ /* warning : assumes (! The_arg_end) */
+ return CStrEq(Cur_args, s);
+}
+
+GLOBALFUNC tMyErr CurArgIsCStrAdvance_v2(char *s)
+{
+ tMyErr err;
+
+ /* warning : assumes (! The_arg_end) */
+ if (! CurArgIsCStr_v2(s)) {
+ err = kMyErrNoMatch;
+ } else {
+ err = AdvanceTheArg();
+ }
+
+ return err;
+}
+
+GLOBALPROC GetCurArgAsCStr(char *s, uimr MaxN)
+{
+ /* warning : assumes (! The_arg_end) */
+ if (CStrLength(Cur_args) > MaxN) {
+ s[0] = 0;
+ } else {
+ CStrCopy(s, Cur_args);
+ }
+}
+
+GLOBALPROC GetCurArgAsPStr(ps3p s)
+{
+ /* warning : assumes (! The_arg_end) */
+ PStrFromCStr(s, Cur_args);
+}
+
+GLOBALPROC BeginParseCommandLineArguments(int argc, The_argvt argv)
+{
+ The_argi = 0;
+ The_argc = argc;
+ The_argv = argv;
+ The_arg_end = falseblnr;
+ (void) AdvanceTheArg();
+}
+
+GLOBALFUNC tMyErr ReportParseFailure(char *s)
+{
+ fprintf(stderr, "%s\n", s);
+
+ return kMyErrReported;
+}
+
+GLOBALFUNC tMyErr ReportParseFailPStr(ps3p s)
+{
+ char t[256];
+
+ CStrFromPStr(s, t);
+ return ReportParseFailure(t);
+}
--- /dev/null
+++ b/setup/CNFGDLFT.i
@@ -1,0 +1,98 @@
+/*
+ CNFGDLFT.i
+ Copyright (C) 2018 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ CoNFiGuration DeFauLTs
+
+ set default values for things not set in CONFIGUR.i
+*/
+
+
+#ifndef kMaintainerName
+#define kMaintainerName "unknown"
+#endif
+
+
+#ifndef kStrHomePage
+#define kStrHomePage "(unknown)"
+#endif
+
+#ifdef __plan9__
+#define cur_ide gbk_ide_9pc
+#endif
+
+#ifndef cur_ide
+
+#ifdef applec
+#define cur_ide gbk_ide_mpw
+#else
+#define cur_ide gbk_ide_bgc
+#endif
+
+#endif /* cur_ide */
+
+
+#ifndef ide_vers
+
+#if gbk_ide_xcd == cur_ide
+#define ide_vers 9410
+#elif gbk_ide_msv == cur_ide
+#define ide_vers 15000
+#else
+#define ide_vers 1
+#endif
+
+#endif /* ide_vers */
+
+
+#ifndef UseCmndLine
+#define UseCmndLine 0
+#endif
+
+
+#ifndef NeedSegmenting
+
+#if gbk_ide_mpw == cur_ide
+#define NeedSegmenting 1
+#else
+#define NeedSegmenting 0
+#endif
+
+#endif /* NeedSegmenting */
+
+
+#ifndef gbo_script
+
+#ifdef __plan9__
+#define gbo_script gbk_script_rc
+#else
+#if gbk_ide_mpw == cur_ide
+#define gbo_script gbk_script_mpw
+#else
+#define gbo_script gbk_script_bash
+#endif
+#endif
+
+#endif /* gbo_script */
+
+
+#ifndef WantWriteVarName
+#define WantWriteVarName 0
+#endif
+
+
+#ifndef WantWriteBldOpts
+#define WantWriteBldOpts 0
+#endif
--- /dev/null
+++ b/setup/CNFGOPTS.i
@@ -1,0 +1,50 @@
+/*
+ CNFGOPTS.i
+ Copyright (C) 2018 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ CoNFiGuration OPTionS
+
+ choices that can be used in CONFIGUR.i
+*/
+
+
+/* choices for cur_ide */
+
+#define gbk_ide_mpw 1 /* Macintosh Programmers Workshop */
+#define gbk_ide_mw8 2 /* Metrowerks CodeWarrior */
+#define gbk_ide_bgc 3 /* Gnu tools */
+#define gbk_ide_snc 4 /* Sun tools */
+#define gbk_ide_msv 5 /* Microsoft Visual C++ */
+#define gbk_ide_lcc 6 /* lcc-win32 - Jacob Navia */
+#define gbk_ide_dvc 7 /* Bloodshed Dev-C++ */
+#define gbk_ide_xcd 8 /* Apple XCode */
+ /* previously Apple Project Builder */
+#define gbk_ide_dmc 9 /* Digital Mars Compiler */
+#define gbk_ide_plc 10 /* Pelles C Compiler */
+#define gbk_ide_mgw 11 /* MinGW */
+#define gbk_ide_cyg 12 /* Cygwin */
+#define gbk_ide_dkp 13 /* devkitpro */
+#define gbk_ide_ccc 14 /* Generic command line c compiler */
+#define gbk_ide_mvc 15 /* Mini vMac C (a specific version of gcc) */
+#define gbk_ide_9pc 16 /* Plan 9 */
+
+/* choices for gbo_script */
+
+#define gbk_script_mpw 1
+#define gbk_script_applescript 2
+#define gbk_script_bash 3
+#define gbk_script_xp 4
+#define gbk_script_vbscript 5
+#define gbk_script_rc 6
--- /dev/null
+++ b/setup/CONFIGUR.i
@@ -1,0 +1,10 @@
+/*
+ CONFIGUR.i
+*/
+
+/*
+ CONFIGURation file
+
+ see CNFGDLFT.i and CNFGOPTS.i for things
+ that can go here.
+*/
--- /dev/null
+++ b/setup/COREDEFS.i
@@ -1,0 +1,90 @@
+/*
+ COREDEFS.i
+ Copyright (C) 2018 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ CORE DEFinitionS
+*/
+
+
+typedef unsigned long ui5b;
+typedef unsigned short ui4b;
+typedef unsigned char ui3b;
+
+typedef signed long si5b;
+typedef signed short si4b;
+typedef signed char si3b;
+
+typedef ui5b ui5r;
+typedef ui4b ui4r;
+typedef ui3b ui3r;
+
+typedef si5b si5r;
+typedef si4b si4r;
+typedef si3b si3r;
+
+typedef si3b *si3p;
+typedef ui3b *ui3p;
+typedef si4b *si4p;
+typedef ui4b *ui4p;
+typedef si5b *si5p;
+typedef ui5b *ui5p;
+
+typedef ui5p *ui5h;
+typedef ui4p *ui4h;
+typedef ui3p *ui3h;
+
+/*
+ define the largest supported
+ representation types.
+*/
+#define uimbl2sz 5
+typedef si5r simr;
+typedef ui5r uimr;
+
+typedef ui3b blnb;
+typedef ui3r blnr;
+#define trueblnr 1
+#define falseblnr 0
+
+typedef si4r tMyErr;
+
+typedef unsigned char MyPStr[256];
+typedef unsigned char *ps3p;
+typedef unsigned char MyCharR;
+typedef MyCharR *MyCharPtr;
+
+typedef unsigned char MyByte;
+typedef MyByte *MyPtr;
+
+#define nullpr ((void *) 0)
+
+#define DISCARDVAL (void)
+
+
+#define LOCALFUNC static
+#define GLOBALFUNC static
+#define EXPORTFUNC static
+#define TYPEDEFFUNC typedef
+
+#define LOCALPROC LOCALFUNC void
+#define GLOBALPROC GLOBALFUNC void
+#define EXPORTPROC EXPORTFUNC void
+#define TYPEDEFPROC TYPEDEFFUNC void
+
+#define LOCALVAR static
+#define GLOBALVAR static
+#define EXPORTVAR static
+
+GLOBALVAR MyPtr pDt;
--- /dev/null
+++ b/setup/DFFILDEF.i
@@ -1,0 +1,64 @@
+/*
+ DFFILDEF.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ DEFinitions for program SPecific FILe DEFinitions
+*/
+
+#define kDepDirCSrc 0
+#define kDepDirCnfg 1
+
+typedef void (*tDoOneDepends)(int DepDir, char *s);
+
+typedef void (*tDoDependsForC)(tDoOneDepends p);
+
+typedef void (*tDoOneCFile)(char *s, int DepDir, long Flgm,
+ tDoDependsForC depends);
+
+typedef void (*tWriteOneExtension)(char *s);
+
+typedef void (*tWriteExtensionList)(tWriteOneExtension p);
+
+typedef void (*tWriteOneDocType)(
+ char *ShortName,
+ char *MacType,
+ char *LongName,
+ tWriteExtensionList WriteExtensionList);
+
+#if 0
+#define kCSrcFlagAsmAvail 0
+#define kCSrcFlagAltSrc 1
+#endif
+#define kCSrcFlagSkip 1
+#define kCSrcFlagUseAPI 2
+#define kCSrcFlagSortFirst 3
+#define kCSrcFlagNoSource 4
+#define kCSrcFlagNoHeader 5
+#define kCSrcFlagOjbc 6
+
+#define kCSrcFlgmNone 0
+#if 0
+#define kCSrcFlgmAltSrc (1 << kCSrcFlagAltSrc)
+#endif
+#define kCSrcFlgmSkip (1 << kCSrcFlagSkip)
+#define kCSrcFlgmUseAPI (1 << kCSrcFlagUseAPI)
+#define kCSrcFlgmSortFirst (1 << kCSrcFlagSortFirst)
+#define kCSrcFlgmNoSource (1 << kCSrcFlagNoSource)
+#define kCSrcFlgmNoHeader (1 << kCSrcFlagNoHeader)
+#define kCSrcFlgmOjbc (1 << kCSrcFlagOjbc)
+
+#define CSrcFlagsUseIf(b) ((b) ? kCSrcFlgmNone : kCSrcFlgmSkip)
+#define CSrcFlagsUseHdrIf(b) (CSrcFlagsUseIf(b) | kCSrcFlgmNoSource)
+#define CSrcFlagsUseSrcIf(b) (CSrcFlagsUseIf(b) | kCSrcFlgmNoHeader)
--- /dev/null
+++ b/setup/GNBLDOPT.i
@@ -1,0 +1,1610 @@
+/*
+ GNBLDOPT.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ GeNeric BuiLD OPTions
+*/
+
+/* --- default definitions for SPBASDEF --- */
+
+#ifndef MayUseSound
+#define MayUseSound 1
+#endif
+
+#ifndef UseOpenGLinOSX
+#define UseOpenGLinOSX 0
+#endif
+
+#ifndef UseMachinOSX
+#define UseMachinOSX 0
+#endif
+
+#ifndef NeedIntFormatInfo
+#define NeedIntFormatInfo 0
+#endif
+
+#ifndef ModPPCi3rTypes
+#define ModPPCi3rTypes 0
+#endif
+
+/* --- end of default definitions for SPBASDEF --- */
+
+LOCALVAR blnr OnlyUserOptions = falseblnr;
+LOCALVAR blnr DoingDevOpts = falseblnr;
+
+LOCALVAR ui3r olv_cur;
+
+LOCALFUNC tMyErr CurArgIsOption(char *s, ui3r *olv)
+{
+ tMyErr err;
+ MyPStr t;
+
+ if (! CurArgIsCStr_v2(s)) {
+ err = kMyErrNoMatch;
+ } else
+ if (DoingDevOpts && OnlyUserOptions) {
+ PStrFromCStr(t, s);
+ PStrApndCStr(t, " is a developer only option");
+ err = ReportParseFailPStr(t);
+ } else
+ if (*olv == olv_cur) {
+ PStrFromCStr(t, s);
+ PStrApndCStr(t, " has appeared more than once");
+ err = ReportParseFailPStr(t);
+ } else
+ if (kMyErr_noErr != (err = AdvanceTheArg())) {
+ /* fail */
+ } else
+ {
+ *olv = olv_cur;
+ err = kMyErr_noErr;
+ }
+
+ return err;
+}
+
+typedef char * (* tGetName)(int i);
+
+LOCALFUNC blnr GetCurArgNameIndex(int n, tGetName p,
+ int *r)
+{
+ blnr v;
+ int i;
+
+ for (i = 0; i < n; ++i) {
+ if (CurArgIsCStr_v2(p(i))) {
+ *r = i;
+ v = trueblnr;
+ goto label_1;
+ }
+ }
+ v = falseblnr;
+
+label_1:
+ return v;
+}
+
+#define nanblnr 2
+
+#define kListOptionAuto (-1)
+
+LOCALFUNC tMyErr FindNamedOption(char *s, int n, tGetName p,
+ int *r, ui3r *olv)
+{
+ tMyErr err;
+ MyPStr t;
+
+ if (kMyErr_noErr != (err = CurArgIsOption(s, olv))) {
+ /* no */
+ } else
+ if (The_arg_end) {
+ PStrFromCStr(t, "Expecting an argument for ");
+ PStrApndCStr(t, s);
+ PStrApndCStr(t, " when reached end");
+ err = ReportParseFailPStr(t);
+ } else
+ if (GetCurArgNameIndex(n, p, r)) {
+ err = AdvanceTheArg();
+ } else
+ if (CurArgIsCStr_v2("*")) {
+ *r = kListOptionAuto;
+ err = AdvanceTheArg();
+ } else
+ {
+ PStrFromCStr(t, "Unknown value for ");
+ PStrApndCStr(t, s);
+ err = ReportParseFailPStr(t);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr BooleanTryAsOptionNot(char *s, blnr *r, ui3r *olv)
+{
+ tMyErr err;
+ MyPStr t;
+
+ if (kMyErr_noErr != (err = CurArgIsOption(s, olv))) {
+ /* no */
+ } else
+ if (The_arg_end) {
+ PStrFromCStr(t, "Expecting a boolean argument for ");
+ PStrApndCStr(t, s);
+ PStrApndCStr(t, " when reached end");
+ err = ReportParseFailPStr(t);
+ } else
+ if (CurArgIsCStr_v2("1")) {
+ *r = trueblnr;
+ err = AdvanceTheArg();
+ } else
+ if (CurArgIsCStr_v2("0")) {
+ *r = falseblnr;
+ err = AdvanceTheArg();
+ } else
+ if (CurArgIsCStr_v2("*")) {
+ *r = nanblnr;
+ err = AdvanceTheArg();
+ } else
+ {
+ PStrFromCStr(t, "Expecting a boolean argument for ");
+ PStrApndCStr(t, s);
+ err = ReportParseFailPStr(t);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr FlagTryAsOptionNot(char *s, blnr *r, ui3r *olv)
+{
+ tMyErr err;
+
+ if (kMyErr_noErr != (err = CurArgIsOption(s, olv))) {
+ /* no */
+ } else
+ {
+ err = kMyErr_noErr;
+ *r = trueblnr;
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr GetCurArgOptionAsNumber(char *s, long *r)
+{
+ tMyErr err;
+ MyPStr t0;
+ MyPStr t;
+
+ if (The_arg_end) {
+ PStrFromCStr(t, "Expecting a number argument for ");
+ PStrApndCStr(t, s);
+ PStrApndCStr(t, " when reached end");
+ err = ReportParseFailPStr(t);
+ } else {
+ GetCurArgAsPStr(t0);
+ *r = PStrToSimr(t0);
+ /* StringToNum(t0, r); */
+ PStrFromSimr(*r, t);
+ /* NumToString(*r, t); */
+ if (! PStrEq(t0, t)) {
+ PStrFromCStr(t, "Expecting a number argument for ");
+ PStrApndCStr(t, s);
+ PStrApndCStr(t, " but got ");
+ PStrAppend(t, t0);
+ err = ReportParseFailPStr(t);
+ } else
+ {
+ err = AdvanceTheArg();
+ }
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr NumberTryAsOptionNot(char *s, long *r, ui3r *olv)
+{
+ tMyErr err;
+
+ if (kMyErr_noErr != (err = CurArgIsOption(s, olv))) {
+ /* no */
+ } else
+ if (kMyErr_noErr != (err = GetCurArgOptionAsNumber(s, r))) {
+ /* fail */
+ } else
+ {
+ err = kMyErr_noErr;
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptNamedOption(char *s, tGetName p, int i, int i0)
+{
+ if (i != i0) {
+ WriteCStrToDestFile(" ");
+ WriteCStrToDestFile(s);
+ WriteCStrToDestFile(" ");
+ WriteCStrToDestFile(p(i));
+ }
+}
+
+LOCALPROC WrtOptNumberOption(char *s, int i, int i0)
+{
+ if (i != i0) {
+ WriteCStrToDestFile(" ");
+ WriteCStrToDestFile(s);
+ WriteCStrToDestFile(" ");
+ WriteUnsignedToOutput(i);
+ }
+}
+
+LOCALPROC WrtOptSimrOption(char *s, simr i, simr i0)
+{
+ if (i != i0) {
+ WriteCStrToDestFile(" ");
+ WriteCStrToDestFile(s);
+ WriteCStrToDestFile(" ");
+ WriteSignedLongToOutput(i);
+ }
+}
+
+LOCALPROC WrtOptBooleanOption(char *s, blnr i, blnr i0)
+{
+ if (i != i0) {
+ WriteCStrToDestFile(" ");
+ WriteCStrToDestFile(s);
+ WriteCStrToDestFile(" ");
+ WriteCStrToDestFile(i ? "1" : "0");
+ }
+}
+
+LOCALPROC WrtOptFlagOption(char *s, blnr v)
+{
+ if (v) {
+ WriteCStrToDestFile(" ");
+ WriteCStrToDestFile(s);
+ }
+}
+
+
+/* option: Branch */
+
+LOCALVAR uimr Branch;
+LOCALVAR ui3r olv_Branch;
+
+LOCALPROC ResetBranchOption(void)
+{
+ olv_Branch = 0;
+}
+
+LOCALFUNC tMyErr TryAsBranchOptionNot(void)
+{
+ return NumberTryAsOptionNot("-br",
+ (long *)&Branch, &olv_Branch);
+}
+
+LOCALFUNC tMyErr ChooseBranch(void)
+{
+ if (0 == olv_Branch) {
+ Branch = MajorVersion;
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptBranchOption(void)
+{
+ WriteCStrToDestFile("-br");
+ WriteCStrToDestFile(" ");
+ WriteUnsignedToOutput(MajorVersion);
+}
+
+
+/* option: target */
+
+enum {
+ gbk_targ_m68k, /* MacOS 68K */
+ gbk_targ_mfpu, /* MacOS 68K with FPU */
+ gbk_targ_mppc, /* MacOS OS 9 for PowerPC */
+ gbk_targ_mach, /* MacOS X Macho */
+ gbk_targ_imch, /* MacOS X Intel */
+ gbk_targ_mc64, /* MacOS X for x64 */
+ gbk_targ_wx86, /* Windows */
+ gbk_targ_wx64, /* Windows on x64 */
+ gbk_targ_lx86, /* X11 for linux on x86 */
+ gbk_targ_lppc, /* X11 for linux on PowerPC */
+ gbk_targ_lx64, /* X11 for linux on x64 */
+ gbk_targ_larm, /* X11 for linux on arm (debian armel) */
+ gbk_targ_lspr, /* X11 for linux on SPARC */
+ gbk_targ_fbsd, /* FreeBSD for x86 */
+ gbk_targ_fb64, /* FreeBSD for x64 */
+ gbk_targ_fbpc, /* FreeBSD for PowerPC */
+ gbk_targ_obsd, /* OpenBSD for x86 */
+ gbk_targ_ob64, /* OpenBSD for x64 */
+ gbk_targ_nbsd, /* NetBSD for x86 */
+ gbk_targ_nb64, /* NetBSD for x64 */
+ gbk_targ_dbsd, /* Dragonfly BSD for x86 */
+ gbk_targ_db64, /* Dragonfly BSD for x64 */
+ gbk_targ_slrs, /* Solaris SPARC */
+ gbk_targ_sl86, /* Solaris Intel */
+ gbk_targ_oind, /* OpenIndiana for x86 */
+ gbk_targ_oi64, /* OpenIndiana for x64 */
+ gbk_targ_minx, /* Minix on x86 */
+ gbk_targ_wcar, /* Windows CE on ARM */
+ gbk_targ_wc86, /* Windows CE (emulator) on x86 */
+ gbk_targ_carb, /* MacOS Carbon lib for OS 9 and OS X */
+ gbk_targ_mx11, /* X11 for MacOS X PowerPC */
+ gbk_targ_mi11, /* X11 for MacOS X Intel */
+ gbk_targ_mx64, /* X11 for MacOS X x64 */
+ gbk_targ_cygw, /* Cygwin/X */
+ gbk_targ_xgen, /* Generic X11 */
+ gbk_targ_ndsa, /* Nintendo DS on ARM */
+ gbk_targ_irix, /* Silicon Graphics's IRIX on MIPS */
+ gbk_targ_9x86, /* Plan 9 on x86 */
+ gbk_targ_9x64, /* Plan 9 on x64 */
+ gbk_targ_9arm, /* Plan 9 on arm */
+ gbk_targ_9a64, /* Plan 9 on aarch64 */
+ kNumTargets
+};
+
+LOCALVAR int cur_targ;
+LOCALVAR ui3r olv_targ;
+
+LOCALPROC ResetTargetOption(void)
+{
+ cur_targ = kListOptionAuto;
+ olv_targ = 0;
+}
+
+LOCALFUNC char * GetTargetName(int i)
+{
+ char *s;
+
+ switch (i) {
+ case gbk_targ_m68k:
+ s = "m68k";
+ break;
+ case gbk_targ_mfpu:
+ s = "mfpu";
+ break;
+ case gbk_targ_mppc:
+ s = "mppc";
+ break;
+ case gbk_targ_carb:
+ s = "carb";
+ break;
+ case gbk_targ_mach:
+ s = "mach";
+ break;
+ case gbk_targ_imch:
+ s = "imch";
+ break;
+ case gbk_targ_mc64:
+ s = "mc64";
+ break;
+ case gbk_targ_wx86:
+ s = "wx86";
+ break;
+ case gbk_targ_mx11:
+ s = "mx11";
+ break;
+ case gbk_targ_mi11:
+ s = "mi11";
+ break;
+ case gbk_targ_mx64:
+ s = "mx64";
+ break;
+ case gbk_targ_lx86:
+ s = "lx86";
+ break;
+ case gbk_targ_slrs:
+ s = "slrs";
+ break;
+ case gbk_targ_sl86:
+ s = "sl86";
+ break;
+ case gbk_targ_fbsd:
+ s = "fbsd";
+ break;
+ case gbk_targ_fb64:
+ s = "fb64";
+ break;
+ case gbk_targ_fbpc:
+ s = "fbpc";
+ break;
+ case gbk_targ_obsd:
+ s = "obsd";
+ break;
+ case gbk_targ_ob64:
+ s = "ob64";
+ break;
+ case gbk_targ_nbsd:
+ s = "nbsd";
+ break;
+ case gbk_targ_nb64:
+ s = "nb64";
+ break;
+ case gbk_targ_dbsd:
+ s = "dbsd";
+ break;
+ case gbk_targ_db64:
+ s = "db64";
+ break;
+ case gbk_targ_oind:
+ s = "oind";
+ break;
+ case gbk_targ_oi64:
+ s = "oi64";
+ break;
+ case gbk_targ_minx:
+ s = "minx";
+ break;
+ case gbk_targ_wcar:
+ s = "wcar";
+ break;
+ case gbk_targ_wc86:
+ s = "wc86";
+ break;
+ case gbk_targ_lppc:
+ s = "lppc";
+ break;
+ case gbk_targ_lx64:
+ s = "lx64";
+ break;
+ case gbk_targ_wx64:
+ s = "wx64";
+ break;
+ case gbk_targ_larm:
+ s = "larm";
+ break;
+ case gbk_targ_lspr:
+ s = "lspr";
+ break;
+ case gbk_targ_cygw:
+ s = "cygw";
+ break;
+ case gbk_targ_xgen:
+ s = "xgen";
+ break;
+ case gbk_targ_ndsa:
+ s = "ndsa";
+ break;
+ case gbk_targ_irix:
+ s = "irix";
+ break;
+ case gbk_targ_9x86:
+ s = "9x86";
+ break;
+ case gbk_targ_9x64:
+ s = "9x64";
+ break;
+ case gbk_targ_9arm:
+ s = "9arm";
+ break;
+ case gbk_targ_9a64:
+ s = "9a64";
+ break;
+ default:
+ s = "(unknown Target)";
+ break;
+ }
+ return s;
+}
+
+LOCALFUNC tMyErr TryAsTargetOptionNot(void)
+{
+ return FindNamedOption("-t", kNumTargets, GetTargetName,
+ &cur_targ, &olv_targ);
+}
+
+LOCALFUNC tMyErr ChooseTarg(void)
+{
+ tMyErr err;
+
+ if (kListOptionAuto == cur_targ) {
+ err = ReportParseFailure("target not specified ('-t' switch)");
+ } else {
+ err = kMyErr_noErr;
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptTarg(void)
+{
+ WriteCStrToDestFile(" ");
+ WriteCStrToDestFile("-t");
+ WriteCStrToDestFile(" ");
+ WriteCStrToDestFile(GetTargetName(cur_targ));
+}
+
+
+/* option: debug level */
+
+enum {
+ gbk_dbg_off,
+ gbk_dbg_test,
+ gbk_dbg_on,
+ kNumDebugLevels
+};
+
+LOCALVAR int gbo_dbg;
+LOCALVAR ui3r olv_dbg;
+
+LOCALPROC ResetDbgOption(void)
+{
+ gbo_dbg = kListOptionAuto;
+ olv_dbg = 0;
+}
+
+LOCALFUNC char * GetDbgLvlName(int i)
+{
+ char *s;
+
+ switch (i) {
+ case gbk_dbg_on:
+ s = "d";
+ break;
+ case gbk_dbg_test:
+ s = "t";
+ break;
+ case gbk_dbg_off:
+ s = "s";
+ break;
+ default:
+ s = "(unknown Debug Level)";
+ break;
+ }
+ return s;
+}
+
+LOCALFUNC tMyErr TryAsDbgOptionNot(void)
+{
+ return FindNamedOption("-d",
+ kNumDebugLevels, GetDbgLvlName, &gbo_dbg, &olv_dbg);
+}
+
+#define dfo_dbg() gbk_dbg_off
+
+LOCALFUNC tMyErr ChooseDbgOption(void)
+{
+ if (kListOptionAuto == gbo_dbg) {
+ gbo_dbg = dfo_dbg();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptDbgOption(void)
+{
+ WrtOptNamedOption("-d", GetDbgLvlName, gbo_dbg, dfo_dbg());
+}
+
+
+/* option: language */
+
+enum {
+ gbk_lang_eng,
+ gbk_lang_fre,
+ gbk_lang_ita,
+ gbk_lang_ger,
+ gbk_lang_dut,
+ gbk_lang_spa,
+ gbk_lang_pol,
+ gbk_lang_ptb,
+ gbk_lang_cat,
+ gbk_lang_cze,
+ gbk_lang_srl,
+ kNumLangLevels
+};
+
+LOCALVAR int gbo_lang;
+LOCALVAR ui3r olv_lang;
+
+LOCALPROC ResetLangOption(void)
+{
+ gbo_lang = kListOptionAuto;
+ olv_lang = 0;
+}
+
+LOCALFUNC char * GetLangName(int i)
+{
+ /* ISO 639-2/B */
+ char *s;
+
+ switch (i) {
+ case gbk_lang_eng:
+ s = "eng";
+ break;
+ case gbk_lang_fre:
+ s = "fre";
+ break;
+ case gbk_lang_ita:
+ s = "ita";
+ break;
+ case gbk_lang_ger:
+ s = "ger";
+ break;
+ case gbk_lang_dut:
+ s = "dut";
+ break;
+ case gbk_lang_spa:
+ s = "spa";
+ break;
+ case gbk_lang_pol:
+ s = "pol";
+ break;
+ case gbk_lang_ptb:
+ s = "ptb";
+ break;
+ case gbk_lang_cat:
+ s = "cat";
+ break;
+ case gbk_lang_cze:
+ s = "cze";
+ break;
+ case gbk_lang_srl:
+ s = "srl";
+ break;
+ default:
+ s = "(unknown Language Level)";
+ break;
+ }
+ return s;
+}
+
+LOCALFUNC tMyErr TryAsLangOptionNot(void)
+{
+ return FindNamedOption("-lang",
+ kNumLangLevels, GetLangName, &gbo_lang, &olv_lang);
+}
+
+LOCALFUNC char * GetLProjName(int i)
+{
+ /*
+ As used in OS X, IETF language tags, except when not
+ */
+ char *s;
+
+ switch (i) {
+ case gbk_lang_eng:
+ s = "English";
+ break;
+ case gbk_lang_fre:
+ s = "French";
+ break;
+ case gbk_lang_ita:
+ s = "Italian";
+ break;
+ case gbk_lang_ger:
+ s = "German";
+ break;
+ case gbk_lang_dut:
+ s = "Dutch";
+ break;
+ case gbk_lang_spa:
+ s = "Spanish";
+ break;
+ case gbk_lang_pol:
+ s = "pl";
+ break;
+ case gbk_lang_ptb:
+ s = "pt_BR";
+ break;
+ case gbk_lang_cat:
+ s = "ca";
+ break;
+ case gbk_lang_cze:
+ s = "cs";
+ break;
+ case gbk_lang_srl:
+ s = "sr";
+ break;
+ default:
+ s = "(unknown Language Level)";
+ break;
+ }
+ return s;
+}
+
+#define dfo_lang() gbk_lang_eng
+
+LOCALFUNC tMyErr ChooseLangOption(void)
+{
+ if (kListOptionAuto == gbo_lang) {
+ gbo_lang = dfo_lang();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptLangOption(void)
+{
+ WrtOptNamedOption("-lang", GetLangName, gbo_lang, dfo_lang());
+}
+
+
+/* option: IconMaster */
+
+#ifndef WantIconMasterDflt
+#define WantIconMasterDflt falseblnr
+#endif
+
+LOCALVAR blnr WantIconMaster;
+LOCALVAR ui3r olv_IconMaster;
+
+LOCALPROC ResetIconMaster(void)
+{
+ WantIconMaster = nanblnr;
+ olv_IconMaster = 0;
+}
+
+LOCALFUNC tMyErr TryAsIconMasterNot(void)
+{
+ return BooleanTryAsOptionNot("-im",
+ &WantIconMaster, &olv_IconMaster);
+}
+
+LOCALFUNC tMyErr ChooseIconMaster(void)
+{
+ if (nanblnr == WantIconMaster) {
+ WantIconMaster = WantIconMasterDflt;
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptIconMaster(void)
+{
+ WrtOptBooleanOption("-im", WantIconMaster, WantIconMasterDflt);
+}
+
+
+/* option: Test Compile Time Error */
+
+LOCALVAR blnr gbo_TstCompErr;
+LOCALVAR ui3r olv_TstCompErr;
+
+LOCALPROC ResetTstCompErr(void)
+{
+ gbo_TstCompErr = nanblnr;
+ olv_TstCompErr = 0;
+}
+
+LOCALFUNC tMyErr TryAsTstCompErrNot(void)
+{
+ return BooleanTryAsOptionNot("-cte",
+ &gbo_TstCompErr, &olv_TstCompErr);
+}
+
+#define dfo_TstCompErr() falseblnr
+
+LOCALFUNC tMyErr ChooseTstCompErr(void)
+{
+ if (nanblnr == gbo_TstCompErr) {
+ gbo_TstCompErr = dfo_TstCompErr();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptTstCompErr(void)
+{
+ WrtOptBooleanOption("-cte", gbo_TstCompErr, dfo_TstCompErr());
+}
+
+
+/* option: Test Build System Error */
+
+LOCALFUNC tMyErr TryAsTstBldSysErr(void)
+{
+ tMyErr err;
+
+ if (! CurArgIsCStr_v2("-bte")) {
+ err = kMyErrNoMatch;
+ } else {
+ err = ReportParseFailure("Testing Build System Error");
+ }
+
+ return err;
+}
+
+
+/* option: target cpu family */
+
+enum {
+ gbk_cpufam_68k, /* Motorola 680x0 */
+ gbk_cpufam_ppc, /* PowerPC */
+ gbk_cpufam_x86, /* Intel 80x86 */
+ gbk_cpufam_spr, /* SPARC */
+ gbk_cpufam_arm, /* ARM */
+ gbk_cpufam_x64, /* x86-64 (aka AMD64, Intel 64) */
+ gbk_cpufam_mip, /* MIPS */
+ gbk_cpufam_gen, /* Generic (don't know) */
+ gbk_cpufam_a64, /* AARCH64 */
+ kNumCPUFamilies
+};
+
+LOCALVAR int gbo_cpufam;
+LOCALVAR ui3r olv_cpufam;
+
+LOCALPROC ResetCPUFamOption(void)
+{
+ gbo_cpufam = kListOptionAuto;
+ olv_cpufam = 0;
+}
+
+LOCALFUNC char * GetCPUFamName(int i)
+{
+ char *s;
+
+ switch (i) {
+ case gbk_cpufam_68k:
+ s = "68k";
+ break;
+ case gbk_cpufam_ppc:
+ s = "ppc";
+ break;
+ case gbk_cpufam_x86:
+ s = "x86";
+ break;
+ case gbk_cpufam_spr:
+ s = "spr";
+ break;
+ case gbk_cpufam_arm:
+ s = "arm";
+ break;
+ case gbk_cpufam_x64:
+ s = "x64";
+ break;
+ case gbk_cpufam_mip:
+ s = "mip";
+ break;
+ case gbk_cpufam_gen:
+ s = "gen";
+ break;
+ default:
+ s = "(unknown CPU)";
+ break;
+ }
+ return s;
+}
+
+LOCALFUNC tMyErr TryAsCPUFamOptionNot(void)
+{
+ return FindNamedOption("-cpu",
+ kNumCPUFamilies, GetCPUFamName, &gbo_cpufam, &olv_cpufam);
+}
+
+LOCALFUNC int dfo_cpufam(void)
+{
+ int v;
+
+ switch (cur_targ) {
+ case gbk_targ_m68k:
+ case gbk_targ_mfpu:
+ v = gbk_cpufam_68k;
+ break;
+ case gbk_targ_mppc:
+ case gbk_targ_carb:
+ case gbk_targ_mach:
+ case gbk_targ_mx11:
+ case gbk_targ_lppc:
+ case gbk_targ_fbpc:
+ v = gbk_cpufam_ppc;
+ break;
+ case gbk_targ_wx86:
+ case gbk_targ_wc86:
+ case gbk_targ_lx86:
+ case gbk_targ_sl86:
+ case gbk_targ_fbsd:
+ case gbk_targ_obsd:
+ case gbk_targ_nbsd:
+ case gbk_targ_dbsd:
+ case gbk_targ_oind:
+ case gbk_targ_minx:
+ case gbk_targ_imch:
+ case gbk_targ_mi11:
+ case gbk_targ_cygw:
+ case gbk_targ_9x86:
+ v = gbk_cpufam_x86;
+ break;
+ case gbk_targ_lspr:
+ case gbk_targ_slrs:
+ v = gbk_cpufam_spr;
+ break;
+ case gbk_targ_wcar:
+ case gbk_targ_ndsa:
+ case gbk_targ_larm:
+ case gbk_targ_9arm:
+ v = gbk_cpufam_arm;
+ break;
+ case gbk_targ_mc64:
+ case gbk_targ_lx64:
+ case gbk_targ_wx64:
+ case gbk_targ_fb64:
+ case gbk_targ_ob64:
+ case gbk_targ_nb64:
+ case gbk_targ_db64:
+ case gbk_targ_oi64:
+ case gbk_targ_mx64:
+ case gbk_targ_9x64:
+ v = gbk_cpufam_x64;
+ break;
+ case gbk_targ_irix:
+ v = gbk_cpufam_mip;
+ break;
+ case gbk_targ_xgen:
+ v = gbk_cpufam_gen;
+ break;
+ case gbk_targ_9a64:
+ v = gbk_cpufam_a64;
+ break;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseCPUFam(void)
+{
+ if (kListOptionAuto == gbo_cpufam) {
+ gbo_cpufam = dfo_cpufam();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptCPUFam(void)
+{
+ WrtOptNamedOption("-cpu", GetCPUFamName, gbo_cpufam, dfo_cpufam());
+}
+
+/* derived option: target family */
+
+enum {
+ gbk_targfam_cmac, /* Classic Mac */
+ gbk_targfam_mach, /* OS X Macho */
+ gbk_targfam_mswn, /* Microsoft Windows */
+ gbk_targfam_linx, /* Linux */
+ gbk_targfam_fbsd, /* FreeBSD */
+ gbk_targfam_obsd, /* OpenBSD */
+ gbk_targfam_nbsd, /* NetBSD */
+ gbk_targfam_dbsd, /* Dragonfly BSD */
+ gbk_targfam_slrs, /* Solaris */
+ gbk_targfam_oind, /* OpenIndiana */
+ gbk_targfam_irix, /* Silicon Graphics's IRIX */
+ gbk_targfam_minx, /* Minix */
+ gbk_targfam_wnce, /* Windows CE */
+ gbk_targfam_carb, /* MacOS Carbon lib for OS 9 and OS X */
+ gbk_targfam_mx11, /* X11 for MacOS X */
+ gbk_targfam_cygw, /* Cygwin/X */
+ gbk_targfam_xgen, /* Generic X11 */
+ gbk_targfam_lnds, /* libnds for Nintendo DS */
+ gbk_targfam_nein, /* Plan 9 */
+ kNumTargFamilies
+};
+
+LOCALVAR int gbo_targfam;
+
+LOCALFUNC tMyErr ChooseTargFam(void)
+{
+ switch (cur_targ) {
+ case gbk_targ_m68k:
+ case gbk_targ_mfpu:
+ case gbk_targ_mppc:
+ gbo_targfam = gbk_targfam_cmac;
+ break;
+ case gbk_targ_mach:
+ case gbk_targ_imch:
+ case gbk_targ_mc64:
+ gbo_targfam = gbk_targfam_mach;
+ break;
+ case gbk_targ_wx86:
+ case gbk_targ_wx64:
+ gbo_targfam = gbk_targfam_mswn;
+ break;
+ case gbk_targ_lx86:
+ case gbk_targ_lppc:
+ case gbk_targ_lx64:
+ case gbk_targ_larm:
+ case gbk_targ_lspr:
+ gbo_targfam = gbk_targfam_linx;
+ break;
+ case gbk_targ_slrs:
+ case gbk_targ_sl86:
+ gbo_targfam = gbk_targfam_slrs;
+ break;
+ case gbk_targ_fbsd:
+ case gbk_targ_fb64:
+ case gbk_targ_fbpc:
+ gbo_targfam = gbk_targfam_fbsd;
+ break;
+ case gbk_targ_obsd:
+ case gbk_targ_ob64:
+ gbo_targfam = gbk_targfam_obsd;
+ break;
+ case gbk_targ_nbsd:
+ case gbk_targ_nb64:
+ gbo_targfam = gbk_targfam_nbsd;
+ break;
+ case gbk_targ_dbsd:
+ case gbk_targ_db64:
+ gbo_targfam = gbk_targfam_dbsd;
+ break;
+ case gbk_targ_oind:
+ case gbk_targ_oi64:
+ gbo_targfam = gbk_targfam_oind;
+ break;
+ case gbk_targ_minx:
+ gbo_targfam = gbk_targfam_minx;
+ break;
+ case gbk_targ_irix:
+ gbo_targfam = gbk_targfam_irix;
+ break;
+ case gbk_targ_wcar:
+ case gbk_targ_wc86:
+ gbo_targfam = gbk_targfam_wnce;
+ break;
+ case gbk_targ_carb:
+ gbo_targfam = gbk_targfam_carb;
+ break;
+ case gbk_targ_mx11:
+ case gbk_targ_mi11:
+ case gbk_targ_mx64:
+ gbo_targfam = gbk_targfam_mx11;
+ break;
+ case gbk_targ_cygw:
+ gbo_targfam = gbk_targfam_cygw;
+ break;
+ case gbk_targ_ndsa:
+ gbo_targfam = gbk_targfam_lnds;
+ break;
+ case gbk_targ_9x86:
+ case gbk_targ_9x64:
+ case gbk_targ_9arm:
+ case gbk_targ_9a64:
+ gbo_targfam = gbk_targfam_nein;
+ break;
+ case gbk_targ_xgen:
+ default:
+ gbo_targfam = gbk_targfam_xgen;
+ break;
+ }
+
+ return kMyErr_noErr;
+}
+
+
+/* option: api family */
+
+enum {
+ gbk_apifam_mac,
+ gbk_apifam_osx,
+ gbk_apifam_win,
+ gbk_apifam_xwn,
+ gbk_apifam_nds,
+ gbk_apifam_gtk,
+ gbk_apifam_sdl,
+ gbk_apifam_sd2,
+ gbk_apifam_cco,
+ gbk_apifam_9dr,
+ kNumAPIFamilies
+};
+
+LOCALVAR int gbo_apifam;
+LOCALVAR ui3r olv_apifam;
+
+LOCALPROC ResetAPIFamOption(void)
+{
+ gbo_apifam = kListOptionAuto;
+ olv_apifam = 0;
+}
+
+LOCALFUNC char * GetAPIFamName(int i)
+{
+ char *s;
+
+ switch (i) {
+ case gbk_apifam_mac:
+ s = "mac";
+ break;
+ case gbk_apifam_osx:
+ s = "osx";
+ break;
+ case gbk_apifam_win:
+ s = "win";
+ break;
+ case gbk_apifam_xwn:
+ s = "xwn";
+ break;
+ case gbk_apifam_nds:
+ s = "nds";
+ break;
+ case gbk_apifam_gtk:
+ s = "gtk";
+ break;
+ case gbk_apifam_sdl:
+ s = "sdl";
+ break;
+ case gbk_apifam_sd2:
+ s = "sd2";
+ break;
+ case gbk_apifam_cco:
+ s = "cco";
+ break;
+ case gbk_apifam_9dr:
+ s = "9dr";
+ break;
+ default:
+ s = "(unknown API)";
+ break;
+ }
+ return s;
+}
+
+LOCALFUNC tMyErr TryAsAPIFamOptionNot(void)
+{
+ return FindNamedOption("-api",
+ kNumAPIFamilies, GetAPIFamName, &gbo_apifam, &olv_apifam);
+}
+
+LOCALFUNC int dfo_apifam(void)
+{
+ int v;
+
+ switch (gbo_targfam) {
+ case gbk_targfam_cmac:
+ v = gbk_apifam_mac;
+ break;
+ case gbk_targfam_mach:
+ case gbk_targfam_carb:
+ if (gbk_cpufam_x64 == gbo_cpufam) {
+ v = gbk_apifam_cco;
+ } else {
+ v = gbk_apifam_osx;
+ }
+ break;
+ case gbk_targfam_mswn:
+ case gbk_targfam_wnce:
+ v = gbk_apifam_win;
+ break;
+ case gbk_targfam_linx:
+ case gbk_targfam_slrs:
+ case gbk_targfam_fbsd:
+ case gbk_targfam_obsd:
+ case gbk_targfam_nbsd:
+ case gbk_targfam_dbsd:
+ case gbk_targfam_oind:
+ case gbk_targfam_minx:
+ case gbk_targfam_irix:
+ case gbk_targfam_mx11:
+ case gbk_targfam_cygw:
+ case gbk_targfam_xgen:
+ v = gbk_apifam_xwn;
+ break;
+ case gbk_targfam_lnds:
+ v = gbk_apifam_nds;
+ break;
+ case gbk_targfam_nein:
+ v = gbk_apifam_9dr;
+ break;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseAPIFam(void)
+{
+ if (kListOptionAuto == gbo_apifam) {
+ gbo_apifam = dfo_apifam();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptAPIFam(void)
+{
+ WrtOptNamedOption("-api", GetAPIFamName, gbo_apifam, dfo_apifam());
+}
+
+
+/* option: print file list */
+
+LOCALVAR blnr CurPrintCFiles;
+LOCALVAR ui3r olv_PrintCFiles;
+
+LOCALPROC ResetListOption(void)
+{
+ CurPrintCFiles = falseblnr;
+ olv_PrintCFiles = 0;
+}
+
+LOCALFUNC tMyErr TryAsListOptionNot(void)
+{
+ return FlagTryAsOptionNot("-l", &CurPrintCFiles, &olv_PrintCFiles);
+}
+
+LOCALFUNC tMyErr ChooseListOption(void)
+{
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptListOption(void)
+{
+ WrtOptFlagOption("-l", CurPrintCFiles);
+}
+
+/* derived option: application is os x bundle (folder) */
+
+LOCALVAR blnr HaveMacBundleApp;
+LOCALVAR blnr WantUnTranslocate;
+
+LOCALFUNC tMyErr ChooseHaveMacBundleApp(void)
+{
+ HaveMacBundleApp = (gbk_targfam_mach == gbo_targfam)
+ || ((gbk_targfam_carb == gbo_targfam)
+ && (gbk_ide_mpw == cur_ide));
+#if 0
+ WantUnTranslocate = (gbk_apifam_cco == gbo_apifam)
+ && ((gbk_cpufam_x64 == gbo_cpufam)
+ || (gbk_cpufam_x86 == gbo_cpufam));
+#else
+ WantUnTranslocate = falseblnr;
+ /*
+ on second thought, probably not a good
+ idea to use undocumented calls.
+ */
+#endif
+
+ return kMyErr_noErr;
+}
+
+/* derived option: have macintosh resources */
+
+LOCALVAR blnr HaveMacRrscs;
+
+LOCALFUNC tMyErr ChooseHaveMacRrscs(void)
+{
+ HaveMacRrscs = (gbk_apifam_mac == gbo_apifam)
+ || ((gbk_targfam_carb == gbo_targfam)
+ && ! (gbk_ide_mpw == cur_ide));
+
+ return kMyErr_noErr;
+}
+
+
+/* option: Abbrev Name */
+
+LOCALVAR char vStrAppAbbrev[8 + 1];
+LOCALVAR ui3r olv_AbbrevName;
+
+LOCALPROC ResetAbbrevName(void)
+{
+ vStrAppAbbrev[0] = 0;
+ olv_AbbrevName = 0;
+}
+
+LOCALFUNC tMyErr TryAsAbbrevNameOptionNot(void)
+{
+ tMyErr err;
+ MyPStr t;
+
+ if (kMyErr_noErr != (err =
+ CurArgIsOption("-an", &olv_AbbrevName)))
+ {
+ /* no */
+ } else
+ if (The_arg_end) {
+ PStrFromCStr(t, "Expecting an argument for ");
+ PStrApndCStr(t, "-an");
+ PStrApndCStr(t, " when reached end");
+ err = ReportParseFailPStr(t);
+ } else
+ {
+ GetCurArgAsCStr(vStrAppAbbrev, 8);
+ err = AdvanceTheArg();
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr ChooseAbbrevName(void)
+{
+ if (0 == vStrAppAbbrev[0]) {
+ CStrCopy(vStrAppAbbrev, kStrAppAbbrev);
+ }
+
+ return kMyErr_noErr;
+}
+
+
+/* option: Variation Name */
+
+LOCALVAR char vVariationName[64 + 1];
+LOCALVAR ui3r olv_VariationName;
+
+LOCALPROC ResetVariationName(void)
+{
+ vVariationName[0] = 0;
+ olv_VariationName = 0;
+}
+
+LOCALFUNC tMyErr TryAsVariationNameOptionNot(void)
+{
+ tMyErr err;
+ MyPStr t;
+
+ if (kMyErr_noErr != (err =
+ CurArgIsOption("-n", &olv_VariationName)))
+ {
+ /* no */
+ } else
+ if (The_arg_end) {
+ PStrFromCStr(t, "Expecting an argument for ");
+ PStrApndCStr(t, "-n");
+ PStrApndCStr(t, " when reached end");
+ err = ReportParseFailPStr(t);
+ } else
+ {
+ GetCurArgAsCStr(vVariationName, 64);
+ err = AdvanceTheArg();
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr ChooseVariationName(void)
+{
+ if (0 == vVariationName[0]) {
+ MyPStr s;
+
+ PStrFromCStr(s, vStrAppAbbrev);
+ PStrApndCStr(s, "-");
+ PStrApndNUimr(s, MajorVersion, 2);
+ PStrApndCStr(s, ".");
+ PStrApndNUimr(s, MinorVersion, 2);
+ PStrApndCStr(s, "-");
+ /* PStrApndCStr(s, GetIdeName(cur_ide)); */
+ PStrApndCStr(s, GetTargetName(cur_targ));
+ /* PStrApndCStr(s, GetDbgLvlName(gbo_dbg)); */
+ CStrFromPStr(s, vVariationName);
+ }
+
+ return kMyErr_noErr;
+}
+
+
+/* option: Need International Characters */
+
+LOCALVAR blnr NeedIntl;
+LOCALVAR ui3r olv_NeedIntl;
+
+LOCALPROC ResetNeedIntl(void)
+{
+ NeedIntl = falseblnr;
+ olv_NeedIntl = 0;
+}
+
+LOCALFUNC tMyErr TryAsNeedIntlNot(void)
+{
+ return FlagTryAsOptionNot("-intl", &NeedIntl, &olv_NeedIntl);
+}
+
+LOCALFUNC tMyErr ChooseNeedIntl(void)
+{
+ return kMyErr_noErr;
+}
+
+
+/* option: Demo Message */
+
+LOCALVAR blnr WantDemoMsg;
+LOCALVAR ui3r olv_DemoMsg;
+
+LOCALPROC ResetDemoMsg(void)
+{
+ WantDemoMsg = nanblnr;
+ olv_DemoMsg = 0;
+}
+
+LOCALFUNC tMyErr TryAsDemoMsgNot(void)
+{
+ return BooleanTryAsOptionNot("-dmo", &WantDemoMsg, &olv_DemoMsg);
+}
+
+#define dfo_DemoMsg() falseblnr
+
+LOCALFUNC tMyErr ChooseDemoMsg(void)
+{
+ if (nanblnr == WantDemoMsg) {
+ WantDemoMsg = dfo_DemoMsg();
+ }
+
+ return kMyErr_noErr;
+}
+
+
+/* option: Activation Code */
+
+LOCALVAR blnr WantActvCode;
+#define NumKeyCon 7
+LOCALVAR long KeyCon[NumKeyCon];
+LOCALVAR ui3r olv_ActvCode;
+
+LOCALPROC ResetActvCode(void)
+{
+ WantActvCode = falseblnr;
+ olv_ActvCode = 0;
+}
+
+LOCALFUNC tMyErr TryAsActvCodeNot(void)
+{
+ tMyErr err;
+ int i;
+
+ if (kMyErr_noErr != (err = CurArgIsOption("-act", &olv_ActvCode))) {
+ /* no */
+ } else
+ {
+ WantActvCode = trueblnr;
+ for (i = 0; i < NumKeyCon; ++i) {
+ err = GetCurArgOptionAsNumber("-act", &KeyCon[i]);
+ if (kMyErr_noErr != err) {
+ goto Label_1;
+ }
+ }
+ err = kMyErr_noErr;
+Label_1:
+ ;
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr ChooseActvCode(void)
+{
+ return kMyErr_noErr;
+}
+
+
+/* --- end of default definition of options --- */
+
+LOCALPROC GNResetCommandLineParameters(void)
+{
+ ResetBranchOption();
+ ResetTargetOption();
+ ResetDbgOption();
+ ResetLangOption();
+ ResetIconMaster();
+ ResetTstCompErr();
+}
+
+LOCALFUNC tMyErr TryAsGNOptionNot(void)
+{
+ tMyErr err;
+
+ if (kMyErrNoMatch == (err = TryAsBranchOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsTargetOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsDbgOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsLangOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsIconMasterNot()))
+ if (kMyErrNoMatch == (err = TryAsTstCompErrNot()))
+ if (kMyErrNoMatch == (err = TryAsTstBldSysErr()))
+ {
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr AutoChooseGNSettings(void)
+{
+ tMyErr err;
+
+ if (kMyErr_noErr == (err = ChooseBranch()))
+ if (kMyErr_noErr == (err = ChooseTarg()))
+ if (kMyErr_noErr == (err = ChooseDbgOption()))
+ if (kMyErr_noErr == (err = ChooseLangOption()))
+ if (kMyErr_noErr == (err = ChooseIconMaster()))
+ if (kMyErr_noErr == (err = ChooseTstCompErr()))
+ {
+ err = kMyErr_noErr;
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptGNSettings(void)
+{
+ WrtOptBranchOption();
+ WrtOptTarg();
+ WrtOptDbgOption();
+ WrtOptLangOption();
+ WrtOptIconMaster();
+ WrtOptTstCompErr();
+}
+
+LOCALPROC GNDevResetCommandLineParameters(void)
+{
+ ResetCPUFamOption();
+ ResetAPIFamOption();
+ ResetListOption();
+ ResetAbbrevName();
+ ResetVariationName();
+ ResetNeedIntl();
+ ResetDemoMsg();
+ ResetActvCode();
+}
+
+LOCALFUNC tMyErr TryAsGNDevOptionNot(void)
+{
+ tMyErr err;
+
+ DoingDevOpts = trueblnr;
+
+ if (kMyErrNoMatch == (err = TryAsCPUFamOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsAPIFamOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsListOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsAbbrevNameOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsVariationNameOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsNeedIntlNot()))
+ if (kMyErrNoMatch == (err = TryAsDemoMsgNot()))
+ if (kMyErrNoMatch == (err = TryAsActvCodeNot()))
+ {
+ }
+
+ DoingDevOpts = falseblnr;
+
+ return err;
+}
+
+LOCALFUNC tMyErr AutoChooseGNDevSettings(void)
+{
+ tMyErr err;
+
+ if (kMyErr_noErr == (err = ChooseCPUFam()))
+ if (kMyErr_noErr == (err = ChooseTargFam())) /* derived */
+ if (kMyErr_noErr == (err = ChooseAPIFam()))
+ if (kMyErr_noErr == (err = ChooseListOption()))
+ if (kMyErr_noErr == (err = ChooseHaveMacBundleApp())) /* derived */
+ if (kMyErr_noErr == (err = ChooseHaveMacRrscs())) /* derived */
+ if (kMyErr_noErr == (err = ChooseAbbrevName()))
+ if (kMyErr_noErr == (err = ChooseVariationName()))
+ if (kMyErr_noErr == (err = ChooseNeedIntl()))
+ if (kMyErr_noErr == (err = ChooseDemoMsg()))
+ if (kMyErr_noErr == (err = ChooseActvCode()))
+ {
+ err = kMyErr_noErr;
+ }
+
+ return err;
+}
+
+#if 0
+LOCALPROC WrtOptGNDevSettings(void)
+{
+ WrtOptCPUFam();
+ WrtOptAPIFam();
+ WrtOptListOption();
+ /* Maintainer */
+ /* HomePage */
+ /* Sponsor */
+ /* VariationName */
+ /* AbbrevName */
+ /* ConfigDir */
+ /* Err2File */
+ /* WantDemoMsg */
+ /* WantActvCode */
+}
+#endif
--- /dev/null
+++ b/setup/SPBASDEF.i
@@ -1,0 +1,34 @@
+/*
+ SPBASDEF.i
+ Copyright (C) 2009 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ program SPecific BASic DEFinitions
+*/
+
+
+#define kStrAppName "Mini vMac"
+#define kStrAppAbbrev "minivmac" /* [a-z0-9_]{1,8} */
+#define MajorVersion 36
+#define MinorVersion 04
+#define kStrCopyrightYear "2018"
+#define kMacCreatorSig "MnvM"
+#define kBundleIdentifier "com.gryphel.minivmac"
+#define kShortDescription "miniature Macintosh emulator"
+
+#define Have_SPBLDOPT 1
+#define Have_SPCNFGGL 1
+#define Have_SPCNFGAP 1
+
+#define UseOpenGLinOSX 1
--- /dev/null
+++ b/setup/SPBLDOPT.i
@@ -1,0 +1,3945 @@
+/*
+ SPBLDOPT.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ program SPecific BuiLD OPTions
+*/
+
+/* option: model */
+
+enum {
+ gbk_mdl_Twig43,
+ gbk_mdl_Twiggy,
+ gbk_mdl_128K,
+ gbk_mdl_512Ke,
+ gbk_mdl_Plus,
+ gbk_mdl_SE,
+ gbk_mdl_SEFDHD,
+ gbk_mdl_Classic,
+ gbk_mdl_PB100,
+ gbk_mdl_II,
+ gbk_mdl_IIx,
+ kNumModels
+};
+
+LOCALVAR int cur_mdl;
+LOCALVAR ui3r olv_mdl;
+
+LOCALPROC ResetModelOption(void)
+{
+ cur_mdl = kListOptionAuto;
+ olv_mdl = 0;
+}
+
+LOCALFUNC char * GetModelName(int i)
+{
+ char *s;
+
+ switch (i) {
+ case gbk_mdl_Twig43:
+ s = "Twig43";
+ break;
+ case gbk_mdl_Twiggy:
+ s = "Twiggy";
+ break;
+ case gbk_mdl_128K:
+ s = "128K";
+ break;
+ case gbk_mdl_512Ke:
+ s = "512Ke";
+ break;
+ case gbk_mdl_Plus:
+ s = "Plus";
+ break;
+ case gbk_mdl_SE:
+ s = "SE";
+ break;
+ case gbk_mdl_SEFDHD:
+ s = "SEFDHD";
+ break;
+ case gbk_mdl_Classic:
+ s = "Classic";
+ break;
+ case gbk_mdl_PB100:
+ s = "PB100";
+ break;
+ case gbk_mdl_II:
+ s = "II";
+ break;
+ case gbk_mdl_IIx:
+ s = "IIx";
+ break;
+ default:
+ s = "(unknown Model)";
+ break;
+ }
+ return s;
+}
+
+LOCALFUNC tMyErr TryAsModelOptionNot(void)
+{
+ return FindNamedOption("-m", kNumModels, GetModelName,
+ &cur_mdl, &olv_mdl);
+}
+
+#define dfo_mdl() gbk_mdl_Plus
+
+LOCALVAR blnr cur_mIIorIIX;
+
+LOCALFUNC tMyErr ChooseModel(void)
+{
+ if (kListOptionAuto == cur_mdl) {
+ cur_mdl = dfo_mdl();
+ }
+
+ cur_mIIorIIX = (gbk_mdl_II == cur_mdl) || (gbk_mdl_IIx == cur_mdl);
+
+#if 0
+ if (cur_mIIorIIX) {
+ if (gbk_cpufam_68k == gbo_cpufam) {
+ err = ReportParseFailure(
+ "Mac II emulation is not supported on Macintosh 680x0");
+ }
+ }
+#endif
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptModelOption(void)
+{
+ WrtOptNamedOption("-m", GetModelName, cur_mdl, dfo_mdl());
+}
+
+
+/* option: horizontal resolution */
+
+LOCALVAR uimr cur_hres;
+LOCALVAR ui3r olv_hres;
+
+LOCALPROC ResetHResOption(void)
+{
+ olv_hres = 0;
+}
+
+LOCALFUNC tMyErr TryAsHResOptionNot(void)
+{
+ return NumberTryAsOptionNot("-hres",
+ (long *)&cur_hres, &olv_hres);
+}
+
+LOCALFUNC uimr dfo_hres(void)
+{
+ uimr v;
+
+ if (cur_mIIorIIX) {
+ v = 640;
+ } else if (gbk_mdl_PB100 == cur_mdl) {
+ v = 640;
+ } else {
+ v = 512;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseHRes(void)
+{
+ tMyErr err;
+ MyPStr t;
+ MyPStr s;
+
+ if (0 == olv_hres) {
+ cur_hres = dfo_hres();
+ err = kMyErr_noErr;
+ } else {
+ if ((cur_hres & 0x1F) != 0) {
+ PStrFromCStr(t, "-hres must be a multiple of 32."
+ " The next lowest multiple is ");
+ PStrFromUimr(cur_hres & ~ 0x1F, s);
+ PStrAppend(t, s);
+ err = ReportParseFailPStr(t);
+ } else if (cur_hres < 128) {
+ err = ReportParseFailure("-hres must be >= 128");
+ } else if (cur_hres >= (uimr)32 * 1024) {
+ err = ReportParseFailure("-hres must be < 32k");
+ } else {
+ err = kMyErr_noErr;
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptHResOption(void)
+{
+ WrtOptNumberOption("-hres", cur_hres, dfo_hres());
+}
+
+
+/* option: vertical resolution */
+
+LOCALVAR uimr cur_vres;
+LOCALVAR ui3r olv_vres;
+
+LOCALPROC ResetVResOption(void)
+{
+ olv_vres = 0;
+}
+
+LOCALFUNC tMyErr TryAsVResOptionNot(void)
+{
+ return NumberTryAsOptionNot("-vres", (long *)&cur_vres, &olv_vres);
+}
+
+LOCALFUNC uimr dfo_vres(void)
+{
+ uimr v;
+
+ if (cur_mIIorIIX) {
+ v = 480;
+ } else if (gbk_mdl_PB100 == cur_mdl) {
+ v = 400;
+ } else {
+ v = 342;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseVRes(void)
+{
+ tMyErr err;
+
+ if (0 == olv_vres) {
+ cur_vres = dfo_vres();
+ err = kMyErr_noErr;
+ } else {
+ if (cur_vres < 128) {
+ err = ReportParseFailure("-vres must be >= 128");
+ } else if (cur_vres >= (uimr)32 * 1024) {
+ err = ReportParseFailure("-vres must be < 32k");
+ } else {
+ err = kMyErr_noErr;
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptVResOption(void)
+{
+ WrtOptNumberOption("-vres", cur_vres, dfo_vres());
+}
+
+
+/* option: screen depth */
+
+LOCALVAR uimr cur_ScrnDpth;
+LOCALVAR ui3r olv_ScrnDpth;
+
+LOCALPROC ResetScrnDpthOption(void)
+{
+ olv_ScrnDpth = 0;
+}
+
+LOCALFUNC tMyErr TryAsScrnDpthOptionNot(void)
+{
+ return NumberTryAsOptionNot("-depth",
+ (long *)&cur_ScrnDpth, &olv_ScrnDpth);
+}
+
+LOCALFUNC uimr dfo_ScrnDpth(void)
+{
+ uimr v;
+
+ if (cur_mIIorIIX) {
+ v = 3;
+ } else {
+ v = 0;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseScrnDpth(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+
+ if (0 == olv_ScrnDpth) {
+ cur_ScrnDpth = dfo_ScrnDpth();
+ } else {
+ if (cur_mIIorIIX) {
+ if (cur_ScrnDpth > 5) {
+ err = ReportParseFailure("-depth must be <= 5");
+ }
+ } else {
+ if (cur_ScrnDpth != 0) {
+ err = ReportParseFailure(
+ "-depth must be 0 for this model");
+ }
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptScrnDpth(void)
+{
+ WrtOptNumberOption("-depth", cur_ScrnDpth, dfo_ScrnDpth());
+}
+
+
+/* option: Initial FullScreen */
+
+LOCALVAR blnr WantInitFullScreen;
+LOCALVAR ui3r olv_InitFullScreen;
+
+LOCALPROC ResetInitFullScreen(void)
+{
+ WantInitFullScreen = nanblnr;
+ olv_InitFullScreen = 0;
+}
+
+LOCALFUNC tMyErr TryAsInitFullScreenNot(void)
+{
+ return BooleanTryAsOptionNot("-fullscreen",
+ &WantInitFullScreen, &olv_InitFullScreen);
+}
+
+LOCALFUNC blnr dfo_InitFullScreen(void)
+{
+ blnr v;
+
+ v = gbk_targfam_wnce == gbo_targfam;
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseInitFullScreen(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+
+ if (nanblnr == WantInitFullScreen) {
+ WantInitFullScreen = dfo_InitFullScreen();
+ } else {
+ if (! WantInitFullScreen) {
+ if (gbk_targ_wcar == cur_targ) {
+ err = ReportParseFailure(
+ "-fullscreen 0 is not supported for -t wcar");
+ }
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptInitFullScreen(void)
+{
+ WrtOptBooleanOption("-fullscreen",
+ WantInitFullScreen, dfo_InitFullScreen());
+}
+
+
+/* option: Variable FullScreen */
+
+LOCALVAR blnr WantVarFullScreen;
+LOCALVAR ui3r olv_VarFullScreen;
+
+LOCALPROC ResetVarFullScreen(void)
+{
+ WantVarFullScreen = nanblnr;
+ olv_VarFullScreen = 0;
+}
+
+LOCALFUNC tMyErr TryAsVarFullScreenNot(void)
+{
+ return BooleanTryAsOptionNot("-var-fullscreen",
+ &WantVarFullScreen, &olv_VarFullScreen);
+}
+
+LOCALFUNC blnr dfo_VarFullScreen(void)
+{
+ blnr v;
+
+ if ((gbk_apifam_gtk == gbo_apifam)
+ || (gbk_targfam_wnce == gbo_targfam))
+ {
+ v = falseblnr;
+ } else {
+ v = trueblnr;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseVarFullScreen(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+
+ if (nanblnr == WantVarFullScreen) {
+ WantVarFullScreen = dfo_VarFullScreen();
+ } else {
+ if (WantVarFullScreen) {
+ if (gbk_targ_wcar == cur_targ) {
+ err = ReportParseFailure(
+ "-var-fullscreen is not supported for -t wcar");
+ }
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptVarFullScreen(void)
+{
+ WrtOptBooleanOption("-var-fullscreen",
+ WantVarFullScreen, dfo_VarFullScreen());
+}
+
+
+/* option: magnification factor */
+
+LOCALVAR uimr cur_MagFctr;
+LOCALVAR ui3r olv_MagFctr;
+
+LOCALPROC ResetMagFctrOption(void)
+{
+ olv_MagFctr = 0;
+}
+
+LOCALFUNC tMyErr TryAsMagFctrOptionNot(void)
+{
+ return NumberTryAsOptionNot("-mf",
+ (long *)&cur_MagFctr, &olv_MagFctr);
+}
+
+LOCALFUNC uimr dfo_MagFctr(void)
+{
+ uimr v;
+
+ if (gbk_apifam_gtk == gbo_apifam) {
+ /* temporary, until implemented */
+ v = 1;
+ } else {
+ v = 2;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseMagFctr(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+
+ if (0 == olv_MagFctr) {
+ cur_MagFctr = dfo_MagFctr();
+ } else {
+ if (cur_MagFctr < 1) {
+ err = ReportParseFailure("-mf must be >= 1");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptMagFctrOption(void)
+{
+ WrtOptNumberOption("-mf", cur_MagFctr, dfo_MagFctr());
+}
+
+
+/* option: Initial Magnify */
+
+LOCALVAR blnr WantInitMagnify;
+LOCALVAR ui3r olv_InitMagnify;
+
+LOCALPROC ResetInitMagnify(void)
+{
+ WantInitMagnify = nanblnr;
+ olv_InitMagnify = 0;
+}
+
+LOCALFUNC tMyErr TryAsInitMagnifyNot(void)
+{
+ return BooleanTryAsOptionNot("-magnify",
+ &WantInitMagnify, &olv_InitMagnify);
+}
+
+#define dfo_InitMagnify() falseblnr
+
+LOCALFUNC tMyErr ChooseInitMagnify(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (nanblnr == WantInitMagnify) {
+ WantInitMagnify = dfo_InitMagnify();
+ } else {
+ if (WantInitMagnify && (cur_MagFctr == 1)) {
+ err = ReportParseFailure(
+ "-magnify 1 does not make sense with -mf 1");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptInitMagnify(void)
+{
+ WrtOptBooleanOption("-magnify",
+ WantInitMagnify, dfo_InitMagnify());
+}
+
+
+/* option: sound */
+
+LOCALVAR blnr MySoundEnabled;
+LOCALVAR ui3r olv_SoundEnabled;
+
+LOCALPROC ResetSoundOption(void)
+{
+ MySoundEnabled = nanblnr;
+ olv_SoundEnabled = 0;
+}
+
+LOCALFUNC tMyErr TryAsSoundOptionNot(void)
+{
+ return BooleanTryAsOptionNot("-sound",
+ &MySoundEnabled, &olv_SoundEnabled);
+}
+
+LOCALFUNC blnr dfo_SoundEnabled(void)
+{
+ blnr v;
+
+ v = (gbk_apifam_mac == gbo_apifam)
+ || (gbk_apifam_osx == gbo_apifam)
+ || (gbk_apifam_win == gbo_apifam)
+ || (gbk_apifam_sdl == gbo_apifam)
+ || (gbk_apifam_sd2 == gbo_apifam)
+ || (gbk_apifam_9dr == gbo_apifam)
+ || (gbk_apifam_cco == gbo_apifam)
+ || ((gbk_apifam_xwn == gbo_apifam)
+ && ((gbo_targfam == gbk_targfam_linx)
+ || (gbo_targfam == gbk_targfam_fbsd)
+ || (gbo_targfam == gbk_targfam_nbsd)));
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseSoundEnabled(void)
+{
+ if (nanblnr == MySoundEnabled) {
+ MySoundEnabled = dfo_SoundEnabled();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptSoundOption(void)
+{
+ WrtOptBooleanOption("-sound", MySoundEnabled, dfo_SoundEnabled());
+}
+
+
+/* option: sound api */
+
+enum {
+ gbk_sndapi_none,
+ gbk_sndapi_alsa,
+ gbk_sndapi_ddsp,
+ kNumSndApiLevels
+};
+
+LOCALVAR int gbo_sndapi;
+LOCALVAR ui3r olv_sndapi;
+
+LOCALPROC ResetSndApiOption(void)
+{
+ gbo_sndapi = kListOptionAuto;
+ olv_sndapi = 0;
+}
+
+LOCALFUNC char * GetSndApiName(int i)
+{
+ char *s;
+
+ switch (i) {
+ case gbk_sndapi_none:
+ s = "none";
+ break;
+ case gbk_sndapi_alsa:
+ s = "alsa";
+ break;
+ case gbk_sndapi_ddsp:
+ s = "ddsp";
+ break;
+ default:
+ s = "(unknown sound api)";
+ break;
+ }
+ return s;
+}
+
+LOCALFUNC tMyErr TryAsSndApiOptionNot(void)
+{
+ return FindNamedOption("-snd-api",
+ kNumSndApiLevels, GetSndApiName, &gbo_sndapi, &olv_sndapi);
+}
+
+LOCALFUNC int dfo_sndapi(void)
+{
+ int v;
+
+ if (! MySoundEnabled) {
+ v = gbk_sndapi_none;
+ } else if (gbk_apifam_xwn != gbo_apifam) {
+ v = gbk_sndapi_none;
+ } else if (gbo_targfam == gbk_targfam_linx) {
+ v = gbk_sndapi_alsa;
+ } else {
+ v = gbk_sndapi_ddsp;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseSndApiOption(void)
+{
+ if (kListOptionAuto == gbo_sndapi) {
+ gbo_sndapi = dfo_sndapi();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptSndApiOption(void)
+{
+ WrtOptNamedOption("-snd-api", GetSndApiName,
+ gbo_sndapi, dfo_sndapi());
+}
+
+
+/* option: sound sample size */
+
+LOCALVAR uimr cur_SoundSampSz;
+LOCALVAR ui3r olv_SoundSampSz;
+
+LOCALPROC ResetSoundSampSzOption(void)
+{
+ olv_SoundSampSz = 0;
+}
+
+LOCALFUNC tMyErr TryAsSoundSampSzOptionNot(void)
+{
+ return NumberTryAsOptionNot("-sss",
+ (long *)&cur_SoundSampSz, &olv_SoundSampSz);
+}
+
+LOCALFUNC uimr dfo_SoundSampSz(void)
+{
+ uimr v;
+
+ if (gbk_sndapi_ddsp == gbo_sndapi) {
+ v = 4;
+ } else {
+ v = 3;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseSoundSampSz(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+
+
+ if (0 == olv_SoundSampSz) {
+ cur_SoundSampSz = dfo_SoundSampSz();
+ } else {
+ if ((cur_SoundSampSz < 3) || (cur_SoundSampSz > 4)) {
+ err = ReportParseFailure(
+ "-sss must be 3 or 4");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptSoundSampSzOption(void)
+{
+ WrtOptNumberOption("-sss", cur_SoundSampSz, dfo_SoundSampSz());
+}
+
+
+/* option: number of drives */
+
+LOCALVAR uimr cur_numdrives;
+LOCALVAR ui3r olv_numdrives;
+
+LOCALPROC ResetNumDrivesOption(void)
+{
+ olv_numdrives = 0;
+}
+
+LOCALFUNC tMyErr TryAsNumDrivesOptionNot(void)
+{
+ return NumberTryAsOptionNot("-drives",
+ (long *)&cur_numdrives, &olv_numdrives);
+}
+
+LOCALFUNC uimr dfo_numdrives(void)
+{
+ uimr v;
+
+ if (cur_mdl < gbk_mdl_512Ke) {
+ v = 2;
+ } else {
+ v = 6;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseNumDrives(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+
+
+ if (0 == olv_numdrives) {
+ cur_numdrives = dfo_numdrives();
+ } else {
+ if ((cur_numdrives <= 0) || (cur_numdrives > 32)) {
+ err = ReportParseFailure(
+ "-drives must be a number between 1 and 32");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptNumDrivesOption(void)
+{
+ WrtOptNumberOption("-drives", cur_numdrives, dfo_numdrives());
+}
+
+
+/* option: disk driver - support tags */
+
+LOCALVAR blnr SonySupportTags;
+LOCALVAR ui3r olv_SonySupportTags;
+
+LOCALPROC ResetSonySupportTags(void)
+{
+ SonySupportTags = nanblnr;
+ olv_SonySupportTags = 0;
+}
+
+LOCALFUNC tMyErr TryAsSonySupportTagsNot(void)
+{
+ return BooleanTryAsOptionNot("-sony-tag",
+ &SonySupportTags, &olv_SonySupportTags);
+}
+
+#define dfo_SonySupportTags() falseblnr
+
+LOCALFUNC tMyErr ChooseSonySupportTags(void)
+{
+ if (nanblnr == SonySupportTags) {
+ SonySupportTags = dfo_SonySupportTags();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptSonySupportTags(void)
+{
+ WrtOptBooleanOption("-sony-tag",
+ SonySupportTags, dfo_SonySupportTags());
+}
+
+
+/* option: disk driver - calculate checksums */
+
+LOCALVAR blnr SonyWantChecksumsUpdated;
+LOCALVAR ui3r olv_SonyWantChecksumsUpdated;
+
+LOCALPROC ResetSonyWantChecksumsUpdated(void)
+{
+ SonyWantChecksumsUpdated = nanblnr;
+ olv_SonyWantChecksumsUpdated = 0;
+}
+
+LOCALFUNC tMyErr TryAsSonyWantChecksumsUpdatedNot(void)
+{
+ return BooleanTryAsOptionNot("-sony-sum",
+ &SonyWantChecksumsUpdated, &olv_SonyWantChecksumsUpdated);
+}
+
+#define dfo_SonyWantChecksumsUpdated() falseblnr
+
+LOCALFUNC tMyErr ChooseSonyWantChecksumsUpdated(void)
+{
+ if (nanblnr == SonyWantChecksumsUpdated) {
+ SonyWantChecksumsUpdated = dfo_SonyWantChecksumsUpdated();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptSonyWantChecksumsUpdated(void)
+{
+ WrtOptBooleanOption("-sony-sum",
+ SonyWantChecksumsUpdated, dfo_SonyWantChecksumsUpdated());
+}
+
+
+/* option: disk driver - support disk copy 4.2 format */
+
+LOCALVAR blnr SonySupportDC42;
+LOCALVAR ui3r olv_SonySupportDC42;
+
+LOCALPROC ResetSonySupportDC42(void)
+{
+ SonySupportDC42 = nanblnr;
+ olv_SonySupportDC42 = 0;
+}
+
+LOCALFUNC tMyErr TryAsSonySupportDC42Not(void)
+{
+ return BooleanTryAsOptionNot("-sony-dc42",
+ &SonySupportDC42, &olv_SonySupportDC42);
+}
+
+#define dfo_SonySupportDC42() trueblnr
+
+LOCALFUNC tMyErr ChooseSonySupportDC42(void)
+{
+ if (nanblnr == SonySupportDC42) {
+ SonySupportDC42 = dfo_SonySupportDC42();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptSonySupportDC42(void)
+{
+ WrtOptBooleanOption("-sony-dc42",
+ SonySupportDC42, dfo_SonySupportDC42());
+}
+
+
+/* option: Save Dialog Enable */
+
+LOCALVAR blnr gbo_SaveDialogEnable;
+LOCALVAR ui3r olv_SaveDialogEnable;
+
+LOCALPROC ResetSaveDialogEnable(void)
+{
+ gbo_SaveDialogEnable = nanblnr;
+ olv_SaveDialogEnable = 0;
+}
+
+LOCALFUNC tMyErr TryAsSaveDialogEnable(void)
+{
+ return BooleanTryAsOptionNot("-svd",
+ &gbo_SaveDialogEnable, &olv_SaveDialogEnable);
+}
+
+#define dfo_SaveDialogEnable() trueblnr
+
+LOCALFUNC tMyErr ChooseSaveDialogEnable(void)
+{
+ if (nanblnr == gbo_SaveDialogEnable) {
+ gbo_SaveDialogEnable = dfo_SaveDialogEnable();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptSaveDialogEnable(void)
+{
+ WrtOptBooleanOption("-svd",
+ gbo_SaveDialogEnable, dfo_SaveDialogEnable());
+}
+
+
+/* option: Insert Ith Disk Image */
+
+LOCALVAR blnr WantInsertIthDisk;
+LOCALVAR ui3r olv_InsertIthDisk;
+
+LOCALPROC ResetInsertIthDisk(void)
+{
+ WantInsertIthDisk = nanblnr;
+ olv_InsertIthDisk = 0;
+}
+
+LOCALFUNC tMyErr TryAsInsertIthDisk(void)
+{
+ return BooleanTryAsOptionNot("-iid",
+ &WantInsertIthDisk, &olv_InsertIthDisk);
+}
+
+#define dfo_InsertIthDisk() falseblnr
+
+LOCALFUNC tMyErr ChooseInsertIthDisk(void)
+{
+ if (nanblnr == WantInsertIthDisk) {
+ WantInsertIthDisk = dfo_InsertIthDisk();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptInsertIthDisk(void)
+{
+ WrtOptBooleanOption("-iid",
+ WantInsertIthDisk, dfo_InsertIthDisk());
+}
+
+
+/* option: Command Option Swap */
+
+LOCALVAR blnr WantCmndOptSwap;
+LOCALVAR ui3r olv_CmndOptSwap;
+
+LOCALPROC ResetCmndOptSwap(void)
+{
+ WantCmndOptSwap = falseblnr;
+ olv_CmndOptSwap = 0;
+}
+
+LOCALFUNC tMyErr TryAsCmndOptSwapNot(void)
+{
+ return FlagTryAsOptionNot("-ccs",
+ &WantCmndOptSwap, &olv_CmndOptSwap);
+}
+
+LOCALFUNC tMyErr ChooseCmndOptSwap(void)
+{
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptCmndOptSwap(void)
+{
+ WrtOptFlagOption("-ccs", WantCmndOptSwap);
+}
+
+
+/* option: key mapping */
+
+enum {
+ gbk_keynam_Control,
+ gbk_keynam_Command,
+ gbk_keynam_Option,
+ gbk_keynam_Shift,
+ gbk_keynam_CapsLock,
+ gbk_keynam_Escape,
+ gbk_keynam_BackSlash,
+ gbk_keynam_Slash,
+ gbk_keynam_Grave,
+ gbk_keynam_Enter,
+ gbk_keynam_PageUp,
+ gbk_keynam_PageDown,
+ gbk_keynam_Home,
+ gbk_keynam_End,
+ gbk_keynam_Help,
+ gbk_keynam_ForwardDel,
+ gbk_keynam_F1,
+ gbk_keynam_F2,
+ gbk_keynam_F3,
+ gbk_keynam_F4,
+ gbk_keynam_F5,
+ kNumKeyNames
+};
+
+enum {
+ gbk_keynam_RControl = kNumKeyNames,
+ gbk_keynam_RCommand,
+ gbk_keynam_ROption,
+ gbk_keynam_RShift,
+ kNumSrcKeyNames
+};
+
+enum {
+ gbk_keynam_CM = kNumKeyNames,
+ kNumDstKeyNames
+};
+
+LOCALVAR ui3b gbo_keymap[kNumSrcKeyNames];
+LOCALVAR ui3r olv_keymap[kNumSrcKeyNames];
+
+LOCALPROC ResetKeyMapOption(void)
+{
+ uimr i;
+
+ for (i = 0; i < kNumSrcKeyNames; ++i) {
+ gbo_keymap[i] = 0xFF;
+ olv_keymap[i] = 0;
+ }
+}
+
+LOCALFUNC char * GetKeyMapName(int i)
+{
+ char *s;
+
+ switch (i) {
+ case gbk_keynam_Control:
+ s = "Control";
+ break;
+ case gbk_keynam_Command:
+ s = "Command";
+ break;
+ case gbk_keynam_Option:
+ s = "Option";
+ break;
+ case gbk_keynam_Shift:
+ s = "Shift";
+ break;
+ case gbk_keynam_CapsLock:
+ s = "CapsLock";
+ break;
+ case gbk_keynam_Escape:
+ s = "Escape";
+ break;
+ case gbk_keynam_BackSlash:
+ s = "BackSlash";
+ break;
+ case gbk_keynam_Slash:
+ s = "Slash";
+ break;
+ case gbk_keynam_Grave:
+ s = "Grave";
+ break;
+ case gbk_keynam_Enter:
+ s = "Enter";
+ break;
+ case gbk_keynam_PageUp:
+ s = "PageUp";
+ break;
+ case gbk_keynam_PageDown:
+ s = "PageDown";
+ break;
+ case gbk_keynam_Home:
+ s = "Home";
+ break;
+ case gbk_keynam_End:
+ s = "End";
+ break;
+ case gbk_keynam_Help:
+ s = "Help";
+ break;
+ case gbk_keynam_ForwardDel:
+ s = "ForwardDel";
+ break;
+ case gbk_keynam_F1:
+ s = "F1";
+ break;
+ case gbk_keynam_F2:
+ s = "F2";
+ break;
+ case gbk_keynam_F3:
+ s = "F3";
+ break;
+ case gbk_keynam_F4:
+ s = "F4";
+ break;
+ case gbk_keynam_F5:
+ s = "F5";
+ break;
+ default:
+ s = "(unknown key)";
+ break;
+ }
+
+ return s;
+}
+
+LOCALFUNC char * GetSrcKeyMapName(int i)
+{
+ char *s;
+
+ switch (i) {
+ case gbk_keynam_RControl:
+ s = "RControl";
+ break;
+ case gbk_keynam_RCommand:
+ s = "RCommand";
+ break;
+ case gbk_keynam_ROption:
+ s = "ROption";
+ break;
+ case gbk_keynam_RShift:
+ s = "RShift";
+ break;
+ default:
+ s = GetKeyMapName(i);
+ break;
+ }
+
+ return s;
+}
+
+LOCALFUNC char * GetDstKeyMapName(int i)
+{
+ char *s;
+
+ switch (i) {
+ case gbk_keynam_CM:
+ s = "CM";
+ break;
+ default:
+ s = GetKeyMapName(i);
+ break;
+ }
+
+ return s;
+}
+
+LOCALFUNC tMyErr TryAsKeyMapOptionNot(void)
+{
+ tMyErr err;
+ MyPStr t;
+ int k;
+ int j;
+
+ if (! CurArgIsCStr_v2("-km")) {
+ err = kMyErrNoMatch;
+ } else
+ if (kMyErr_noErr != (err = AdvanceTheArg())) {
+ /* fail */
+ } else
+ if (The_arg_end) {
+ PStrFromCStr(t,
+ "Expecting a src argument for -km when reached end");
+ err = ReportParseFailPStr(t);
+ } else
+ if (! GetCurArgNameIndex(kNumSrcKeyNames, GetSrcKeyMapName, &k)) {
+ PStrFromCStr(t, "Unknown source value for -km");
+ err = ReportParseFailPStr(t);
+ } else
+ if (olv_keymap[k] == olv_cur) {
+ PStrFromCStr(t,
+ "same -km src value has appeared more than once");
+ err = ReportParseFailPStr(t);
+ } else
+ if (kMyErr_noErr != (err = AdvanceTheArg())) {
+ /* fail */
+ } else
+ if (The_arg_end) {
+ PStrFromCStr(t,
+ "Expecting a dst argument for -km when reached end");
+ err = ReportParseFailPStr(t);
+ } else
+ if (! GetCurArgNameIndex(kNumDstKeyNames, GetDstKeyMapName, &j)) {
+ if (CurArgIsCStr_v2("*")) {
+ olv_keymap[k] = olv_cur;
+ gbo_keymap[k] = 0xFF;
+ err = AdvanceTheArg();
+ } else
+ {
+ PStrFromCStr(t, "Unknown dst value for -km");
+ err = ReportParseFailPStr(t);
+ }
+ } else
+
+ {
+ olv_keymap[k] = olv_cur;
+ gbo_keymap[k] = j;
+ err = AdvanceTheArg();
+ }
+
+ return err;
+}
+
+LOCALPROC dfo_keyset(ui3b *a, uimr i, ui3r v)
+{
+ a[i] = v;
+
+ if (0xFF == gbo_keymap[i]) {
+ gbo_keymap[i] = v;
+ }
+}
+
+LOCALPROC dfo_keymap(ui3b *a)
+{
+ uimr i;
+
+ dfo_keyset(a, gbk_keynam_Control,
+ WantCmndOptSwap ? gbk_keynam_Command : gbk_keynam_CM);
+ dfo_keyset(a, gbk_keynam_Command,
+ WantCmndOptSwap ? gbk_keynam_CM : gbk_keynam_Command);
+
+ for (i = gbk_keynam_Option; i <= gbk_keynam_ForwardDel; ++i) {
+ dfo_keyset(a, i, i);
+ }
+
+ dfo_keyset(a, gbk_keynam_F1, gbk_keynam_Option);
+ dfo_keyset(a, gbk_keynam_F2, gbk_keynam_Command);
+
+ for (i = gbk_keynam_F3; i <= gbk_keynam_F5; ++i) {
+ dfo_keyset(a, i, i);
+ }
+
+ dfo_keyset(a, gbk_keynam_RControl, gbo_keymap[gbk_keynam_Control]);
+ dfo_keyset(a, gbk_keynam_RCommand, gbo_keymap[gbk_keynam_Command]);
+ dfo_keyset(a, gbk_keynam_ROption, gbo_keymap[gbk_keynam_Option]);
+ dfo_keyset(a, gbk_keynam_RShift, gbo_keymap[gbk_keynam_Shift]);
+}
+
+LOCALFUNC ui3r KeyMapInverse(uimr v)
+{
+ uimr i;
+
+ for (i = 0; i < kNumSrcKeyNames; ++i) {
+ if (v == gbo_keymap[i]) {
+ return i;
+ }
+ }
+
+ return 0xFF;
+}
+
+LOCALVAR ui3r ControlModeKey;
+
+LOCALFUNC tMyErr ChooseKeyMap(void)
+{
+ tMyErr err;
+ ui3b a[kNumSrcKeyNames];
+
+ dfo_keymap(a);
+
+ ControlModeKey = KeyMapInverse(gbk_keynam_CM);
+
+ if (0xFF == ControlModeKey) {
+ err = ReportParseFailure(
+ "-km : no key maps to CM");
+ } else {
+ err = kMyErr_noErr;
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptKeyMap(void)
+{
+ ui3b a[kNumSrcKeyNames];
+ uimr i;
+
+ dfo_keymap(a);
+
+ for (i = 0; i < kNumSrcKeyNames; ++i) {
+ if (gbo_keymap[i] != a[i]) {
+ WriteCStrToDestFile(" -km ");
+ WriteCStrToDestFile(GetSrcKeyMapName(i));
+ WriteCStrToDestFile(" ");
+ WriteCStrToDestFile(GetDstKeyMapName(gbo_keymap[i]));
+ }
+ }
+}
+
+
+/* option: emulated key toggle mapping */
+
+LOCALVAR int gbo_EKTMap;
+LOCALVAR ui3r olv_EKTMap;
+
+LOCALPROC ResetEKTMapOption(void)
+{
+ gbo_EKTMap = kListOptionAuto;
+ olv_EKTMap = 0;
+}
+
+LOCALFUNC tMyErr TryAsEKTMapOptionNot(void)
+{
+ return FindNamedOption("-ekt",
+ kNumKeyNames, GetKeyMapName, &gbo_EKTMap, &olv_EKTMap);
+}
+
+LOCALFUNC int dfo_EKTMap(void)
+{
+ blnr a[kNumKeyNames];
+ uimr i;
+ uimr j;
+
+ for (i = 0; i < kNumKeyNames; ++i) {
+ a[i] = falseblnr;
+ }
+
+ for (i = 0; i < kNumSrcKeyNames; ++i) {
+ j = gbo_keymap[i];
+ if (j < kNumKeyNames) {
+ a[j] = trueblnr;
+ }
+ }
+
+ for (i = 0; i < kNumKeyNames; ++i) {
+ if (! a[i]) {
+ return i;
+ }
+ }
+
+ return gbk_keynam_Control;
+}
+
+LOCALFUNC tMyErr ChooseEKTMap(void)
+{
+ if (kListOptionAuto == gbo_EKTMap) {
+ gbo_EKTMap = dfo_EKTMap();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptEKTMap(void)
+{
+ WrtOptNamedOption("-ekt", GetKeyMapName, gbo_EKTMap, dfo_EKTMap());
+}
+
+
+/* option: Alternate Keyboard Mode */
+
+LOCALVAR blnr WantAltKeysMode;
+LOCALVAR ui3r olv_WantAltKeysMode;
+
+LOCALPROC ResetAltKeysMode(void)
+{
+ WantAltKeysMode = falseblnr;
+ olv_WantAltKeysMode = 0;
+}
+
+LOCALFUNC tMyErr TryAsAltKeysModeNot(void)
+{
+ return FlagTryAsOptionNot("-akm",
+ &WantAltKeysMode, &olv_WantAltKeysMode);
+}
+
+LOCALFUNC tMyErr ChooseAltKeysMode(void)
+{
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptAltKeysMode(void)
+{
+ WrtOptFlagOption("-akm", WantAltKeysMode);
+}
+
+
+/* option: ItnlKyBdFix */
+
+LOCALVAR blnr ItnlKyBdFix;
+LOCALVAR ui3r olv_ItnlKyBdFix;
+
+LOCALPROC ResetItnlKyBdFixOption(void)
+{
+ ItnlKyBdFix = nanblnr;
+}
+
+LOCALFUNC tMyErr TryAsItnlKyBdFixNot(void)
+{
+ return BooleanTryAsOptionNot("-ikb",
+ &ItnlKyBdFix, &olv_ItnlKyBdFix);
+}
+
+LOCALFUNC blnr dfo_ItnlKyBdFix(void)
+{
+ blnr v;
+
+ v = (gbk_apifam_win == gbo_apifam);
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseItnlKyBdFix(void)
+{
+ tMyErr err = kMyErr_noErr;
+
+ if (nanblnr == ItnlKyBdFix) {
+ ItnlKyBdFix = dfo_ItnlKyBdFix();
+ } else {
+ if (ItnlKyBdFix) {
+ if (gbk_apifam_win != gbo_apifam) {
+ err = ReportParseFailure("-ikb is only for Windows");
+ }
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptItnlKyBdFix(void)
+{
+ WrtOptBooleanOption("-ikb", ItnlKyBdFix, dfo_ItnlKyBdFix());
+}
+
+
+/* option: LocalTalk emulation */
+
+LOCALVAR blnr WantLocalTalk;
+LOCALVAR ui3r olv_LocalTalk;
+
+LOCALPROC ResetLocalTalk(void)
+{
+ WantLocalTalk = falseblnr;
+ olv_LocalTalk = 0;
+}
+
+LOCALFUNC tMyErr TryAsLocalTalkNot(void)
+{
+ return FlagTryAsOptionNot("-lt", &WantLocalTalk, &olv_LocalTalk);
+}
+
+LOCALFUNC tMyErr ChooseLocalTalk(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+
+ if (WantLocalTalk) {
+ if ((gbk_apifam_osx != gbo_apifam)
+ && (gbk_apifam_cco != gbo_apifam))
+ {
+ err = ReportParseFailure(
+ "-lt is so far only implemented for OS X");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptLocalTalk(void)
+{
+ WrtOptFlagOption("-lt", WantLocalTalk);
+}
+
+
+/* option: initial speed */
+
+enum {
+ gbk_speed_AllOut,
+ gbk_speed_1X,
+ gbk_speed_2X,
+ gbk_speed_4X,
+ gbk_speed_8X,
+ gbk_speed_16X,
+ gbk_speed_32X,
+ kNumSpeeds
+};
+
+LOCALVAR int CurInitSpeed;
+LOCALVAR ui3r olv_InitSpeed;
+
+LOCALPROC ResetInitSpeedOption(void)
+{
+ CurInitSpeed = kListOptionAuto;
+ olv_InitSpeed = 0;
+}
+
+LOCALFUNC char * GetInitSpeedName(int i)
+{
+ char *s;
+
+ switch (i) {
+ case gbk_speed_AllOut:
+ s = "a";
+ break;
+ case gbk_speed_1X:
+ s = "z";
+ break;
+ case gbk_speed_2X:
+ s = "1";
+ break;
+ case gbk_speed_4X:
+ s = "2";
+ break;
+ case gbk_speed_8X:
+ s = "3";
+ break;
+ case gbk_speed_16X:
+ s = "4";
+ break;
+ case gbk_speed_32X:
+ s = "5";
+ break;
+ default:
+ s = "(unknown Speed)";
+ break;
+ }
+ return s;
+}
+
+LOCALFUNC tMyErr TryAsInitSpeedOptionNot(void)
+{
+ return FindNamedOption("-speed",
+ kNumSpeeds, GetInitSpeedName, &CurInitSpeed, &olv_InitSpeed);
+}
+
+LOCALFUNC int dfo_InitSpeed(void)
+{
+ int v;
+
+ if (cur_mIIorIIX) {
+ v = gbk_speed_4X;
+ } else {
+ v = gbk_speed_8X;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseInitSpeed(void)
+{
+ if (kListOptionAuto == CurInitSpeed) {
+ CurInitSpeed = dfo_InitSpeed();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptInitSpeedOption(void)
+{
+ WrtOptNamedOption("-speed", GetInitSpeedName,
+ CurInitSpeed, dfo_InitSpeed());
+}
+
+
+/* option: Initial Run In Background */
+
+LOCALVAR blnr WantInitBackground;
+LOCALVAR ui3r olv_InitBackground;
+
+LOCALPROC ResetInitBackground(void)
+{
+ WantInitBackground = nanblnr;
+ olv_InitBackground = 0;
+}
+
+LOCALFUNC tMyErr TryAsInitBackgroundNot(void)
+{
+ return BooleanTryAsOptionNot("-bg",
+ &WantInitBackground, &olv_InitBackground);
+}
+
+LOCALFUNC blnr dfo_InitBackground(void)
+{
+ blnr v;
+
+ if (WantLocalTalk) {
+ v = trueblnr;
+ } else {
+ v = falseblnr;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseInitBackground(void)
+{
+ if (nanblnr == WantInitBackground) {
+ WantInitBackground = dfo_InitBackground();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptInitBackground(void)
+{
+ WrtOptBooleanOption("-bg", WantInitBackground,
+ dfo_InitBackground());
+}
+
+
+/* option: Initial AutoSlow */
+
+LOCALVAR blnr WantInitAutoSlow;
+LOCALVAR ui3r olv_InitAutoSlow;
+
+LOCALPROC ResetInitAutoSlow(void)
+{
+ WantInitAutoSlow = nanblnr;
+ olv_InitAutoSlow = 0;
+}
+
+LOCALFUNC tMyErr TryAsInitAutoSlowNot(void)
+{
+ return BooleanTryAsOptionNot("-as",
+ &WantInitAutoSlow, &olv_InitAutoSlow);
+}
+
+LOCALFUNC blnr dfo_InitAutoSlow(void)
+{
+ blnr v;
+
+ v = ! cur_mIIorIIX;
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseInitAutoSlow(void)
+{
+ if (nanblnr == WantInitAutoSlow) {
+ WantInitAutoSlow = dfo_InitAutoSlow();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptInitAutoSlow(void)
+{
+ WrtOptBooleanOption("-as", WantInitAutoSlow, dfo_InitAutoSlow());
+}
+
+
+/* option: Timing Accuracy */
+
+LOCALVAR uimr timingacc;
+LOCALVAR ui3r olv_timingacc;
+
+LOCALPROC ResetTimingAccuracyOption(void)
+{
+ olv_timingacc = 0;
+}
+
+LOCALFUNC tMyErr TryAsTimingAccuracyOptionNot(void)
+{
+ return NumberTryAsOptionNot("-ta",
+ (long *)&timingacc, &olv_timingacc);
+}
+
+#define dfo_timingacc() 1
+
+LOCALFUNC tMyErr ChooseTimingAccuracy(void)
+{
+ if (0 == olv_timingacc) {
+ timingacc = dfo_timingacc();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptTimingAccuracy(void)
+{
+ WrtOptNumberOption("-ta", timingacc, dfo_timingacc());
+}
+
+
+/* option: Emulated CPU version */
+
+LOCALVAR uimr em_cpu_vers;
+LOCALVAR ui3r olv_em_cpu_vers;
+
+LOCALPROC ResetEmCpuVersOption(void)
+{
+ olv_em_cpu_vers = 0;
+}
+
+LOCALFUNC tMyErr TryAsEmCpuVersOptionNot(void)
+{
+ return NumberTryAsOptionNot("-em-cpu",
+ (long *)&em_cpu_vers, &olv_em_cpu_vers);
+}
+
+LOCALFUNC uimr dfo_em_cpu_vers(void)
+{
+ uimr v;
+
+ if (cur_mIIorIIX) {
+ v = 2;
+ } else {
+ v = 0;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseEmCpuVers(void)
+{
+ if (0 == olv_em_cpu_vers) {
+ em_cpu_vers = dfo_em_cpu_vers();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptEmCpuVers(void)
+{
+ WrtOptNumberOption("-em-cpu", em_cpu_vers, dfo_em_cpu_vers());
+}
+
+
+/* option: memory size */
+
+enum {
+ gbk_msz_128K,
+ gbk_msz_512K,
+ gbk_msz_1M,
+ gbk_msz_2M,
+ gbk_msz_2_5M,
+ gbk_msz_4M,
+ gbk_msz_5M,
+ gbk_msz_8M,
+ kNumMemSizs
+};
+
+LOCALVAR int cur_msz;
+LOCALVAR ui3r olv_msz;
+
+LOCALPROC ResetMemSizOption(void)
+{
+ cur_msz = kListOptionAuto;
+ olv_msz = 0;
+}
+
+LOCALFUNC char * GetMemSizName(int i)
+{
+ char *s;
+
+ switch (i) {
+ case gbk_msz_128K:
+ s = "128K";
+ break;
+ case gbk_msz_512K:
+ s = "512K";
+ break;
+ case gbk_msz_1M:
+ s = "1M";
+ break;
+ case gbk_msz_2M:
+ s = "2M";
+ break;
+ case gbk_msz_2_5M:
+ s = "2.5M";
+ break;
+ case gbk_msz_4M:
+ s = "4M";
+ break;
+ case gbk_msz_5M:
+ s = "5M";
+ break;
+ case gbk_msz_8M:
+ s = "8M";
+ break;
+ default:
+ s = "(unknown Memory Size)";
+ break;
+ }
+ return s;
+}
+
+LOCALFUNC tMyErr TryAsMemSizOptionNot(void)
+{
+ return FindNamedOption("-mem",
+ kNumMemSizs, GetMemSizName, &cur_msz, &olv_msz);
+}
+
+LOCALFUNC int dfo_msz(void)
+{
+ int v;
+
+ switch (cur_mdl) {
+ case gbk_mdl_Twig43:
+ case gbk_mdl_Twiggy:
+ case gbk_mdl_128K:
+ v = gbk_msz_128K;
+ break;
+ case gbk_mdl_512Ke:
+ v = gbk_msz_512K;
+ break;
+ case gbk_mdl_II:
+ case gbk_mdl_IIx:
+ v = gbk_msz_8M;
+ break;
+ case gbk_mdl_Plus:
+ case gbk_mdl_SE:
+ case gbk_mdl_SEFDHD:
+ case gbk_mdl_Classic:
+ case gbk_mdl_PB100:
+ default:
+ v = gbk_msz_4M;
+ break;
+ }
+ if (gbk_targfam_lnds == gbo_targfam) {
+ if (v > gbk_msz_2M) {
+ v = gbk_msz_2M;
+ }
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseMemSiz(void)
+{
+ if (kListOptionAuto == cur_msz) {
+ cur_msz = dfo_msz();
+ } else {
+ /* should error check here */
+ /* no, checked in ChooseMemBankSizes */
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptMemSizOption(void)
+{
+ WrtOptNamedOption("-mem", GetMemSizName, cur_msz, dfo_msz());
+}
+
+/* memory bank sizes */
+
+LOCALVAR uimr RAMa_Size;
+LOCALVAR uimr RAMb_Size;
+
+#define ln2_msz_64K 16
+#define ln2_msz_128K 17
+#define ln2_msz_256K 18
+#define ln2_msz_512K 19
+#define ln2_msz_1M 20
+#define ln2_msz_2M 21
+#define ln2_msz_4M 22
+#define ln2_msz_8M 23
+
+LOCALFUNC tMyErr ChooseMemBankSizes(void)
+{
+ tMyErr err;
+ RAMa_Size = 0;
+ RAMb_Size = 0;
+
+ switch (cur_mdl) {
+ case gbk_mdl_Twig43:
+ case gbk_mdl_Twiggy:
+ case gbk_mdl_128K:
+ case gbk_mdl_512Ke:
+ if (cur_msz == gbk_msz_128K) {
+ RAMa_Size = ln2_msz_128K;
+ } else
+ if (cur_msz == gbk_msz_512K) {
+ RAMa_Size = ln2_msz_512K;
+ } else
+ {
+ /* unsupported */
+ }
+ break;
+ case gbk_mdl_Plus:
+ case gbk_mdl_SE:
+ case gbk_mdl_SEFDHD:
+ case gbk_mdl_Classic:
+ if (cur_msz == gbk_msz_128K) {
+ if (gbk_mdl_Plus == cur_mdl) {
+ RAMa_Size = ln2_msz_128K;
+ }
+ } else
+ if (cur_msz == gbk_msz_512K) {
+ RAMa_Size = ln2_msz_512K;
+ } else
+ if (cur_msz == gbk_msz_1M) {
+ RAMa_Size = ln2_msz_512K;
+ RAMb_Size = ln2_msz_512K;
+ } else
+ if (cur_msz == gbk_msz_2M) {
+ RAMa_Size = ln2_msz_2M;
+ } else
+ if (cur_msz == gbk_msz_2_5M) {
+ RAMa_Size = ln2_msz_2M;
+ RAMb_Size = ln2_msz_512K;
+ } else
+ if (cur_msz == gbk_msz_4M) {
+ RAMa_Size = ln2_msz_2M;
+ RAMb_Size = ln2_msz_2M;
+ } else
+ {
+ /* unsupported */
+ }
+ break;
+ case gbk_mdl_II:
+ case gbk_mdl_IIx:
+ if (cur_msz == gbk_msz_1M) {
+ RAMa_Size = ln2_msz_1M;
+ } else
+ if (cur_msz == gbk_msz_2M) {
+ RAMa_Size = ln2_msz_1M;
+ RAMb_Size = ln2_msz_1M;
+ } else
+ if (cur_msz == gbk_msz_4M) {
+ RAMa_Size = ln2_msz_4M;
+ } else
+ if (cur_msz == gbk_msz_5M) {
+ RAMa_Size = ln2_msz_4M;
+ RAMb_Size = ln2_msz_1M;
+ } else
+ if (cur_msz == gbk_msz_8M) {
+ RAMa_Size = ln2_msz_4M;
+ RAMb_Size = ln2_msz_4M;
+ } else
+ {
+ /* unsupported */
+ }
+ break;
+ case gbk_mdl_PB100:
+ if (cur_msz == gbk_msz_4M) {
+ RAMa_Size = ln2_msz_4M;
+ } else
+ {
+ /* unsupported */
+ }
+ default:
+ /* unsupported */
+ break;
+ }
+
+ if (0 == RAMa_Size) {
+ err = ReportParseFailure(
+ "memory size (-mem) unsupported for this model (-m)");
+ } else {
+ err = kMyErr_noErr;
+ }
+
+ return err;
+}
+
+
+/* option: Parameter RAM CaretBlinkTime */
+ /* usually in 3 (Fast), 8 (Medium), 15 (Slow) */
+
+LOCALVAR uimr cur_CaretBlinkTime;
+LOCALVAR ui3r olv_CaretBlinkTime;
+
+LOCALPROC ResetCaretBlinkTimeOption(void)
+{
+ olv_CaretBlinkTime = 0;
+}
+
+LOCALFUNC tMyErr TryAsCaretBlinkTimeOptionNot(void)
+{
+ return NumberTryAsOptionNot("-cbt",
+ (long *)&cur_CaretBlinkTime, &olv_CaretBlinkTime);
+}
+
+LOCALFUNC uimr dfo_CaretBlinkTime(void)
+{
+ uimr v;
+
+ if (cur_mIIorIIX) {
+ v = 8;
+ } else {
+ v = 3;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseCaretBlinkTime(void)
+{
+ tMyErr err;
+
+
+ err = kMyErr_noErr;
+ if (0 == olv_CaretBlinkTime) {
+ cur_CaretBlinkTime = dfo_CaretBlinkTime();
+ } else {
+ if ((cur_CaretBlinkTime <= 0) || (cur_CaretBlinkTime > 15)) {
+ err = ReportParseFailure(
+ "-cbt must be a number between 1 and 15");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptCaretBlinkTime(void)
+{
+ WrtOptNumberOption("-cbt",
+ cur_CaretBlinkTime, dfo_CaretBlinkTime());
+}
+
+
+/* option: Parameter RAM DoubleClickTime */
+ /* usually in 5 (Fast), 8 (Medium), 12 (Slow) */
+
+LOCALVAR uimr cur_DoubleClickTime;
+LOCALVAR ui3r olv_DoubleClickTime;
+
+LOCALPROC ResetDoubleClickTimeOption(void)
+{
+ olv_DoubleClickTime = 0;
+}
+
+LOCALFUNC tMyErr TryAsDoubleClickTimeOptionNot(void)
+{
+ return NumberTryAsOptionNot("-dct",
+ (long *)&cur_DoubleClickTime, &olv_DoubleClickTime);
+}
+
+LOCALFUNC uimr dfo_DoubleClickTime(void)
+{
+ uimr v;
+
+ if (cur_mIIorIIX) {
+ v = 8;
+ } else {
+ v = 5;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseDoubleClickTime(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+
+
+ if (0 == olv_DoubleClickTime) {
+ cur_DoubleClickTime = dfo_DoubleClickTime();
+ } else {
+ if ((cur_DoubleClickTime <= 0) || (cur_DoubleClickTime > 15)) {
+ err = ReportParseFailure(
+ "-dct must be a number between 1 and 15");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptDoubleClickTime(void)
+{
+ WrtOptNumberOption("-dct",
+ cur_DoubleClickTime, dfo_DoubleClickTime());
+}
+
+
+/* option: Parameter RAM MenuBlink */
+ /* in 0..3 */
+
+LOCALVAR uimr cur_MenuBlink;
+LOCALVAR ui3r olv_MenuBlink;
+
+LOCALPROC ResetMenuBlinkOption(void)
+{
+ olv_MenuBlink = 0;
+}
+
+LOCALFUNC tMyErr TryAsMenuBlinkOptionNot(void)
+{
+ return NumberTryAsOptionNot("-mnb",
+ (long *)&cur_MenuBlink, &olv_MenuBlink);
+}
+
+#define dfo_MenuBlink() 3
+
+LOCALFUNC tMyErr ChooseMenuBlink(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (0 == olv_MenuBlink) {
+ cur_MenuBlink = dfo_MenuBlink();
+ } else {
+ if (cur_MenuBlink > 3) {
+ err = ReportParseFailure(
+ "-mnb must be a number between 0 and 3");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptMenuBlink(void)
+{
+ WrtOptNumberOption("-mnb", cur_MenuBlink, dfo_MenuBlink());
+}
+
+
+/* option: Parameter RAM AutoKeyThresh */
+ /* usually in 0 (Off), A (Long), 6, 4, 3 (Short) */
+
+LOCALVAR uimr cur_AutoKeyThresh;
+LOCALVAR ui3r olv_AutoKeyThresh;
+
+LOCALPROC ResetAutoKeyThreshOption(void)
+{
+ olv_AutoKeyThresh = 0;
+}
+
+LOCALFUNC tMyErr TryAsAutoKeyThreshOptionNot(void)
+{
+ return NumberTryAsOptionNot("-kyt",
+ (long *)&cur_AutoKeyThresh, &olv_AutoKeyThresh);
+}
+
+#define dfo_AutoKeyThresh() 6
+
+LOCALFUNC tMyErr ChooseAutoKeyThresh(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (0 == olv_AutoKeyThresh) {
+ cur_AutoKeyThresh = dfo_AutoKeyThresh();
+ } else {
+ if (cur_AutoKeyThresh > 15) {
+ err = ReportParseFailure(
+ "-kyt must be a number between 0 and 15");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptAutoKeyThresh(void)
+{
+ WrtOptNumberOption("-kyt", cur_AutoKeyThresh, dfo_AutoKeyThresh());
+}
+
+
+/* option: Parameter RAM AutoKeyRate */
+ /* usually in 0 (Slow), 6, 4, 3, 1 (Fast) */
+
+LOCALVAR uimr cur_AutoKeyRate;
+LOCALVAR ui3r olv_AutoKeyRate;
+
+LOCALPROC ResetAutoKeyRateOption(void)
+{
+ olv_AutoKeyRate = 0;
+}
+
+LOCALFUNC tMyErr TryAsAutoKeyRateOptionNot(void)
+{
+ return NumberTryAsOptionNot("-kyr",
+ (long *)&cur_AutoKeyRate, &olv_AutoKeyRate);
+}
+
+#define dfo_AutoKeyRate() 3
+
+LOCALFUNC tMyErr ChooseAutoKeyRate(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (0 == olv_AutoKeyRate) {
+ cur_AutoKeyRate = dfo_AutoKeyRate();
+ } else {
+ if (cur_AutoKeyRate > 15) {
+ err = ReportParseFailure(
+ "-kyr must be a number between 0 and 15");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptAutoKeyRate(void)
+{
+ WrtOptNumberOption("-kyr", cur_AutoKeyRate, dfo_AutoKeyRate());
+}
+
+
+LOCALFUNC tMyErr ChooseHilColPart(char *s, uimr *cur_HilColV,
+ ui3r olv_HilColV, uimr dfo_HilColV)
+{
+ tMyErr err;
+ MyPStr t;
+
+ err = kMyErr_noErr;
+ if (0 == olv_HilColV) {
+ *cur_HilColV = dfo_HilColV;
+ } else {
+ if (! cur_mIIorIIX) {
+ if (0 != *cur_HilColV) {
+ PStrFromCStr(t, s);
+ PStrApndCStr(t,
+ " not allowed for this emulated computer");
+ err = ReportParseFailPStr(t);
+ }
+ } else
+ if (*cur_HilColV > 65535) {
+ PStrFromCStr(t, s);
+ PStrApndCStr(t, " must be a number between 0 and 65535");
+ err = ReportParseFailPStr(t);
+ }
+ }
+
+ return err;
+}
+
+/* option: Parameter RAM HilColRed */
+
+LOCALVAR uimr cur_HilColRed;
+LOCALVAR ui3r olv_HilColRed;
+
+LOCALPROC ResetHilColRedOption(void)
+{
+ olv_HilColRed = 0;
+}
+
+LOCALFUNC tMyErr TryAsHilColRedOptionNot(void)
+{
+ return NumberTryAsOptionNot("-hcr",
+ (long *)&cur_HilColRed, &olv_HilColRed);
+}
+
+#define dfo_HilColRed() 0
+
+LOCALFUNC tMyErr ChooseHilColRed(void)
+{
+ return ChooseHilColPart("-hcr", &cur_HilColRed, olv_HilColRed,
+ dfo_HilColRed());
+}
+
+LOCALPROC WrtOptHilColRed(void)
+{
+ WrtOptNumberOption("-hcr", cur_HilColRed, dfo_HilColRed());
+}
+
+
+/* option: Parameter RAM HilColGreen */
+
+LOCALVAR uimr cur_HilColGreen;
+LOCALVAR ui3r olv_HilColGreen;
+
+LOCALPROC ResetHilColGreenOption(void)
+{
+ olv_HilColGreen = 0;
+}
+
+LOCALFUNC tMyErr TryAsHilColGreenOptionNot(void)
+{
+ return NumberTryAsOptionNot("-hcg",
+ (long *)&cur_HilColGreen, &olv_HilColGreen);
+}
+
+#define dfo_HilColGreen() 0
+
+LOCALFUNC tMyErr ChooseHilColGreen(void)
+{
+ return ChooseHilColPart("-hcg", &cur_HilColGreen, olv_HilColGreen,
+ dfo_HilColGreen());
+}
+
+LOCALPROC WrtOptHilColGreen(void)
+{
+ WrtOptNumberOption("-hcg", cur_HilColGreen, dfo_HilColGreen());
+}
+
+
+/* option: Parameter RAM HilColBlue */
+
+LOCALVAR uimr cur_HilColBlue;
+LOCALVAR ui3r olv_HilColBlue;
+
+LOCALPROC ResetHilColBlueOption(void)
+{
+ olv_HilColBlue = 0;
+}
+
+LOCALFUNC tMyErr TryAsHilColBlueOptionNot(void)
+{
+ return NumberTryAsOptionNot("-hcb",
+ (long *)&cur_HilColBlue, &olv_HilColBlue);
+}
+
+#define dfo_HilColBlue() 0
+
+LOCALFUNC tMyErr ChooseHilColBlue(void)
+{
+ return ChooseHilColPart("-hcb", &cur_HilColBlue, olv_HilColBlue,
+ dfo_HilColBlue());
+}
+
+LOCALPROC WrtOptHilColBlue(void)
+{
+ WrtOptNumberOption("-hcb", cur_HilColBlue, dfo_HilColBlue());
+}
+
+
+/* option: Automatic Location */
+
+LOCALVAR blnr WantAutoLocation;
+LOCALVAR ui3r olv_AutoLocation;
+
+LOCALPROC ResetAutoLocation(void)
+{
+ WantAutoLocation = nanblnr;
+ olv_AutoLocation = 0;
+}
+
+LOCALFUNC tMyErr TryAsAutoLocationNot(void)
+{
+ return BooleanTryAsOptionNot("-alc",
+ &WantAutoLocation, &olv_AutoLocation);
+}
+
+#define dfo_AutoLocation() trueblnr
+
+LOCALFUNC tMyErr ChooseAutoLocation(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (nanblnr == WantAutoLocation) {
+ WantAutoLocation = dfo_AutoLocation();
+ } else {
+ if (cur_mdl < gbk_mdl_Plus) {
+ err = ReportParseFailure(
+ "-alc not supported for this model (-m)");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptAutoLocation(void)
+{
+ WrtOptBooleanOption("-alc", WantAutoLocation, dfo_AutoLocation());
+}
+
+
+/* option: Location Latitude */
+
+LOCALVAR uimr cur_InitLatitude;
+LOCALVAR ui3r olv_InitLatitude;
+
+LOCALPROC ResetInitLatitudeOption(void)
+{
+ olv_InitLatitude = 0;
+}
+
+LOCALFUNC tMyErr TryAsInitLatitudeOptionNot(void)
+{
+ return NumberTryAsOptionNot("-lcy",
+ (long *)&cur_InitLatitude, &olv_InitLatitude);
+}
+
+#define dfo_InitLatitude() 0
+
+LOCALFUNC tMyErr ChooseInitLatitude(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (0 == olv_InitLatitude) {
+ cur_InitLatitude = dfo_InitLatitude();
+ } else {
+ if (cur_mdl < gbk_mdl_Plus) {
+ err = ReportParseFailure(
+ "-lcy not supported for this model (-m)");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptInitLatitude(void)
+{
+ if (! WantAutoLocation) {
+ WrtOptSimrOption("-lcy", cur_InitLatitude, dfo_InitLatitude());
+ }
+}
+
+
+/* option: Location Longitude */
+
+LOCALVAR simr cur_InitLongitude;
+LOCALVAR ui3r olv_InitLongitude;
+
+LOCALPROC ResetInitLongitudeOption(void)
+{
+ olv_InitLongitude = 0;
+}
+
+LOCALFUNC tMyErr TryAsInitLongitudeOptionNot(void)
+{
+ return NumberTryAsOptionNot("-lcx",
+ &cur_InitLongitude, &olv_InitLongitude);
+}
+
+#define dfo_InitLongitude() 0
+
+LOCALFUNC tMyErr ChooseInitLongitude(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (0 == olv_InitLongitude) {
+ cur_InitLongitude = dfo_InitLongitude();
+ } else {
+ if (cur_mdl < gbk_mdl_Plus) {
+ err = ReportParseFailure(
+ "-lcx not supported for this model (-m)");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptInitLongitude(void)
+{
+ if (! WantAutoLocation) {
+ WrtOptSimrOption("-lcx", cur_InitLongitude,
+ dfo_InitLongitude());
+ }
+}
+
+
+/* option: Automatic Time Zone */
+
+LOCALVAR blnr WantAutoTimeZone;
+LOCALVAR ui3r olv_AutoTimeZone;
+
+LOCALPROC ResetAutoTimeZone(void)
+{
+ WantAutoTimeZone = nanblnr;
+ olv_AutoTimeZone = 0;
+}
+
+LOCALFUNC tMyErr TryAsAutoTimeZoneNot(void)
+{
+ return BooleanTryAsOptionNot("-atz",
+ &WantAutoTimeZone, &olv_AutoTimeZone);
+}
+
+#define dfo_AutoTimeZone() trueblnr
+
+LOCALFUNC tMyErr ChooseAutoTimeZone(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (nanblnr == WantAutoTimeZone) {
+ WantAutoTimeZone = dfo_AutoTimeZone();
+ } else {
+ if (cur_mdl < gbk_mdl_Plus) {
+ err = ReportParseFailure(
+ "-atz not supported for this model (-m)");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptAutoTimeZone(void)
+{
+ WrtOptBooleanOption("-atz", WantAutoTimeZone, dfo_AutoTimeZone());
+}
+
+
+/* option: Daylight Savings Time */
+
+LOCALVAR blnr WantTzDST;
+LOCALVAR ui3r olv_TzDST;
+
+LOCALPROC ResetTzDST(void)
+{
+ WantTzDST = nanblnr;
+ olv_TzDST = 0;
+}
+
+LOCALFUNC tMyErr TryAsTzDSTNot(void)
+{
+ return BooleanTryAsOptionNot("-lcd",
+ &WantTzDST, &olv_TzDST);
+}
+
+#define dfo_TzDST() falseblnr
+
+LOCALFUNC tMyErr ChooseTzDST(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (nanblnr == WantTzDST) {
+ WantTzDST = dfo_TzDST();
+ } else {
+ if (cur_mdl < gbk_mdl_Plus) {
+ err = ReportParseFailure(
+ "-lcd not supported for this model (-m)");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptTzDST(void)
+{
+ if (! WantAutoTimeZone) {
+ WrtOptBooleanOption("-lcd", WantTzDST, dfo_TzDST());
+ }
+}
+
+
+/* option: Time Zone Delta Hours */
+
+LOCALVAR simr cur_TzDeltH;
+LOCALVAR ui3r olv_TzDeltH;
+
+LOCALPROC ResetTzDeltHOption(void)
+{
+ olv_TzDeltH = 0;
+}
+
+LOCALFUNC tMyErr TryAsTzDeltHOptionNot(void)
+{
+ return NumberTryAsOptionNot("-lcz",
+ &cur_TzDeltH, &olv_TzDeltH);
+}
+
+
+/* option: Time Zone Delta Seconds */
+
+LOCALVAR simr cur_TzDeltS;
+LOCALVAR ui3r olv_TzDeltS;
+
+LOCALPROC ResetTzDeltSOption(void)
+{
+ olv_TzDeltS = 0;
+}
+
+LOCALFUNC tMyErr TryAsTzDeltSOptionNot(void)
+{
+ return NumberTryAsOptionNot("-lczs",
+ &cur_TzDeltS, &olv_TzDeltS);
+}
+
+#define dfo_TzDeltS() 0
+
+LOCALFUNC tMyErr ChooseTzDeltS(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (cur_mdl < gbk_mdl_Plus) {
+ if ((0 != olv_TzDeltS) || (0 != olv_TzDeltH)) {
+ err = ReportParseFailure(
+ "-lczs and -lcz are not supported for this model (-m)");
+ }
+ } else if (0 == olv_TzDeltS) {
+ if (0 == olv_TzDeltH) {
+ cur_TzDeltS = dfo_TzDeltS();
+ } else {
+ cur_TzDeltS = cur_TzDeltH * 3600;
+ }
+ } else {
+ if (0 != olv_TzDeltH) {
+ err = ReportParseFailure(
+ "-lczs and -lcz can not both be used");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptTzDeltS(void)
+{
+ if (! WantAutoTimeZone) {
+ simr t = cur_TzDeltS / 3600;
+
+ if (t * 3600 == cur_TzDeltS) {
+ WrtOptSimrOption("-lcz", t, 0);
+ } else {
+ WrtOptSimrOption("-lczs", cur_TzDeltS, dfo_TzDeltS());
+ }
+ }
+}
+
+
+/* option: Speaker Volume */
+ /* usually in 3 (Fast), 8 (Medium), 15 (Slow) */
+
+LOCALVAR uimr cur_SpeakerVol;
+LOCALVAR ui3r olv_SpeakerVol;
+
+LOCALPROC ResetSpeakerVolOption(void)
+{
+ olv_SpeakerVol = 0;
+}
+
+LOCALFUNC tMyErr TryAsSpeakerVolOptionNot(void)
+{
+ return NumberTryAsOptionNot("-svl",
+ (long *)&cur_SpeakerVol, &olv_SpeakerVol);
+}
+
+LOCALFUNC uimr dfo_SpeakerVol(void)
+{
+ uimr v;
+
+ if (MySoundEnabled) {
+ v = 7;
+ } else {
+ v = 0;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseSpeakerVol(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+
+
+ if (0 == olv_SpeakerVol) {
+ cur_SpeakerVol = dfo_SpeakerVol();
+ } else {
+ if (cur_SpeakerVol >= 8) {
+ err = ReportParseFailure(
+ "-svl must be a number between 0 and 7");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptSpeakerVol(void)
+{
+ WrtOptNumberOption("-svl", cur_SpeakerVol, dfo_SpeakerVol());
+}
+
+
+/* option: Minimum Extension */
+
+LOCALVAR blnr WantMinExtn;
+LOCALVAR ui3r olv_WantMinExtn;
+
+LOCALPROC ResetWantMinExtn(void)
+{
+ WantMinExtn = falseblnr;
+ olv_WantMinExtn = 0;
+}
+
+LOCALFUNC tMyErr TryAsWantMinExtnNot(void)
+{
+ return FlagTryAsOptionNot("-min-extn",
+ &WantMinExtn, &olv_WantMinExtn);
+}
+
+LOCALFUNC tMyErr ChooseWantMinExtn(void)
+{
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptMinExtn(void)
+{
+ WrtOptFlagOption("-min-extn", WantMinExtn);
+}
+
+
+/* option: MouseMotion */
+
+LOCALVAR blnr MyMouseMotion;
+LOCALVAR ui3r olv_MouseMotion;
+
+LOCALPROC ResetMouseMotionOption(void)
+{
+ MyMouseMotion = nanblnr;
+ olv_MouseMotion = 0;
+}
+
+LOCALFUNC tMyErr TryAsMouseMotionOptionNot(void)
+{
+ return BooleanTryAsOptionNot("-emm",
+ &MyMouseMotion, &olv_MouseMotion);
+}
+
+LOCALFUNC blnr dfo_MouseMotion(void)
+{
+ blnr v;
+
+ v = (gbk_apifam_gtk != gbo_apifam);
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseMouseMotion(void)
+{
+
+ if (nanblnr == MyMouseMotion) {
+ MyMouseMotion = dfo_MouseMotion();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptMouseMotion(void)
+{
+ WrtOptBooleanOption("-emm", MyMouseMotion, dfo_MouseMotion());
+}
+
+
+/* option: GrabKeysFullScreen */
+
+LOCALVAR blnr WantGrabKeysFS;
+LOCALVAR ui3r olv_GrabKeysFS;
+
+LOCALPROC ResetGrabKeysFS(void)
+{
+ WantGrabKeysFS = nanblnr;
+ olv_GrabKeysFS = 0;
+}
+
+LOCALFUNC tMyErr TryAsGrabKeysFSNot(void)
+{
+ return BooleanTryAsOptionNot("-gkf",
+ &WantGrabKeysFS, &olv_GrabKeysFS);
+}
+
+#define dfo_GrabKeysFS() trueblnr
+
+LOCALFUNC tMyErr ChooseGrabKeysFS(void)
+{
+ if (nanblnr == WantGrabKeysFS) {
+ WantGrabKeysFS = dfo_GrabKeysFS();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptGrabKeysFS(void)
+{
+ WrtOptBooleanOption("-gkf", WantGrabKeysFS, dfo_GrabKeysFS());
+}
+
+
+/* option: Enable Control Interrupt */
+
+LOCALVAR blnr WantEnblCtrlInt;
+LOCALVAR ui3r olv_EnblCtrlInt;
+
+LOCALPROC ResetEnblCtrlInt(void)
+{
+ WantEnblCtrlInt = nanblnr;
+ olv_EnblCtrlInt = 0;
+}
+
+LOCALFUNC tMyErr TryAsEnblCtrlIntNot(void)
+{
+ return BooleanTryAsOptionNot("-eci",
+ &WantEnblCtrlInt, &olv_EnblCtrlInt);
+}
+
+#define dfo_EnblCtrlInt() trueblnr
+
+LOCALFUNC tMyErr ChooseEnblCtrlInt(void)
+{
+ if (nanblnr == WantEnblCtrlInt) {
+ WantEnblCtrlInt = dfo_EnblCtrlInt();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptEnblCtrlInt(void)
+{
+ WrtOptBooleanOption("-eci", WantEnblCtrlInt, dfo_EnblCtrlInt());
+}
+
+
+/* option: Enable Control Reset */
+
+LOCALVAR blnr WantEnblCtrlRst;
+LOCALVAR ui3r olv_EnblCtrlRst;
+
+LOCALPROC ResetEnblCtrlRst(void)
+{
+ WantEnblCtrlRst = nanblnr;
+ olv_EnblCtrlRst = 0;
+}
+
+LOCALFUNC tMyErr TryAsEnblCtrlRstNot(void)
+{
+ return BooleanTryAsOptionNot("-ecr",
+ &WantEnblCtrlRst, &olv_EnblCtrlRst);
+}
+
+#define dfo_EnblCtrlRst() trueblnr
+
+LOCALFUNC tMyErr ChooseEnblCtrlRst(void)
+{
+ if (nanblnr == WantEnblCtrlRst) {
+ WantEnblCtrlRst = dfo_EnblCtrlRst();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptEnblCtrlRst(void)
+{
+ WrtOptBooleanOption("-ecr", WantEnblCtrlRst, dfo_EnblCtrlRst());
+}
+
+
+/* option: Enable Control K (emulated control toggle) */
+
+LOCALVAR blnr WantEnblCtrlKtg;
+LOCALVAR ui3r olv_EnblCtrlKtg;
+
+LOCALPROC ResetEnblCtrlKtg(void)
+{
+ WantEnblCtrlKtg = nanblnr;
+ olv_EnblCtrlKtg = 0;
+}
+
+LOCALFUNC tMyErr TryAsEnblCtrlKtgNot(void)
+{
+ return BooleanTryAsOptionNot("-eck",
+ &WantEnblCtrlKtg, &olv_EnblCtrlKtg);
+}
+
+#define dfo_EnblCtrlKtg() trueblnr
+
+LOCALFUNC tMyErr ChooseEnblCtrlKtg(void)
+{
+ if (nanblnr == WantEnblCtrlKtg) {
+ WantEnblCtrlKtg = dfo_EnblCtrlKtg();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptEnblCtrlKtg(void)
+{
+ WrtOptBooleanOption("-eck", WantEnblCtrlKtg, dfo_EnblCtrlKtg());
+}
+
+
+/* option: Want Color Image */
+
+LOCALVAR blnr WantColorImage;
+LOCALVAR ui3r olv_ColorImage;
+
+LOCALPROC ResetWantColorImage(void)
+{
+ WantColorImage = nanblnr;
+ olv_ColorImage = 0;
+}
+
+LOCALFUNC tMyErr TryAsWantColorImageNot(void)
+{
+ return BooleanTryAsOptionNot("-ci",
+ &WantColorImage, &olv_ColorImage);
+}
+
+LOCALFUNC blnr dfo_ColorImage(void)
+{
+ blnr v;
+
+ if (gbk_apifam_xwn == gbo_apifam) {
+ v = trueblnr;
+ } else {
+ /* leave as default */
+ v = nanblnr;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseWantColorImage(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+
+ if (nanblnr == WantColorImage) {
+ WantColorImage = dfo_ColorImage();
+ } else {
+ if (gbk_apifam_xwn != gbo_apifam) {
+ err = ReportParseFailure(
+ "-ci is only for -api xwn");
+ } else
+ if ((! WantColorImage) && (cur_ScrnDpth != 0)) {
+ err = ReportParseFailure(
+ "-ci 0 requires -depth 0");
+ } else
+ {
+ /* ok */
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptColorImage(void)
+{
+ WrtOptBooleanOption("-ci", WantColorImage, dfo_ColorImage());
+}
+
+
+/* option: Alternate Happy Mac Icons */
+
+enum {
+ gbk_AHM_none,
+ gbk_AHM_aside,
+ gbk_AHM_cheese,
+ gbk_AHM_evil,
+ gbk_AHM_horror,
+ gbk_AHM_lady_mac,
+ gbk_AHM_moustache,
+ gbk_AHM_nerdy,
+ gbk_AHM_pirate,
+ gbk_AHM_sleepy,
+ gbk_AHM_sly,
+ gbk_AHM_sunglasses,
+ gbk_AHM_surprise,
+ gbk_AHM_tongue,
+ gbk_AHM_yuck,
+ gbk_AHM_zombie,
+
+ kNumAHMs
+};
+
+LOCALVAR int cur_AltHappyMac;
+LOCALVAR ui3r olv_AltHappyMac;
+
+LOCALPROC ResetAltHappyMacOption(void)
+{
+ cur_AltHappyMac = kListOptionAuto;
+ olv_AltHappyMac = 0;
+}
+
+LOCALFUNC char * GetAltHappyMacName(int i)
+{
+ char *s;
+
+ switch (i) {
+ case gbk_AHM_none:
+ s = "none";
+ break;
+ case gbk_AHM_aside:
+ s = "aside";
+ break;
+ case gbk_AHM_cheese:
+ s = "cheese";
+ break;
+ case gbk_AHM_evil:
+ s = "evil";
+ break;
+ case gbk_AHM_horror:
+ s = "horror";
+ break;
+ case gbk_AHM_lady_mac:
+ s = "lady_mac";
+ break;
+ case gbk_AHM_moustache:
+ s = "moustache";
+ break;
+ case gbk_AHM_nerdy:
+ s = "nerdy";
+ break;
+ case gbk_AHM_pirate:
+ s = "pirate";
+ break;
+ case gbk_AHM_sleepy:
+ s = "sleepy";
+ break;
+ case gbk_AHM_sly:
+ s = "sly";
+ break;
+ case gbk_AHM_sunglasses:
+ s = "sunglasses";
+ break;
+ case gbk_AHM_surprise:
+ s = "surprise";
+ break;
+ case gbk_AHM_tongue:
+ s = "tongue";
+ break;
+ case gbk_AHM_yuck:
+ s = "yuck";
+ break;
+ case gbk_AHM_zombie:
+ s = "zombie";
+ break;
+
+ default:
+ s = "(unknown Alt Happy Mac Icon)";
+ break;
+ }
+ return s;
+}
+
+LOCALFUNC tMyErr TryAsAltHappyMacOptionNot(void)
+{
+ return FindNamedOption("-ahm", kNumAHMs, GetAltHappyMacName,
+ &cur_AltHappyMac, &olv_AltHappyMac);
+}
+
+#define dfo_AltHappyMac() gbk_AHM_none
+
+LOCALFUNC tMyErr ChooseAltHappyMac(void)
+{
+ if (kListOptionAuto == cur_AltHappyMac) {
+ cur_AltHappyMac = dfo_AltHappyMac();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptAltHappyMac(void)
+{
+ WrtOptNamedOption("-ahm", GetAltHappyMacName,
+ cur_AltHappyMac, dfo_AltHappyMac());
+}
+
+
+/* option: ROM size */
+
+LOCALVAR uimr cur_RomSize;
+LOCALVAR ui3r olv_RomSize;
+
+LOCALPROC ResetRomSizeOption(void)
+{
+ olv_RomSize = 0;
+}
+
+LOCALFUNC tMyErr TryAsRomSizeOptionNot(void)
+{
+ return NumberTryAsOptionNot("-rsz",
+ (long *)&cur_RomSize, &olv_RomSize);
+}
+
+LOCALFUNC uimr dfo_RomSize(void)
+{
+ uimr v;
+
+ switch (cur_mdl) {
+ case gbk_mdl_Twig43:
+ case gbk_mdl_Twiggy:
+ case gbk_mdl_128K:
+ v = ln2_msz_64K; /* 64 KB */
+ break;
+ case gbk_mdl_512Ke:
+ case gbk_mdl_Plus:
+ v = ln2_msz_128K; /* 128 KB */
+ break;
+ case gbk_mdl_SE:
+ case gbk_mdl_SEFDHD:
+ case gbk_mdl_PB100:
+ case gbk_mdl_II:
+ case gbk_mdl_IIx:
+ v = ln2_msz_256K; /* 256 KB */
+ break;
+ case gbk_mdl_Classic:
+ default:
+ v = ln2_msz_512K; /* 512 KB */
+ break;
+ }
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseRomSize(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+
+
+ if (0 == olv_RomSize) {
+ cur_RomSize = dfo_RomSize();
+ } else {
+ if ((cur_RomSize < 16) || (cur_RomSize > 31)) {
+ err = ReportParseFailure(
+ "-rsz must be a number between 16 and 31");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptRomSize(void)
+{
+ WrtOptNumberOption("-rsz", cur_RomSize, dfo_RomSize());
+}
+
+
+/* option: Want Check RomCheck Sum */
+
+LOCALVAR blnr WantCheckRomCheckSum;
+LOCALVAR ui3r olv_CheckRomCheckSum;
+
+LOCALPROC ResetCheckRomCheckSum(void)
+{
+ WantCheckRomCheckSum = nanblnr;
+ olv_CheckRomCheckSum = 0;
+}
+
+LOCALFUNC tMyErr TryAsCheckRomCheckSumNot(void)
+{
+ return BooleanTryAsOptionNot("-chr",
+ &WantCheckRomCheckSum, &olv_CheckRomCheckSum);
+}
+
+#define dfo_CheckRomCheckSum() trueblnr
+
+LOCALFUNC tMyErr ChooseCheckRomCheckSum(void)
+{
+ if (nanblnr == WantCheckRomCheckSum) {
+ WantCheckRomCheckSum = dfo_CheckRomCheckSum();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptCheckRomCheckSum(void)
+{
+ WrtOptBooleanOption("-chr",
+ WantCheckRomCheckSum, dfo_CheckRomCheckSum());
+}
+
+
+/* option: Want Disable Rom Check */
+
+LOCALVAR blnr WantDisableRomCheck;
+LOCALVAR ui3r olv_DisableRomCheck;
+
+LOCALPROC ResetDisableRomCheck(void)
+{
+ WantDisableRomCheck = nanblnr;
+ olv_DisableRomCheck = 0;
+}
+
+LOCALFUNC tMyErr TryAsDisableRomCheckNot(void)
+{
+ return BooleanTryAsOptionNot("-drc",
+ &WantDisableRomCheck, &olv_DisableRomCheck);
+}
+
+#define dfo_DisableRomCheck() trueblnr
+
+LOCALFUNC tMyErr ChooseDisableRomCheck(void)
+{
+ if (nanblnr == WantDisableRomCheck) {
+ WantDisableRomCheck = dfo_DisableRomCheck();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptDisableRomCheck(void)
+{
+ WrtOptBooleanOption("-drc",
+ WantDisableRomCheck, dfo_DisableRomCheck());
+}
+
+
+/* option: Want Disable Ram Test */
+
+LOCALVAR blnr WantDisableRamTest;
+LOCALVAR ui3r olv_DisableRamTest;
+
+LOCALPROC ResetDisableRamTest(void)
+{
+ WantDisableRamTest = nanblnr;
+ olv_DisableRamTest = 0;
+}
+
+LOCALFUNC tMyErr TryAsDisableRamTestNot(void)
+{
+ return BooleanTryAsOptionNot("-drt",
+ &WantDisableRamTest, &olv_DisableRamTest);
+}
+
+#define dfo_DisableRamTest() trueblnr
+
+LOCALFUNC tMyErr ChooseDisableRamTest(void)
+{
+ if (nanblnr == WantDisableRamTest) {
+ WantDisableRamTest = dfo_DisableRamTest();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptDisableRamTest(void)
+{
+ WrtOptBooleanOption("-drt",
+ WantDisableRamTest, dfo_DisableRamTest());
+}
+
+
+/* option: Want Disassembly */
+
+LOCALVAR blnr WantDisasm;
+LOCALVAR ui3r olv_WantDisasm;
+
+LOCALPROC ResetWantDisasm(void)
+{
+ WantDisasm = nanblnr;
+ olv_WantDisasm = 0;
+}
+
+LOCALFUNC tMyErr TryAsWantDisasmNot(void)
+{
+ return BooleanTryAsOptionNot("-dis",
+ &WantDisasm, &olv_WantDisasm);
+}
+
+#define dfo_WantDisasm() falseblnr
+
+LOCALFUNC tMyErr ChooseWantDisasm(void)
+{
+ if (nanblnr == WantDisasm) {
+ WantDisasm = dfo_WantDisasm();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptWantDisasmNot(void)
+{
+ WrtOptBooleanOption("-dis", WantDisasm, dfo_WantDisasm());
+}
+
+
+/* option: dbglog_HAVE */
+
+LOCALVAR blnr DbgLogHAVE;
+LOCALVAR ui3r olv_DbgLogHAVE;
+
+LOCALPROC ResetDbgLogHAVE(void)
+{
+ DbgLogHAVE = nanblnr;
+ olv_DbgLogHAVE = 0;
+}
+
+LOCALFUNC tMyErr TryAsDbgLogHAVENot(void)
+{
+ return BooleanTryAsOptionNot("-log", &DbgLogHAVE, &olv_DbgLogHAVE);
+}
+
+#define dfo_DbgLogHAVE() WantDisasm
+
+LOCALFUNC tMyErr ChooseDbgLogHAVE(void)
+{
+ if (nanblnr == DbgLogHAVE) {
+ DbgLogHAVE = dfo_DbgLogHAVE();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptDbgLogHAVE(void)
+{
+ WrtOptBooleanOption("-log", DbgLogHAVE, dfo_DbgLogHAVE());
+}
+
+
+/* option: Abnormal Reports */
+
+LOCALVAR blnr gbo_AbnormalReports;
+LOCALVAR ui3r olv_AbnormalReports;
+
+LOCALPROC ResetAbnormalReports(void)
+{
+ gbo_AbnormalReports = nanblnr;
+ olv_AbnormalReports = 0;
+}
+
+LOCALFUNC tMyErr TryAsAbnormalReportsNot(void)
+{
+ return BooleanTryAsOptionNot("-abr", &gbo_AbnormalReports,
+ &olv_AbnormalReports);
+}
+
+#define dfo_AbnormalReports() DbgLogHAVE
+
+LOCALFUNC tMyErr ChooseAbnormalReports(void)
+{
+ if (nanblnr == gbo_AbnormalReports) {
+ gbo_AbnormalReports = dfo_AbnormalReports();
+ }
+
+ return kMyErr_noErr;
+}
+
+LOCALPROC WrtOptAbnormalReports(void)
+{
+ WrtOptBooleanOption("-abr", gbo_AbnormalReports,
+ dfo_AbnormalReports());
+}
+
+
+/* option: Screen VSync */
+
+LOCALVAR blnr WantScreenVSync;
+LOCALVAR ui3r olv_ScreenVSync;
+
+LOCALPROC ResetScreenVSync(void)
+{
+ WantScreenVSync = nanblnr;
+ olv_ScreenVSync = 0;
+}
+
+LOCALFUNC tMyErr TryAsScreenVSyncNot(void)
+{
+ return BooleanTryAsOptionNot("-vsync",
+ &WantScreenVSync, &olv_ScreenVSync);
+}
+
+#define dfo_ScreenVSync() falseblnr
+
+LOCALFUNC tMyErr ChooseScreenVSync(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (nanblnr == WantScreenVSync) {
+ WantScreenVSync = dfo_ScreenVSync();
+ } else {
+ if (WantScreenVSync && (gbk_apifam_osx != gbo_apifam)) {
+ err = ReportParseFailure(
+ "-vsync is so far only implemented for OS X");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptScreenVSync(void)
+{
+ WrtOptBooleanOption("-vsync", WantScreenVSync, dfo_ScreenVSync());
+}
+
+
+/* option: Graphics Switching */
+
+LOCALVAR blnr WantGraphicsSwitching;
+LOCALVAR ui3r olv_GraphicsSwitching;
+
+LOCALPROC ResetGraphicsSwitching(void)
+{
+ WantGraphicsSwitching = nanblnr;
+ olv_GraphicsSwitching = 0;
+}
+
+LOCALFUNC tMyErr TryAsGraphicsSwitchingNot(void)
+{
+ return BooleanTryAsOptionNot("-gse",
+ &WantGraphicsSwitching, &olv_GraphicsSwitching);
+}
+
+#define dfo_GraphicsSwitching() falseblnr
+
+LOCALFUNC tMyErr ChooseGraphicsSwitching(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (nanblnr == WantGraphicsSwitching) {
+ WantGraphicsSwitching = dfo_GraphicsSwitching();
+ } else {
+ if (WantGraphicsSwitching && (gbk_apifam_cco != gbo_apifam)) {
+ err = ReportParseFailure(
+ "-gse is so far only implemented for cocoa on OS X");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptGraphicsSwitching(void)
+{
+ WrtOptBooleanOption("-gse", WantGraphicsSwitching,
+ dfo_GraphicsSwitching());
+}
+
+
+/* option: Signing */
+
+LOCALVAR blnr WantSigning;
+LOCALVAR ui3r olv_Signing;
+
+LOCALPROC ResetSigning(void)
+{
+ WantSigning = nanblnr;
+ olv_Signing = 0;
+}
+
+LOCALFUNC tMyErr TryAsSigningNot(void)
+{
+ return BooleanTryAsOptionNot("-sgn",
+ &WantSigning, &olv_Signing);
+}
+
+LOCALFUNC blnr dfo_Signing(void)
+{
+ blnr v;
+
+ v = (gbk_apifam_cco == gbo_apifam);
+
+ return v;
+}
+
+LOCALFUNC tMyErr ChooseSigning(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (nanblnr == WantSigning) {
+ WantSigning = dfo_Signing();
+ } else {
+ if (WantSigning && (gbk_apifam_cco != gbo_apifam)) {
+ err = ReportParseFailure(
+ "-sgn is so far only implemented for cocoa on OS X");
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptSigning(void)
+{
+ WrtOptBooleanOption("-sgn", WantSigning,
+ dfo_Signing());
+}
+
+
+/* option: Sandbox */
+
+LOCALVAR blnr WantSandbox;
+LOCALVAR ui3r olv_Sandbox;
+
+LOCALPROC ResetSandbox(void)
+{
+ WantSandbox = nanblnr;
+ olv_Sandbox = 0;
+}
+
+LOCALFUNC tMyErr TryAsSandboxNot(void)
+{
+ return BooleanTryAsOptionNot("-sbx",
+ &WantSandbox, &olv_Sandbox);
+}
+
+#define dfo_Sandbox() falseblnr
+
+LOCALFUNC tMyErr ChooseSandbox(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (nanblnr == WantSandbox) {
+ WantSandbox = dfo_Sandbox();
+ } else {
+ if (WantSandbox) {
+ if (gbk_apifam_cco != gbo_apifam) {
+ err = ReportParseFailure("-sbx"
+ " is so far only implemented for cocoa on OS X");
+ } else
+ if (! WantSigning) {
+ err = ReportParseFailure("-sbx"
+ " requires -sgn 1");
+ } else
+ {
+ /* ok */
+ }
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptSandbox(void)
+{
+ WrtOptBooleanOption("-sbx", WantSandbox,
+ dfo_Sandbox());
+}
+
+/* ------ */
+
+LOCALVAR blnr NeedScrnHack;
+LOCALVAR blnr NeedVidMem;
+
+LOCALFUNC tMyErr ChooseScreenOpts(void)
+{
+ tMyErr err;
+
+ err = kMyErr_noErr;
+ if (! cur_mIIorIIX) {
+ if (cur_hres * cur_vres > (uimr)2 * 1024 * 1024) {
+ err = ReportParseFailure(
+ "-hres and -vres multiplied must be < 2M");
+ }
+ }
+
+ if ((gbk_mdl_PB100 == cur_mdl)
+ || cur_mIIorIIX)
+ {
+ NeedScrnHack = falseblnr;
+ NeedVidMem = trueblnr;
+ } else {
+ NeedScrnHack = (cur_hres != dfo_hres())
+ || (cur_vres != dfo_vres());
+ NeedVidMem = NeedScrnHack;
+ }
+
+ return err;
+}
+
+LOCALVAR blnr EmVidCard;
+
+/* video memory size */
+
+LOCALVAR uimr VidMemSize;
+
+LOCALFUNC tMyErr ChooseVidMemSize(void)
+{
+ tMyErr err;
+
+ EmVidCard = cur_mIIorIIX;
+
+ VidMemSize = (((cur_hres * cur_vres) << cur_ScrnDpth) + 7) >> 3;
+
+ --VidMemSize;
+ VidMemSize |= (VidMemSize >> 1);
+ VidMemSize |= (VidMemSize >> 2);
+ VidMemSize |= (VidMemSize >> 4);
+ VidMemSize |= (VidMemSize >> 8);
+ VidMemSize |= (VidMemSize >> 16);
+ ++VidMemSize;
+
+ err = kMyErr_noErr;
+ if (! NeedVidMem) {
+ VidMemSize = 0;
+ } else if (EmVidCard) {
+ if (VidMemSize > 4 * 1024 * 1024) {
+ err = ReportParseFailure(
+ "video memory must be <= 4M");
+ } else if (VidMemSize <= 0x00008000) {
+ VidMemSize = 0x00008000;
+ }
+ } else if (gbk_mdl_PB100 == cur_mdl) {
+ VidMemSize = 0x00008000;
+ } else {
+ /* VidMemSize = 0x00020000; */
+
+ if (VidMemSize > 256 * 1024) {
+ err = ReportParseFailure(
+ "video memory must be <= 256K");
+ } else if (VidMemSize <= 0x00004000) {
+ VidMemSize = 0x00004000;
+ }
+ }
+
+ return err;
+}
+
+/* figure out what hardware to emulate */
+
+LOCALVAR blnr EmClassicKbrd;
+LOCALVAR blnr EmADB;
+LOCALVAR blnr EmRTC;
+LOCALVAR blnr EmPMU;
+LOCALVAR blnr EmVIA2;
+LOCALVAR blnr EmASC;
+
+LOCALFUNC tMyErr ChooseMiscEmHardware(void)
+{
+ EmClassicKbrd = cur_mdl <= gbk_mdl_Plus;
+
+ if (EmClassicKbrd) {
+ EmADB = falseblnr;
+ EmRTC = trueblnr;
+ EmPMU = falseblnr;
+ } else
+ if ((cur_mdl <= gbk_mdl_Classic)
+ || cur_mIIorIIX)
+ {
+ EmADB = trueblnr;
+ EmRTC = trueblnr;
+ EmPMU = falseblnr;
+ } else
+ {
+ EmADB = falseblnr;
+ EmRTC = falseblnr;
+ EmPMU = trueblnr;
+ }
+
+ EmVIA2 = cur_mIIorIIX;
+ EmASC = (gbk_mdl_PB100 == cur_mdl) || cur_mIIorIIX;
+
+ return kMyErr_noErr;
+}
+
+/* total memory size */
+
+#define dbglog_buflnsz 18
+
+#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */
+#define kLnOneBuffLen 9
+
+#define dbhBufferSize (((1UL << kLn2SoundBuffers) + 1UL) \
+ << (kLnOneBuffLen + cur_SoundSampSz - 3))
+
+#define vMacScreenNumBytes ((((cur_hres * cur_vres) \
+ << cur_ScrnDpth) + 7) >> 3)
+
+LOCALVAR uimr TotMemSize;
+
+LOCALFUNC tMyErr ChooseTotMemSize(void)
+{
+ TotMemSize = 0;
+
+ if (DbgLogHAVE) {
+ TotMemSize += (1 << dbglog_buflnsz);
+ }
+
+
+ /* CntrlDisplayBuff */
+ TotMemSize += vMacScreenNumBytes;
+
+ /* screencomparebuff */
+ TotMemSize += vMacScreenNumBytes;
+
+ if (1 != cur_MagFctr) {
+ /* ScalingBuff */
+ TotMemSize += vMacScreenNumBytes * cur_MagFctr * cur_MagFctr;
+
+ /* ScalingTabl */
+ TotMemSize += 256 * cur_MagFctr;
+ }
+
+ if (MySoundEnabled) {
+ /* TheSoundBuffer */
+ TotMemSize += dbhBufferSize;
+ }
+
+ TotMemSize += (1 << RAMa_Size);
+ if (0 != RAMb_Size) {
+ TotMemSize += (1 << RAMb_Size);
+ }
+
+ if (EmVidCard) {
+ TotMemSize += 0x000800; /* kVidROM_Size */
+ }
+
+ if (NeedVidMem) {
+ TotMemSize += VidMemSize;
+ }
+
+ TotMemSize += 512 * 1024UL;
+ /* for M68KITAB */
+
+ return kMyErr_noErr;
+}
+
+/* ------ */
+
+LOCALPROC SPResetCommandLineParameters(void)
+{
+ ResetModelOption();
+ ResetHResOption();
+ ResetVResOption();
+ ResetScrnDpthOption();
+ ResetInitFullScreen();
+ ResetVarFullScreen();
+ ResetMagFctrOption();
+ ResetInitMagnify();
+ ResetSoundOption();
+ ResetSndApiOption();
+ ResetSoundSampSzOption();
+ ResetNumDrivesOption();
+ ResetSonySupportTags();
+ ResetSonyWantChecksumsUpdated();
+ ResetSonySupportDC42();
+ ResetSaveDialogEnable();
+ ResetInsertIthDisk();
+ ResetCmndOptSwap();
+ ResetKeyMapOption();
+ ResetEKTMapOption();
+ ResetAltKeysMode();
+ ResetItnlKyBdFixOption();
+ ResetLocalTalk();
+ ResetInitSpeedOption();
+ ResetInitBackground();
+ ResetInitAutoSlow();
+ ResetTimingAccuracyOption();
+ ResetEmCpuVersOption();
+ ResetMemSizOption();
+ ResetCaretBlinkTimeOption();
+ ResetDoubleClickTimeOption();
+ ResetMenuBlinkOption();
+ ResetAutoKeyThreshOption();
+ ResetAutoKeyRateOption();
+ ResetHilColRedOption();
+ ResetHilColGreenOption();
+ ResetHilColBlueOption();
+ ResetAutoLocation();
+ ResetInitLatitudeOption();
+ ResetInitLongitudeOption();
+ ResetAutoTimeZone();
+ ResetTzDST();
+ ResetTzDeltHOption();
+ ResetTzDeltSOption();
+ ResetSpeakerVolOption();
+ ResetWantMinExtn();
+ ResetMouseMotionOption();
+ ResetGrabKeysFS();
+ ResetEnblCtrlInt();
+ ResetEnblCtrlRst();
+ ResetEnblCtrlKtg();
+ ResetWantColorImage();
+ ResetAltHappyMacOption();
+ ResetRomSizeOption();
+ ResetCheckRomCheckSum();
+ ResetDisableRomCheck();
+ ResetDisableRamTest();
+ ResetWantDisasm();
+ ResetDbgLogHAVE();
+ ResetAbnormalReports();
+ ResetScreenVSync();
+ ResetGraphicsSwitching();
+ ResetSigning();
+ ResetSandbox();
+}
+
+LOCALFUNC tMyErr TryAsSPOptionNot(void)
+{
+ tMyErr err;
+
+ if (kMyErrNoMatch == (err = TryAsModelOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsHResOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsVResOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsScrnDpthOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsInitFullScreenNot()))
+ if (kMyErrNoMatch == (err = TryAsVarFullScreenNot()))
+ if (kMyErrNoMatch == (err = TryAsMagFctrOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsInitMagnifyNot()))
+ if (kMyErrNoMatch == (err = TryAsSoundOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsSndApiOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsSoundSampSzOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsNumDrivesOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsSonySupportTagsNot()))
+ if (kMyErrNoMatch == (err = TryAsSonyWantChecksumsUpdatedNot()))
+ if (kMyErrNoMatch == (err = TryAsSonySupportDC42Not()))
+ if (kMyErrNoMatch == (err = TryAsSaveDialogEnable()))
+ if (kMyErrNoMatch == (err = TryAsInsertIthDisk()))
+ if (kMyErrNoMatch == (err = TryAsCmndOptSwapNot()))
+ if (kMyErrNoMatch == (err = TryAsKeyMapOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsEKTMapOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsAltKeysModeNot()))
+ if (kMyErrNoMatch == (err = TryAsItnlKyBdFixNot()))
+ if (kMyErrNoMatch == (err = TryAsLocalTalkNot()))
+ if (kMyErrNoMatch == (err = TryAsInitSpeedOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsInitBackgroundNot()))
+ if (kMyErrNoMatch == (err = TryAsInitAutoSlowNot()))
+ if (kMyErrNoMatch == (err = TryAsTimingAccuracyOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsEmCpuVersOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsMemSizOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsCaretBlinkTimeOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsDoubleClickTimeOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsMenuBlinkOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsAutoKeyThreshOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsAutoKeyRateOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsHilColRedOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsHilColGreenOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsHilColBlueOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsAutoLocationNot()))
+ if (kMyErrNoMatch == (err = TryAsInitLatitudeOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsInitLongitudeOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsAutoTimeZoneNot()))
+ if (kMyErrNoMatch == (err = TryAsTzDSTNot()))
+ if (kMyErrNoMatch == (err = TryAsTzDeltHOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsTzDeltSOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsSpeakerVolOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsWantMinExtnNot()))
+ if (kMyErrNoMatch == (err = TryAsMouseMotionOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsGrabKeysFSNot()))
+ if (kMyErrNoMatch == (err = TryAsEnblCtrlIntNot()))
+ if (kMyErrNoMatch == (err = TryAsEnblCtrlRstNot()))
+ if (kMyErrNoMatch == (err = TryAsEnblCtrlKtgNot()))
+ if (kMyErrNoMatch == (err = TryAsWantColorImageNot()))
+ if (kMyErrNoMatch == (err = TryAsAltHappyMacOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsRomSizeOptionNot()))
+ if (kMyErrNoMatch == (err = TryAsCheckRomCheckSumNot()))
+ if (kMyErrNoMatch == (err = TryAsDisableRomCheckNot()))
+ if (kMyErrNoMatch == (err = TryAsDisableRamTestNot()))
+ if (kMyErrNoMatch == (err = TryAsWantDisasmNot()))
+ if (kMyErrNoMatch == (err = TryAsDbgLogHAVENot()))
+ if (kMyErrNoMatch == (err = TryAsAbnormalReportsNot()))
+ if (kMyErrNoMatch == (err = TryAsScreenVSyncNot()))
+ if (kMyErrNoMatch == (err = TryAsGraphicsSwitchingNot()))
+ if (kMyErrNoMatch == (err = TryAsSigningNot()))
+ if (kMyErrNoMatch == (err = TryAsSandboxNot()))
+ {
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr AutoChooseSPSettings(void)
+{
+ tMyErr err;
+
+ if (kMyErr_noErr == (err = ChooseModel()))
+ if (kMyErr_noErr == (err = ChooseHRes()))
+ if (kMyErr_noErr == (err = ChooseVRes()))
+ if (kMyErr_noErr == (err = ChooseScrnDpth()))
+ if (kMyErr_noErr == (err = ChooseInitFullScreen()))
+ if (kMyErr_noErr == (err = ChooseVarFullScreen()))
+ if (kMyErr_noErr == (err = ChooseMagFctr()))
+ if (kMyErr_noErr == (err = ChooseInitMagnify()))
+ if (kMyErr_noErr == (err = ChooseSoundEnabled()))
+ if (kMyErr_noErr == (err = ChooseSndApiOption()))
+ if (kMyErr_noErr == (err = ChooseSoundSampSz()))
+ if (kMyErr_noErr == (err = ChooseNumDrives()))
+ if (kMyErr_noErr == (err = ChooseSonySupportTags()))
+ if (kMyErr_noErr == (err = ChooseSonyWantChecksumsUpdated()))
+ if (kMyErr_noErr == (err = ChooseSonySupportDC42()))
+ if (kMyErr_noErr == (err = ChooseSaveDialogEnable()))
+ if (kMyErr_noErr == (err = ChooseInsertIthDisk()))
+ if (kMyErr_noErr == (err = ChooseCmndOptSwap()))
+ if (kMyErr_noErr == (err = ChooseKeyMap()))
+ if (kMyErr_noErr == (err = ChooseEKTMap()))
+ if (kMyErr_noErr == (err = ChooseAltKeysMode()))
+ if (kMyErr_noErr == (err = ChooseItnlKyBdFix()))
+ if (kMyErr_noErr == (err = ChooseLocalTalk()))
+ if (kMyErr_noErr == (err = ChooseInitSpeed()))
+ if (kMyErr_noErr == (err = ChooseInitBackground()))
+ if (kMyErr_noErr == (err = ChooseInitAutoSlow()))
+ if (kMyErr_noErr == (err = ChooseTimingAccuracy()))
+ if (kMyErr_noErr == (err = ChooseEmCpuVers()))
+ if (kMyErr_noErr == (err = ChooseMemSiz()))
+ if (kMyErr_noErr == (err = ChooseMemBankSizes())) /* derived */
+ if (kMyErr_noErr == (err = ChooseCaretBlinkTime()))
+ if (kMyErr_noErr == (err = ChooseDoubleClickTime()))
+ if (kMyErr_noErr == (err = ChooseMenuBlink()))
+ if (kMyErr_noErr == (err = ChooseAutoKeyThresh()))
+ if (kMyErr_noErr == (err = ChooseAutoKeyRate()))
+ if (kMyErr_noErr == (err = ChooseHilColRed()))
+ if (kMyErr_noErr == (err = ChooseHilColGreen()))
+ if (kMyErr_noErr == (err = ChooseHilColBlue()))
+ if (kMyErr_noErr == (err = ChooseAutoLocation()))
+ if (kMyErr_noErr == (err = ChooseInitLatitude()))
+ if (kMyErr_noErr == (err = ChooseInitLongitude()))
+ if (kMyErr_noErr == (err = ChooseAutoTimeZone()))
+ if (kMyErr_noErr == (err = ChooseTzDST()))
+ /* if (kMyErr_noErr == (err = ChooseTzDeltH())) */
+ if (kMyErr_noErr == (err = ChooseTzDeltS()))
+ if (kMyErr_noErr == (err = ChooseSpeakerVol()))
+ if (kMyErr_noErr == (err = ChooseWantMinExtn()))
+ if (kMyErr_noErr == (err = ChooseMouseMotion()))
+ if (kMyErr_noErr == (err = ChooseGrabKeysFS()))
+ if (kMyErr_noErr == (err = ChooseEnblCtrlInt()))
+ if (kMyErr_noErr == (err = ChooseEnblCtrlRst()))
+ if (kMyErr_noErr == (err = ChooseEnblCtrlKtg()))
+ if (kMyErr_noErr == (err = ChooseWantColorImage()))
+ if (kMyErr_noErr == (err = ChooseAltHappyMac()))
+ if (kMyErr_noErr == (err = ChooseRomSize()))
+ if (kMyErr_noErr == (err = ChooseCheckRomCheckSum()))
+ if (kMyErr_noErr == (err = ChooseDisableRomCheck()))
+ if (kMyErr_noErr == (err = ChooseDisableRamTest()))
+
+ if (kMyErr_noErr == (err = ChooseWantDisasm()))
+ if (kMyErr_noErr == (err = ChooseDbgLogHAVE()))
+ if (kMyErr_noErr == (err = ChooseAbnormalReports()))
+ if (kMyErr_noErr == (err = ChooseScreenVSync()))
+ if (kMyErr_noErr == (err = ChooseGraphicsSwitching()))
+ if (kMyErr_noErr == (err = ChooseSigning()))
+ if (kMyErr_noErr == (err = ChooseSandbox()))
+
+ if (kMyErr_noErr == (err = ChooseScreenOpts())) /* derived */
+ if (kMyErr_noErr == (err = ChooseVidMemSize())) /* derived */
+ if (kMyErr_noErr == (err = ChooseMiscEmHardware())) /* derived */
+ if (kMyErr_noErr == (err = ChooseTotMemSize())) /* derived */
+ {
+ err = kMyErr_noErr;
+ }
+
+ return err;
+}
+
+LOCALPROC WrtOptSPSettings(void)
+{
+ WrtOptModelOption();
+ WrtOptHResOption();
+ WrtOptVResOption();
+ WrtOptScrnDpth();
+ WrtOptInitFullScreen();
+ WrtOptVarFullScreen();
+ WrtOptMagFctrOption();
+ WrtOptInitMagnify();
+ WrtOptSoundOption();
+ WrtOptSndApiOption();
+ WrtOptSoundSampSzOption();
+ WrtOptNumDrivesOption();
+ WrtOptSonySupportTags();
+ WrtOptSonyWantChecksumsUpdated();
+ WrtOptSonySupportDC42();
+ WrtOptSaveDialogEnable();
+ WrtOptInsertIthDisk();
+ WrtOptCmndOptSwap();
+ WrtOptKeyMap();
+ WrtOptEKTMap();
+ WrtOptAltKeysMode();
+ WrtOptItnlKyBdFix();
+ WrtOptLocalTalk();
+ WrtOptInitSpeedOption();
+ WrtOptInitBackground();
+ WrtOptInitAutoSlow();
+ WrtOptTimingAccuracy();
+ WrtOptEmCpuVers();
+ WrtOptMemSizOption();
+ WrtOptCaretBlinkTime();
+ WrtOptDoubleClickTime();
+ WrtOptMenuBlink();
+ WrtOptAutoKeyThresh();
+ WrtOptAutoKeyRate();
+ WrtOptHilColRed();
+ WrtOptHilColGreen();
+ WrtOptHilColBlue();
+ WrtOptAutoLocation();
+ WrtOptInitLatitude();
+ WrtOptInitLongitude();
+ WrtOptAutoTimeZone();
+ WrtOptTzDST();
+ /* WrtOptTzDeltH(); */
+ WrtOptTzDeltS();
+ WrtOptSpeakerVol();
+ WrtOptMinExtn();
+ WrtOptMouseMotion();
+ WrtOptGrabKeysFS();
+ WrtOptEnblCtrlInt();
+ WrtOptEnblCtrlRst();
+ WrtOptEnblCtrlKtg();
+ WrtOptColorImage();
+ WrtOptAltHappyMac();
+ WrtOptRomSize();
+ WrtOptCheckRomCheckSum();
+ WrtOptDisableRomCheck();
+ WrtOptDisableRamTest();
+ WrtOptWantDisasmNot();
+ WrtOptDbgLogHAVE();
+ WrtOptAbnormalReports();
+ WrtOptScreenVSync();
+ WrtOptGraphicsSwitching();
+ WrtOptSigning();
+ WrtOptSandbox();
+}
--- /dev/null
+++ b/setup/SPCNFGAP.i
@@ -1,0 +1,286 @@
+/*
+ SPCNFGAP.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ program SPecific CoNFiGuration of API users
+
+ (that is, configuration settings that are used
+ only by platform specific code)
+*/
+
+
+LOCALPROC WriteAppSpecificCNFGRAPIoptions(void)
+{
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define RomFileName \"");
+ switch (cur_mdl) {
+ case gbk_mdl_Twig43:
+ WriteCStrToDestFile("Twig43.ROM");
+ break;
+ case gbk_mdl_Twiggy:
+ WriteCStrToDestFile("Twiggy.ROM");
+ break;
+ case gbk_mdl_128K:
+ WriteCStrToDestFile("Mac128K.ROM");
+ break;
+ case gbk_mdl_SE:
+ WriteCStrToDestFile("MacSE.ROM");
+ break;
+ case gbk_mdl_SEFDHD:
+ WriteCStrToDestFile("SEFDHD.ROM");
+ break;
+ case gbk_mdl_Classic:
+ WriteCStrToDestFile("Classic.ROM");
+ break;
+ case gbk_mdl_PB100:
+ WriteCStrToDestFile("PB100.ROM");
+ break;
+ case gbk_mdl_II:
+ WriteCStrToDestFile("MacII.ROM");
+ break;
+ case gbk_mdl_IIx:
+ WriteCStrToDestFile("MacIIx.ROM");
+ break;
+ case gbk_mdl_512Ke:
+ case gbk_mdl_Plus:
+ default:
+ WriteCStrToDestFile("vMac.ROM");
+ break;
+ }
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define kCheckSumRom_Size ");
+ if (gbk_mdl_Classic == cur_mdl) {
+ WriteCStrToDestFile("0x040000"); /* 256 KB */
+ } else {
+ WriteCStrToDestFile("0x");
+ WriteHexLongToOutput(1UL << cur_RomSize);
+ }
+ WriteEndDestFileLn();
+
+ switch (cur_mdl) {
+ case gbk_mdl_Twig43:
+ WriteDestFileLn("#define kRomCheckSum1 0x27F4E04B");
+ break;
+ case gbk_mdl_Twiggy:
+ WriteDestFileLn("#define kRomCheckSum1 0x2884371D");
+ break;
+ case gbk_mdl_128K:
+ WriteDestFileLn("#define kRomCheckSum1 0x28BA61CE");
+ WriteDestFileLn("#define kRomCheckSum2 0x28BA4E50");
+ break;
+ case gbk_mdl_SE:
+ WriteDestFileLn("#define kRomCheckSum1 0xB2E362A8");
+ break;
+ case gbk_mdl_SEFDHD:
+ WriteDestFileLn("#define kRomCheckSum1 0xB306E171");
+ break;
+ case gbk_mdl_Classic:
+ WriteDestFileLn("#define kRomCheckSum1 0xA49F9914");
+ break;
+ case gbk_mdl_PB100:
+ WriteDestFileLn("#define kRomCheckSum1 0x96645F9C");
+ break;
+ case gbk_mdl_II:
+ WriteDestFileLn("#define kRomCheckSum1 0x9779D2C4");
+ WriteDestFileLn("#define kRomCheckSum2 0x97221136");
+ break;
+ case gbk_mdl_IIx:
+ WriteDestFileLn("#define kRomCheckSum1 0x97221136");
+ break;
+ case gbk_mdl_512Ke:
+ case gbk_mdl_Plus:
+ default:
+ WriteDestFileLn("#define kRomCheckSum1 0x4D1EEEE1");
+ /* Mac Plus ROM v 1, 'Lonely Hearts' */
+ WriteDestFileLn("#define kRomCheckSum2 0x4D1EEAE1");
+ /* Mac Plus ROM v 2, 'Lonely Heifers' */
+ WriteDestFileLn("#define kRomCheckSum3 0x4D1F8172");
+ /* Mac Plus ROM v 3, 'Loud Harmonicas' */
+ break;
+ }
+
+ if (! WantCheckRomCheckSum) {
+ WriteCompCondBool("CheckRomCheckSum", WantCheckRomCheckSum);
+ }
+
+ WriteCompCondBool("RomStartCheckSum", (cur_mdl >= gbk_mdl_Twiggy));
+
+ if (DbgLogHAVE) {
+ WriteDefineUimr("dbglog_buflnsz", dbglog_buflnsz);
+ }
+
+ if (gbk_targfam_wnce == gbo_targfam) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("#define EnableShellLinks 0");
+ WriteDestFileLn("#define EnableDragDrop 0");
+ WriteDestFileLn("#define UseTimerThread 0");
+ } else if (gbk_targfam_lnds == gbo_targfam) {
+ WriteDestFileLn("#define EnableDragDrop 0");
+ } else {
+ WriteDestFileLn("#define EnableDragDrop 1");
+ }
+ WriteCompCondBool("SaveDialogEnable", gbo_SaveDialogEnable);
+ WriteCompCondBool("EnableAltKeysMode", WantAltKeysMode);
+ {
+ uimr i;
+
+ for (i = 0; i < kNumSrcKeyNames; ++i) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define MKC_formac_");
+ WriteCStrToDestFile(GetSrcKeyMapName(i));
+ WriteCStrToDestFile(" MKC_");
+ WriteCStrToDestFile(GetDstKeyMapName(gbo_keymap[i]));
+ WriteEndDestFileLn();
+ }
+ }
+
+ if (gbk_keynam_Control == ControlModeKey) {
+ /* kStrCntrlKyName */
+ } else {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define kControlModeKey \"");
+ WriteCStrToDestFile(GetSrcKeyMapName(ControlModeKey));
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+ }
+
+ if (gbk_keynam_Control == gbo_EKTMap) {
+ /* kStrCntrlKyName */
+ } else {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define kUnMappedKey \"");
+ WriteCStrToDestFile(GetDstKeyMapName(gbo_EKTMap));
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+ }
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define MKC_UnMappedKey ");
+ WriteCStrToDestFile(" MKC_");
+ WriteCStrToDestFile(GetDstKeyMapName(gbo_EKTMap));
+ WriteEndDestFileLn();
+
+ WriteCompCondBool("VarFullScreen", WantVarFullScreen);
+ if (WantVarFullScreen) {
+ WriteCompCondBool("WantInitFullScreen", WantInitFullScreen);
+ }
+ WriteCompCondBool("MayFullScreen",
+ WantVarFullScreen || WantInitFullScreen);
+ WriteCompCondBool("MayNotFullScreen",
+ WantVarFullScreen || ! WantInitFullScreen);
+
+ WriteCompCondBool("WantInitMagnify", WantInitMagnify);
+
+ WriteCompCondBool("EnableMagnify", 1 != cur_MagFctr);
+ if (1 != cur_MagFctr) {
+ WriteDefineUimr("MyWindowScale", cur_MagFctr);
+ }
+
+ if (nanblnr != WantColorImage) {
+ WriteCompCondBool("UseColorImage", WantColorImage);
+ }
+
+ WriteCompCondBool("WantInitRunInBackground", WantInitBackground);
+ WriteCompCondBool("WantInitNotAutoSlow", ! WantInitAutoSlow);
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define WantInitSpeedValue ");
+ if (gbk_speed_AllOut == CurInitSpeed) {
+ WriteCStrToDestFile("-1");
+ } else {
+ WriteUnsignedToOutput(CurInitSpeed - 1);
+ }
+ WriteEndDestFileLn();
+
+ if (WantScreenVSync) {
+ WriteDestFileLn("#define UseAGLdoublebuff 1");
+ }
+
+ if (WantGraphicsSwitching) {
+ WriteDestFileLn("#define WantGraphicsSwitching 1");
+ }
+
+ if (! WantGrabKeysFS) {
+ WriteDestFileLn("#define GrabKeysFullScreen 0");
+ }
+
+ WriteCompCondBool("WantEnblCtrlInt", WantEnblCtrlInt);
+ WriteCompCondBool("WantEnblCtrlRst", WantEnblCtrlRst);
+ WriteCompCondBool("WantEnblCtrlKtg", WantEnblCtrlKtg);
+
+ WriteCompCondBool("NeedRequestInsertDisk",
+ (gbk_apifam_gtk == gbo_apifam)
+ || (gbk_apifam_mac == gbo_apifam)
+ || (gbk_apifam_win == gbo_apifam)
+ || (gbk_apifam_osx == gbo_apifam)
+ || (gbk_apifam_cco == gbo_apifam)
+ );
+
+ if (WantInsertIthDisk) {
+ WriteDestFileLn("#define NeedRequestIthDisk 1");
+ }
+
+ WriteCompCondBool("NeedDoMoreCommandsMsg",
+ (gbk_apifam_gtk == gbo_apifam)
+ || (gbk_apifam_mac == gbo_apifam)
+ || (gbk_apifam_win == gbo_apifam)
+ || (gbk_apifam_osx == gbo_apifam)
+ || (gbk_apifam_cco == gbo_apifam)
+ );
+ WriteCompCondBool("NeedDoAboutMsg",
+ (gbk_apifam_gtk == gbo_apifam)
+ || (gbk_apifam_mac == gbo_apifam)
+ || (gbk_apifam_win == gbo_apifam)
+ || (gbk_apifam_osx == gbo_apifam)
+ || (gbk_apifam_cco == gbo_apifam)
+ );
+ WriteCompCondBool("UseControlKeys", trueblnr);
+ WriteCompCondBool("UseActvCode", WantActvCode);
+ WriteCompCondBool("EnableDemoMsg", WantDemoMsg);
+
+ if (WantActvCode) {
+ int i;
+
+ WriteBlankLineToDestFile();
+ for (i = 0; i < NumKeyCon; ++i) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define KeyCon");
+ WriteUnsignedToOutput(i);
+ WriteSpaceToDestFile();
+ WriteUnsignedToOutput(KeyCon[i]);
+ WriteEndDestFileLn();
+ }
+ }
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("/* version and other info to display to user */");
+
+ WriteBlankLineToDestFile();
+
+ WriteCompCondBool("NeedIntlChars",
+ (gbk_lang_eng != gbo_lang) || NeedIntl);
+ if (gbk_apifam_win == gbo_apifam) {
+ WriteCompCondBool("ItnlKyBdFix", ItnlKyBdFix);
+ }
+ WriteCDefQuote("kStrAppName", WriteStrAppUnabrevName);
+ WriteCDefQuote("kAppVariationStr", WriteAppVariationStr);
+ WriteCDefQuote("kStrCopyrightYear", WriteAppCopyrightYearStr);
+ WriteCDefQuote("kMaintainerName", WriteMaintainerName);
+ WriteCDefQuote("kStrHomePage", WriteHomePage);
+}
--- /dev/null
+++ b/setup/SPCNFGGL.i
@@ -1,0 +1,103 @@
+/*
+ SPCNFGGL.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ program SPecific CoNFiGuration GLobals
+*/
+
+LOCALPROC WriteAppSpecificCNFGGLOBoptions(void)
+{
+ WriteBlankLineToDestFile();
+
+ WriteCompCondBool("MySoundRecenterSilence", falseblnr);
+
+ WriteDefineUimr("kLn2SoundSampSz", cur_SoundSampSz);
+
+ WriteBlankLineToDestFile();
+
+#if 0 /* not used currently */
+ WriteCompCondBool("Debug", gbk_dbg_off != gbo_dbg);
+#endif
+
+ WriteCompCondBool("dbglog_HAVE", DbgLogHAVE);
+
+ WriteCompCondBool("WantAbnormalReports", gbo_AbnormalReports);
+
+ WriteBlankLineToDestFile();
+
+ WriteDefineUimr("NumDrives", cur_numdrives);
+
+ WriteCompCondBool("IncludeSonyRawMode", (! WantMinExtn)
+ && (gbk_apifam_nds != gbo_apifam));
+ WriteCompCondBool("IncludeSonyGetName",
+ (! WantMinExtn) && (gbk_apifam_gtk != gbo_apifam)
+ && (gbk_apifam_nds != gbo_apifam)
+ && (gbk_apifam_sdl != gbo_apifam)
+ && (gbk_apifam_sd2 != gbo_apifam));
+ WriteCompCondBool("IncludeSonyNew",
+ (! WantMinExtn) && (gbk_apifam_gtk != gbo_apifam)
+ && (gbk_apifam_sdl != gbo_apifam)
+ && (gbk_apifam_sd2 != gbo_apifam)
+ && (gbk_apifam_nds != gbo_apifam));
+ WriteCompCondBool("IncludeSonyNameNew",
+ (! WantMinExtn) && (gbk_apifam_gtk != gbo_apifam)
+ && (gbk_apifam_sdl != gbo_apifam)
+ && (gbk_apifam_sd2 != gbo_apifam)
+ && (gbk_apifam_nds != gbo_apifam));
+
+ WriteBlankLineToDestFile();
+
+ WriteDefineUimr("vMacScreenHeight", cur_vres);
+ WriteDefineUimr("vMacScreenWidth", cur_hres);
+ WriteDefineUimr("vMacScreenDepth", cur_ScrnDpth);
+
+
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define kROM_Size ");
+ WriteCStrToDestFile("0x");
+ WriteHexLongToOutput(1UL << cur_RomSize);
+ WriteEndDestFileLn();
+
+
+ WriteBlankLineToDestFile();
+
+ WriteCompCondBool("IncludePbufs",
+ 1 /* ((! WantMinExtn) || WantActvCode || WantDemoMsg) */
+ && (gbk_apifam_gtk != gbo_apifam)
+ && (gbk_apifam_nds != gbo_apifam));
+
+ WriteDefineUimr("NumPbufs", 4);
+
+
+ WriteBlankLineToDestFile();
+
+ WriteCompCondBool("EnableMouseMotion", MyMouseMotion);
+
+ WriteBlankLineToDestFile();
+
+ WriteCompCondBool("IncludeHostTextClipExchange",
+ 1 /* ((! WantMinExtn) || WantActvCode || WantDemoMsg) */
+ && (gbk_apifam_gtk != gbo_apifam)
+ && (gbk_apifam_sdl != gbo_apifam)
+ && (gbk_apifam_nds != gbo_apifam));
+
+ WriteDestFileLn("#define EnableAutoSlow 1");
+ WriteCompCondBool("EmLocalTalk", WantLocalTalk);
+
+ WriteCompCondBool("AutoLocation", WantAutoLocation);
+ WriteCompCondBool("AutoTimeZone", WantAutoTimeZone);
+}
--- /dev/null
+++ b/setup/SPFILDEF.i
@@ -1,0 +1,296 @@
+/*
+ SPFILDEF.i
+ Copyright (C) 2012 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ program SPecific FILe DEFinitions
+*/
+
+
+
+/* --- list of source files --- */
+
+static void DoMYOSGLUEdepends(tDoOneDepends p)
+{
+ {
+ char *s = nullpr;
+
+ switch (gbo_lang) {
+ case gbk_lang_eng:
+ s = "STRCNENG.h";
+ break;
+ case gbk_lang_fre:
+ s = "STRCNFRE.h";
+ break;
+ case gbk_lang_ita:
+ s = "STRCNITA.h";
+ break;
+ case gbk_lang_ger:
+ s = "STRCNGER.h";
+ break;
+ case gbk_lang_dut:
+ s = "STRCNDUT.h";
+ break;
+ case gbk_lang_spa:
+ s = "STRCNSPA.h";
+ break;
+ case gbk_lang_pol:
+ s = "STRCNPOL.h";
+ break;
+ case gbk_lang_ptb:
+ s = "STRCNPTB.h";
+ break;
+ case gbk_lang_cat:
+ s = "STRCNCAT.h";
+ break;
+ case gbk_lang_cze:
+ s = "STRCNCZE.h";
+ break;
+ case gbk_lang_srl:
+ s = "STRCNSRL.h";
+ break;
+ }
+
+ if (nullpr != s) {
+ p(kDepDirCSrc, s);
+ }
+ }
+
+ p(kDepDirCnfg, "STRCONST.h");
+ p(kDepDirCSrc, "INTLCHAR.h");
+ p(kDepDirCSrc, "COMOSGLU.h");
+ if (WantLocalTalk) {
+ p(kDepDirCSrc, "BPFILTER.h");
+ }
+ if (WantAltKeysMode) {
+ p(kDepDirCSrc, "ALTKEYSM.h");
+ }
+ p(kDepDirCSrc, "CONTROLM.h");
+ if (gbk_sndapi_none != gbo_sndapi) {
+ {
+ char *s = nullpr;
+
+ switch (gbo_sndapi) {
+ case gbk_sndapi_alsa:
+ s = "SGLUALSA.h";
+ break;
+ case gbk_sndapi_ddsp:
+ s = "SGLUDDSP.h";
+ break;
+ }
+
+ if (nullpr != s) {
+ p(kDepDirCSrc, s);
+ }
+ }
+ p(kDepDirCnfg, "SOUNDGLU.h");
+ }
+}
+
+static void DoMINEM68Kdepends(tDoOneDepends p)
+{
+ if (cur_mIIorIIX) {
+ p(kDepDirCSrc, "FPMATHEM.h");
+ p(kDepDirCSrc, "FPCPEMDV.h");
+ }
+}
+
+static void DoROMEMDEVdepends(tDoOneDepends p)
+{
+ if (NeedScrnHack) {
+ p(kDepDirCSrc, "SCRNHACK.h");
+ }
+ if (gbk_AHM_none != cur_AltHappyMac) {
+ p(kDepDirCSrc, "HPMCHACK.h");
+ }
+}
+
+static void DoAllSrcFiles(tDoOneCFile p)
+{
+ blnr WantSCRNMAPR = (gbk_apifam_osx == gbo_apifam)
+ || (gbk_apifam_mac == gbo_apifam)
+ || (gbk_apifam_cco == gbo_apifam)
+ || (gbk_apifam_xwn == gbo_apifam)
+ || (gbk_apifam_9dr == gbo_apifam)
+ || (gbk_apifam_sdl == gbo_apifam)
+ || (gbk_apifam_sd2 == gbo_apifam);
+ blnr WantSCRNTRNS = WantSCRNMAPR && (cur_ScrnDpth != 0);
+
+ p("CNFGRAPI", kDepDirCnfg, kCSrcFlgmNoSource, nullpr);
+ p("CNFGGLOB", kDepDirCnfg, kCSrcFlgmNoSource, nullpr);
+ p("SYSDEPNS", kDepDirCSrc, kCSrcFlgmNoSource, nullpr);
+ p("ENDIANAC", kDepDirCSrc, kCSrcFlgmNoSource, nullpr);
+ p("MYOSGLUE", kDepDirCSrc, kCSrcFlgmNoSource, nullpr);
+
+ p("STRCNENG", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_lang_eng == gbo_lang), nullpr);
+ p("STRCNFRE", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_lang_fre == gbo_lang), nullpr);
+ p("STRCNITA", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_lang_ita == gbo_lang), nullpr);
+ p("STRCNGER", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_lang_ger == gbo_lang), nullpr);
+ p("STRCNDUT", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_lang_dut == gbo_lang), nullpr);
+ p("STRCNSPA", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_lang_spa == gbo_lang), nullpr);
+ p("STRCNPOL", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_lang_pol == gbo_lang), nullpr);
+ p("STRCNPTB", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_lang_ptb == gbo_lang), nullpr);
+ p("STRCNCAT", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_lang_cat == gbo_lang), nullpr);
+ p("STRCNCZE", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_lang_cze == gbo_lang), nullpr);
+ p("STRCNSRL", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_lang_srl == gbo_lang), nullpr);
+
+ p("STRCONST", kDepDirCnfg, kCSrcFlgmNoSource, nullpr);
+ p("INTLCHAR", kDepDirCSrc, kCSrcFlgmNoSource, nullpr);
+ p("COMOSGLU", kDepDirCSrc, kCSrcFlgmNoSource, nullpr);
+ p("BPFILTER", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(WantLocalTalk), nullpr);
+ p("ALTKEYSM", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(WantAltKeysMode), nullpr);
+ p("ACTVCODE", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(WantActvCode), nullpr);
+ p("CONTROLM", kDepDirCSrc, kCSrcFlgmNoSource, nullpr);
+ p("PBUFSTDC", kDepDirCSrc,
+ CSrcFlagsUseHdrIf((gbk_apifam_xwn == gbo_apifam)
+ || (gbk_apifam_sd2 == gbo_apifam)
+ || (gbk_apifam_9dr == gbo_apifam)
+ || (gbk_apifam_sdl == gbo_apifam)
+ ),
+ nullpr);
+ p("SCRNMAPR", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(WantSCRNMAPR), nullpr);
+ p("SCRNTRNS", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(WantSCRNTRNS), nullpr);
+ p("DATE2SEC", kDepDirCSrc, kCSrcFlgmNoSource, nullpr);
+
+ p("SGLUALSA", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_sndapi_alsa == gbo_sndapi), nullpr);
+ p("SGLUDDSP", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_sndapi_ddsp == gbo_sndapi), nullpr);
+
+ p("SOUNDGLU", kDepDirCnfg,
+ CSrcFlagsUseHdrIf(gbk_sndapi_none != gbo_sndapi), nullpr);
+
+ p("OSGLUMAC", kDepDirCSrc,
+ kCSrcFlgmUseAPI
+ | CSrcFlagsUseSrcIf(gbk_apifam_mac == gbo_apifam),
+ DoMYOSGLUEdepends);
+ p("OSGLUOSX", kDepDirCSrc,
+ kCSrcFlgmUseAPI
+ | CSrcFlagsUseSrcIf(gbk_apifam_osx == gbo_apifam),
+ DoMYOSGLUEdepends);
+ p("OSGLUWIN", kDepDirCSrc,
+ kCSrcFlgmUseAPI
+ | CSrcFlagsUseSrcIf(gbk_apifam_win == gbo_apifam),
+ DoMYOSGLUEdepends);
+ p("OSGLUXWN", kDepDirCSrc,
+ kCSrcFlgmUseAPI
+ | CSrcFlagsUseSrcIf(gbk_apifam_xwn == gbo_apifam),
+ DoMYOSGLUEdepends);
+ p("OSGLUNDS", kDepDirCSrc,
+ kCSrcFlgmUseAPI
+ | CSrcFlagsUseSrcIf(gbk_apifam_nds == gbo_apifam),
+ DoMYOSGLUEdepends);
+ p("OSGLUGTK", kDepDirCSrc,
+ kCSrcFlgmUseAPI
+ | CSrcFlagsUseSrcIf(gbk_apifam_gtk == gbo_apifam),
+ DoMYOSGLUEdepends);
+ p("OSPLAN9", kDepDirCSrc,
+ kCSrcFlgmUseAPI
+ | CSrcFlagsUseSrcIf(gbk_apifam_9dr == gbo_apifam),
+ DoMYOSGLUEdepends);
+ p("OSGLUSDL", kDepDirCSrc,
+ kCSrcFlgmUseAPI
+ | CSrcFlagsUseSrcIf(gbk_apifam_sdl == gbo_apifam),
+ DoMYOSGLUEdepends);
+ p("OSGLUSD2", kDepDirCSrc,
+ kCSrcFlgmUseAPI
+ | CSrcFlagsUseSrcIf(gbk_apifam_sd2 == gbo_apifam),
+ DoMYOSGLUEdepends);
+ p("OSGLUCCO", kDepDirCSrc,
+ kCSrcFlgmUseAPI | kCSrcFlgmOjbc
+ | CSrcFlagsUseSrcIf(gbk_apifam_cco == gbo_apifam),
+ DoMYOSGLUEdepends);
+
+ p("EMCONFIG", kDepDirCnfg, kCSrcFlgmNoSource, nullpr);
+ p("GLOBGLUE", kDepDirCSrc, kCSrcFlgmNone, nullpr);
+ p("M68KITAB", kDepDirCSrc, kCSrcFlgmNone, nullpr);
+ p("DISAM68K", kDepDirCSrc, CSrcFlagsUseIf(WantDisasm), nullpr);
+ p("FPMATHEM", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(cur_mIIorIIX),
+ nullpr);
+ p("FPCPEMDV", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(cur_mIIorIIX),
+ nullpr);
+
+ p("MINEM68K", kDepDirCSrc, kCSrcFlgmSortFirst, DoMINEM68Kdepends);
+ /*
+ Put the most speed critical part of the
+ program first, to help ensure consistent
+ alignment for it, regardless of changes
+ to rest of program.
+ Speed can depend subtly, basically
+ randomly, on how code is aligned.
+ */
+
+ p("VIAEMDEV", kDepDirCSrc, kCSrcFlgmNone, nullpr);
+ p("VIA2EMDV", kDepDirCSrc, CSrcFlagsUseIf(EmVIA2), nullpr);
+ p("IWMEMDEV", kDepDirCSrc, kCSrcFlgmNone, nullpr);
+ p("SCCEMDEV", kDepDirCSrc, kCSrcFlgmNone, nullpr);
+ p("RTCEMDEV", kDepDirCSrc, CSrcFlagsUseIf(EmRTC), nullpr);
+ p("SCRNHACK", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(NeedScrnHack), nullpr);
+ p("HPMCHACK", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(gbk_AHM_none != cur_AltHappyMac), nullpr);
+ p("ROMEMDEV", kDepDirCSrc, kCSrcFlgmNone, DoROMEMDEVdepends);
+ p("SCSIEMDV", kDepDirCSrc, kCSrcFlgmNone, nullpr);
+ p("SONYEMDV", kDepDirCSrc, kCSrcFlgmNone, nullpr);
+ p("SCRNEMDV", kDepDirCSrc, kCSrcFlgmNone, nullpr);
+ p("VIDEMDEV", kDepDirCSrc, CSrcFlagsUseIf(EmVidCard), nullpr);
+ p("MOUSEMDV", kDepDirCSrc, kCSrcFlgmNone, nullpr);
+ p("KBRDEMDV", kDepDirCSrc, CSrcFlagsUseIf(EmClassicKbrd), nullpr);
+ p("ADBSHARE", kDepDirCSrc,
+ CSrcFlagsUseHdrIf(cur_mdl >= gbk_mdl_SE), nullpr);
+ p("ADBEMDEV", kDepDirCSrc, CSrcFlagsUseIf(EmADB), nullpr);
+ p("PMUEMDEV", kDepDirCSrc, CSrcFlagsUseIf(EmPMU), nullpr);
+ p("ASCEMDEV", kDepDirCSrc, CSrcFlagsUseIf(EmASC), nullpr);
+ p("SNDEMDEV", kDepDirCSrc,
+ CSrcFlagsUseIf((! EmASC) && (gbk_mdl_PB100 != cur_mdl)
+ && MySoundEnabled),
+ nullpr);
+ p("PROGMAIN", kDepDirCSrc, kCSrcFlgmNone, nullpr);
+}
+
+/* --- list of document types --- */
+
+static void WriteRomExtensions(tWriteOneExtension p)
+{
+ p("rom");
+}
+
+static void WriteDskExtensions(tWriteOneExtension p)
+{
+ p("dsk");
+}
+
+static void DoAllDocTypes(tWriteOneDocType p)
+{
+ p("ROM", "ROM!", "Rom image", WriteRomExtensions);
+ p("DSK", "MvIm", "Disk image", WriteDskExtensions);
+}
--- /dev/null
+++ b/setup/SPOTHRCF.i
@@ -1,0 +1,903 @@
+/*
+ SPOTHRCF.i
+ Copyright (C) 2008 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ program SPecific write OTHer ConFiguration files
+*/
+
+LOCALPROC WriteAppCNFGGLOBContents(void)
+{
+ WriteCommonCNFGGLOBContents();
+
+ if (cur_mIIorIIX) {
+ Write64bitConfig();
+ }
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "/* capabilities provided by platform specific code */");
+
+ WriteBlankLineToDestFile();
+
+ WriteCompCondBool("MySoundEnabled", MySoundEnabled);
+
+ WriteAppSpecificCNFGGLOBoptions();
+}
+
+LOCALPROC WriteBldOpts(void)
+{
+ Branch = MajorVersion;
+
+ WrtOptGNSettings();
+ WrtOptSPSettings();
+}
+
+LOCALPROC WriteAppCNFGRAPIContents(void)
+{
+ WriteCommonCNFGRAPIContents();
+
+ WriteAppSpecificCNFGRAPIoptions();
+
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define kBldOpts \"");
+ WriteBldOpts();
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteOneWire(char *a, char *b)
+{
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("\tWire_");
+ WriteCStrToDestFile(a);
+ WriteCStrToDestFile("_");
+ WriteCStrToDestFile(b);
+ WriteCStrToDestFile(",");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define ");
+ WriteCStrToDestFile(b);
+ WriteCStrToDestFile(" (Wires[Wire_");
+ WriteCStrToDestFile(a);
+ WriteCStrToDestFile("_");
+ WriteCStrToDestFile(b);
+ WriteCStrToDestFile("])");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define ");
+ WriteCStrToDestFile(a);
+ WriteCStrToDestFile(" (Wires[Wire_");
+ WriteCStrToDestFile(a);
+ WriteCStrToDestFile("_");
+ WriteCStrToDestFile(b);
+ WriteCStrToDestFile("])");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteConfigureWires(void)
+{
+ WriteDestFileLn(
+ "/* the Wire variables are 1/0, not true/false */");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("enum {");
+ if (cur_mIIorIIX) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_unknown_SoundDisable,");
+ WriteDestFileLn(
+ "#define SoundDisable (Wires[Wire_unknown_SoundDisable])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_unknown_SoundVolb0,");
+ WriteDestFileLn(
+ "#define SoundVolb0 (Wires[Wire_unknown_SoundVolb0])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_unknown_SoundVolb1,");
+ WriteDestFileLn(
+ "#define SoundVolb1 (Wires[Wire_unknown_SoundVolb1])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_unknown_SoundVolb2,");
+ WriteDestFileLn(
+ "#define SoundVolb2 (Wires[Wire_unknown_SoundVolb2])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iA0_unknown,");
+ WriteDestFileLn(
+ "#define VIA1_iA0 (Wires[Wire_VIA1_iA0_unknown])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iA1_unknown,");
+ WriteDestFileLn(
+ "#define VIA1_iA1 (Wires[Wire_VIA1_iA1_unknown])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iA2_unknown,");
+ WriteDestFileLn(
+ "#define VIA1_iA2 (Wires[Wire_VIA1_iA2_unknown])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "\tWire_VIA1_iB7_unknown,"
+ " /* for compatibility with SoundDisable */");
+ WriteDestFileLn(
+ "#define VIA1_iB7 (Wires[Wire_VIA1_iB7_unknown])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA2_InterruptRequest,");
+ WriteDestFileLn(
+ "#define VIA2_InterruptRequest"
+ " (Wires[Wire_VIA2_InterruptRequest])");
+ WriteDestFileLn(
+ "#define VIA2_interruptChngNtfy VIAorSCCinterruptChngNtfy");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA2_iA7_unknown,");
+ WriteDestFileLn(
+ "#define VIA2_iA7 (Wires[Wire_VIA2_iA7_unknown])");
+ WriteDestFileLn(
+ "#define VIA2_iA7_ChangeNtfy Addr32_ChangeNtfy");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA2_iA6_unknown,");
+ WriteDestFileLn(
+ "#define VIA2_iA6 (Wires[Wire_VIA2_iA6_unknown])");
+ WriteDestFileLn(
+ "#define VIA2_iA6_ChangeNtfy Addr32_ChangeNtfy");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA2_iB7_unknown,");
+ WriteDestFileLn(
+ "#define VIA2_iB7 (Wires[Wire_VIA2_iB7_unknown])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA2_iCB2_unknown,");
+ WriteDestFileLn(
+ "#define VIA2_iCB2 (Wires[Wire_VIA2_iCB2_unknown])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA2_iB2_PowerOff,");
+ WriteDestFileLn(
+ "#define VIA2_iB2 (Wires[Wire_VIA2_iB2_PowerOff])");
+ WriteDestFileLn(
+ "#define VIA2_iB2_ChangeNtfy PowerOff_ChangeNtfy");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA2_iB3_Addr32,");
+ WriteDestFileLn(
+ "#define VIA2_iB3 (Wires[Wire_VIA2_iB3_Addr32])");
+ WriteDestFileLn(
+ "#define Addr32 (Wires[Wire_VIA2_iB3_Addr32])");
+ WriteDestFileLn(
+ "#define VIA2_iB3_ChangeNtfy Addr32_ChangeNtfy");
+ }
+
+ if (cur_mdl <= gbk_mdl_Classic) {
+ WriteOneWire("VIA1_iA0", "SoundVolb0");
+ WriteOneWire("VIA1_iA1", "SoundVolb1");
+ WriteOneWire("VIA1_iA2", "SoundVolb2");
+ }
+
+ if ((cur_mdl <= gbk_mdl_Plus) || cur_mIIorIIX)
+ {
+ WriteOneWire("VIA1_iA4", "MemOverlay");
+ WriteDestFileLn(
+ "#define VIA1_iA4_ChangeNtfy MemOverlay_ChangeNtfy");
+ } else {
+ if (cur_mdl <= gbk_mdl_Classic) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iA4_DriveSel,");
+ WriteDestFileLn(
+ "#define VIA1_iA4 (Wires[Wire_VIA1_iA4_DriveSel])");
+ }
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_MemOverlay,");
+ WriteDestFileLn("#define MemOverlay (Wires[Wire_MemOverlay])");
+ }
+
+ if (cur_mdl <= gbk_mdl_Classic) {
+ WriteOneWire("VIA1_iA6", "SCRNvPage2");
+ }
+
+ if (gbk_mdl_PB100 == cur_mdl) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_SCCwaitrq,");
+ WriteDestFileLn("#define SCCwaitrq (Wires[Wire_SCCwaitrq])");
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iA0_PmuBus0,");
+ WriteDestFileLn("\tWire_VIA1_iA1_PmuBus1,");
+ WriteDestFileLn("\tWire_VIA1_iA2_PmuBus2,");
+ WriteDestFileLn("\tWire_VIA1_iA3_PmuBus3,");
+ WriteDestFileLn("\tWire_VIA1_iA4_PmuBus4,");
+ WriteDestFileLn("\tWire_VIA1_iA5_PmuBus5,");
+ WriteDestFileLn("\tWire_VIA1_iA6_PmuBus6,");
+ WriteDestFileLn("\tWire_VIA1_iA7_PmuBus7,");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "#define VIA1_iA0 (Wires[Wire_VIA1_iA0_PmuBus0])");
+ WriteDestFileLn(
+ "#define VIA1_iA1 (Wires[Wire_VIA1_iA1_PmuBus1])");
+ WriteDestFileLn(
+ "#define VIA1_iA2 (Wires[Wire_VIA1_iA2_PmuBus2])");
+ WriteDestFileLn(
+ "#define VIA1_iA3 (Wires[Wire_VIA1_iA3_PmuBus3])");
+ WriteDestFileLn(
+ "#define VIA1_iA4 (Wires[Wire_VIA1_iA4_PmuBus4])");
+ WriteDestFileLn(
+ "#define VIA1_iA5 (Wires[Wire_VIA1_iA5_PmuBus5])");
+ WriteDestFileLn(
+ "#define VIA1_iA6 (Wires[Wire_VIA1_iA6_PmuBus6])");
+ WriteDestFileLn(
+ "#define VIA1_iA7 (Wires[Wire_VIA1_iA7_PmuBus7])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iB0_PmuToReady,");
+ WriteDestFileLn(
+ "#define VIA1_iB0 (Wires[Wire_VIA1_iB0_PmuToReady])");
+ WriteDestFileLn(
+ "#define PmuToReady (Wires[Wire_VIA1_iB0_PmuToReady])");
+ WriteDestFileLn(
+ "#define VIA1_iB0_ChangeNtfy PmuToReady_ChangeNtfy");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iB1_PmuFromReady,");
+ WriteDestFileLn(
+ "#define VIA1_iB1 (Wires[Wire_VIA1_iB1_PmuFromReady])");
+ WriteDestFileLn(
+ "#define PmuFromReady (Wires[Wire_VIA1_iB1_PmuFromReady])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iB2_Unknown,");
+ WriteDestFileLn(
+ "#define VIA1_iB2 (Wires[Wire_VIA1_iB2_Unknown])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iB3_Unknown,");
+ WriteDestFileLn(
+ "#define VIA1_iB3 (Wires[Wire_VIA1_iB3_Unknown])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iB4_Unknown,");
+ WriteDestFileLn(
+ "#define VIA1_iB4 (Wires[Wire_VIA1_iB4_Unknown])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iB5_Unknown,");
+ WriteDestFileLn(
+ "#define VIA1_iB5 (Wires[Wire_VIA1_iB5_Unknown])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iB6_Unknown,");
+ WriteDestFileLn(
+ "#define VIA1_iB6 (Wires[Wire_VIA1_iB6_Unknown])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iB7_Unknown,");
+ WriteDestFileLn(
+ "#define VIA1_iB7 (Wires[Wire_VIA1_iB7_Unknown])");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iCB2_Unknown,");
+ WriteDestFileLn(
+ "#define VIA1_iCB2 (Wires[Wire_VIA1_iCB2_Unknown])");
+ } else {
+ WriteOneWire("VIA1_iA5", "IWMvSel");
+
+ WriteOneWire("VIA1_iA7", "SCCwaitrq");
+
+ WriteOneWire("VIA1_iB0", "RTCdataLine");
+ WriteDestFileLn(
+ "#define VIA1_iB0_ChangeNtfy RTCdataLine_ChangeNtfy");
+
+ WriteOneWire("VIA1_iB1", "RTCclock");
+ WriteDestFileLn(
+ "#define VIA1_iB1_ChangeNtfy RTCclock_ChangeNtfy");
+
+ WriteOneWire("VIA1_iB2", "RTCunEnabled");
+ WriteDestFileLn(
+ "#define VIA1_iB2_ChangeNtfy RTCunEnabled_ChangeNtfy");
+
+ if (cur_mdl <= gbk_mdl_Plus) {
+ WriteOneWire("VIA1_iA3", "SoundBuffer");
+ WriteOneWire("VIA1_iB3", "MouseBtnUp");
+ WriteOneWire("VIA1_iB4", "MouseX2");
+ WriteOneWire("VIA1_iB5", "MouseY2");
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iCB2_KybdDat,");
+ WriteDestFileLn(
+ "#define VIA1_iCB2 (Wires[Wire_VIA1_iCB2_KybdDat])");
+ WriteDestFileLn(
+ "#define VIA1_iCB2_ChangeNtfy Kybd_DataLineChngNtfy");
+ } else {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iA3_SCCvSync,");
+ WriteDestFileLn(
+ "#define VIA1_iA3 (Wires[Wire_VIA1_iA3_SCCvSync])");
+
+ WriteOneWire("VIA1_iB3", "ADB_Int");
+
+ WriteOneWire("VIA1_iB4", "ADB_st0");
+ WriteDestFileLn(
+ "#define VIA1_iB4_ChangeNtfy ADBstate_ChangeNtfy");
+
+ WriteOneWire("VIA1_iB5", "ADB_st1");
+ WriteDestFileLn(
+ "#define VIA1_iB5_ChangeNtfy ADBstate_ChangeNtfy");
+
+ WriteOneWire("VIA1_iCB2", "ADB_Data");
+ WriteDestFileLn(
+ "#define VIA1_iCB2_ChangeNtfy ADB_DataLineChngNtfy");
+ }
+ }
+
+ if (cur_mdl <= gbk_mdl_Plus) {
+ WriteOneWire("VIA1_iB6", "SCRNbeamInVid");
+ } else if (cur_mdl <= gbk_mdl_Classic) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_iB6_SCSIintenable,");
+ WriteDestFileLn(
+ "#define VIA1_iB6 (Wires[Wire_VIA1_iB6_SCSIintenable])");
+ }
+
+ if (cur_mdl <= gbk_mdl_Classic) {
+ WriteOneWire("VIA1_iB7", "SoundDisable");
+ }
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VIA1_InterruptRequest,");
+ WriteDestFileLn(
+ "#define VIA1_InterruptRequest"
+ " (Wires[Wire_VIA1_InterruptRequest])");
+ WriteDestFileLn(
+ "#define VIA1_interruptChngNtfy VIAorSCCinterruptChngNtfy");
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_SCCInterruptRequest,");
+ WriteDestFileLn(
+ "#define SCCInterruptRequest"
+ " (Wires[Wire_SCCInterruptRequest])");
+ WriteDestFileLn(
+ "#define SCCinterruptChngNtfy VIAorSCCinterruptChngNtfy");
+
+ if (cur_mdl <= gbk_mdl_Plus) {
+ } else {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_ADBMouseDisabled,");
+ WriteDestFileLn(
+ "#define ADBMouseDisabled (Wires[Wire_ADBMouseDisabled])");
+ }
+
+ if (cur_mIIorIIX) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VBLinterrupt,");
+ WriteDestFileLn(
+ "#define Vid_VBLinterrupt (Wires[Wire_VBLinterrupt])");
+ WriteDestFileLn("#define VIA2_iA0 (Wires[Wire_VBLinterrupt])");
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tWire_VBLintunenbl,");
+ WriteDestFileLn(
+ "#define Vid_VBLintunenbl (Wires[Wire_VBLintunenbl])");
+ }
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("\tkNumWires");
+ WriteDestFileLn("};");
+}
+
+LOCALPROC WriteConfigureVIA1(void)
+{
+ WriteDestFileLn("/* VIA configuration */");
+
+ if (gbk_mdl_Classic == cur_mdl) {
+ WriteDestFileLn("#define VIA1_ORA_FloatVal 0xF7");
+ } else if (cur_mIIorIIX) {
+ WriteDestFileLn("#define VIA1_ORA_FloatVal 0xBF");
+ WriteDestFileLn(
+ "\t/* bit 6 used to check version of hardware */");
+ } else {
+ WriteDestFileLn("#define VIA1_ORA_FloatVal 0xFF");
+ }
+
+ WriteDestFileLn("#define VIA1_ORB_FloatVal 0xFF");
+
+ if (cur_mdl <= gbk_mdl_Classic) {
+ WriteDestFileLn("#define VIA1_ORA_CanIn 0x80");
+ WriteDestFileLn("#define VIA1_ORA_CanOut 0x7F");
+ } else if (gbk_mdl_PB100 == cur_mdl) {
+ WriteDestFileLn("#define VIA1_ORA_CanIn 0xFF");
+ WriteDestFileLn("#define VIA1_ORA_CanOut 0xFF");
+ } else if (cur_mIIorIIX) {
+ WriteDestFileLn("#define VIA1_ORA_CanIn 0x80");
+ WriteDestFileLn("#define VIA1_ORA_CanOut 0x3F");
+ } else {
+ WriteDestFileLn("#define VIA1_ORA_CanIn 0x00");
+ WriteDestFileLn("#define VIA1_ORA_CanOut 0x00");
+ }
+
+ if (cur_mdl <= gbk_mdl_Plus) {
+ WriteDestFileLn("#define VIA1_ORB_CanIn 0x79");
+ WriteDestFileLn("#define VIA1_ORB_CanOut 0x87");
+ } else if (cur_mdl <= gbk_mdl_Classic) {
+ WriteDestFileLn("#define VIA1_ORB_CanIn 0x09");
+ WriteDestFileLn("#define VIA1_ORB_CanOut 0xF7");
+ } else if (gbk_mdl_PB100 == cur_mdl) {
+ WriteDestFileLn("#define VIA1_ORB_CanIn 0x02");
+ WriteDestFileLn("#define VIA1_ORB_CanOut 0xFD");
+ } else if (cur_mIIorIIX) {
+ WriteDestFileLn("#define VIA1_ORB_CanIn 0x09");
+ WriteDestFileLn("#define VIA1_ORB_CanOut 0xB7");
+ } else {
+ WriteDestFileLn("#define VIA1_ORB_CanIn 0x00");
+ WriteDestFileLn("#define VIA1_ORB_CanOut 0x00");
+ }
+
+ if (cur_mdl <= gbk_mdl_Plus) {
+ WriteDestFileLn("#define VIA1_IER_Never0 (1 << 1)");
+ WriteDestFileLn(
+ "#define VIA1_IER_Never1 ((1 << 3) | (1 << 4))");
+ } else if (cur_mdl <= gbk_mdl_Classic) {
+ WriteDestFileLn("#define VIA1_IER_Never0 0x00");
+ WriteDestFileLn(
+ "#define VIA1_IER_Never1 ((1 << 3) | (1 << 4))");
+ } else if (gbk_mdl_PB100 == cur_mdl) {
+ WriteDestFileLn("#define VIA1_IER_Never0 0x00");
+ WriteDestFileLn("#define VIA1_IER_Never1 0x0C");
+ } else if (cur_mIIorIIX) {
+ WriteDestFileLn("#define VIA1_IER_Never0 0x00");
+ WriteDestFileLn("#define VIA1_IER_Never1 0x58");
+ } else {
+ WriteDestFileLn("#define VIA1_IER_Never0 0xFF");
+ WriteDestFileLn("#define VIA1_IER_Never1 0xFF");
+ }
+
+ if (gbk_mdl_PB100 == cur_mdl) {
+ WriteDestFileLn("#define VIA1_CB2modesAllowed 0x03");
+ WriteDestFileLn("#define VIA1_CA2modesAllowed 0x03");
+ } else {
+ WriteDestFileLn("#define VIA1_CB2modesAllowed 0x01");
+ WriteDestFileLn("#define VIA1_CA2modesAllowed 0x01");
+ }
+}
+
+LOCALPROC WriteConfigureVIA2(void)
+{
+ WriteDestFileLn("/* VIA 2 configuration */");
+
+ WriteDestFileLn("#define VIA2_ORA_FloatVal 0xFF");
+ WriteDestFileLn("#define VIA2_ORB_FloatVal 0xFF");
+
+ if (cur_mIIorIIX) {
+ WriteDestFileLn("#define VIA2_ORA_CanIn 0x01");
+ WriteDestFileLn("#define VIA2_ORA_CanOut 0xC0");
+ } else {
+ WriteDestFileLn("#define VIA2_ORA_CanIn 0x00");
+ WriteDestFileLn("#define VIA2_ORA_CanOut 0x00");
+ }
+
+ if (cur_mIIorIIX) {
+ WriteDestFileLn("#define VIA2_ORB_CanIn 0x00");
+ WriteDestFileLn("#define VIA2_ORB_CanOut 0x8C");
+ } else {
+ WriteDestFileLn("#define VIA2_ORB_CanIn 0x00");
+ WriteDestFileLn("#define VIA2_ORB_CanOut 0x00");
+ }
+
+ if (cur_mIIorIIX) {
+ WriteDestFileLn("#define VIA2_IER_Never0 0x00");
+ WriteDestFileLn("#define VIA2_IER_Never1 0xED");
+ } else {
+ WriteDestFileLn("#define VIA2_IER_Never0 0xFF");
+ WriteDestFileLn("#define VIA2_IER_Never1 0xFF");
+ }
+
+ WriteDestFileLn("#define VIA2_CB2modesAllowed 0x01");
+ WriteDestFileLn("#define VIA2_CA2modesAllowed 0x01");
+}
+
+LOCALPROC WriteAppSTRCONSTcontents(void)
+{
+ char *s;
+
+ switch (gbo_lang) {
+ case gbk_lang_eng:
+ s = "ENG";
+ break;
+ case gbk_lang_fre:
+ s = "FRE";
+ break;
+ case gbk_lang_ita:
+ s = "ITA";
+ break;
+ case gbk_lang_ger:
+ s = "GER";
+ break;
+ case gbk_lang_dut:
+ s = "DUT";
+ break;
+ case gbk_lang_spa:
+ s = "SPA";
+ break;
+ case gbk_lang_pol:
+ s = "POL";
+ break;
+ case gbk_lang_ptb:
+ s = "PTB";
+ break;
+ case gbk_lang_cat:
+ s = "CAT";
+ break;
+ case gbk_lang_cze:
+ s = "CZE";
+ break;
+ case gbk_lang_srl:
+ s = "SRL";
+ break;
+ default:
+ s = "???";
+ break;
+ }
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#include ");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("STRCN");
+ WriteCStrToDestFile(s);
+ WriteCStrToDestFile(".h");
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteAppSOUNDGLUcontents(void)
+{
+ char *s;
+
+ switch (gbo_sndapi) {
+ case gbk_sndapi_alsa:
+ s = "ALSA";
+ break;
+ case gbk_sndapi_ddsp:
+ s = "DDSP";
+ break;
+ default:
+ s = "???";
+ break;
+ }
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#include ");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("SGLU");
+ WriteCStrToDestFile(s);
+ WriteCStrToDestFile(".h");
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteAppEMCONFIGcontents(void)
+{
+ WriteDestFileLn("/*");
+ ++DestFileIndent;
+ WriteDestFileLn(
+ "Configuration options used by platform independent code.");
+ WriteConfigurationWarning();
+ --DestFileIndent;
+ WriteDestFileLn("*/");
+
+ WriteBlankLineToDestFile();
+
+ WriteCompCondBool("EmClassicKbrd", EmClassicKbrd);
+ WriteCompCondBool("EmADB", EmADB);
+ WriteCompCondBool("EmRTC", EmRTC);
+ WriteCompCondBool("EmPMU", EmPMU);
+ WriteCompCondBool("EmVIA2", EmVIA2);
+ WriteCompCondBool("Use68020", em_cpu_vers >= 2);
+ WriteCompCondBool("EmFPU",
+ cur_mIIorIIX);
+ WriteCompCondBool("EmMMU", falseblnr);
+ WriteCompCondBool("EmASC", EmASC);
+
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define CurEmMd kEmMd_");
+ WriteCStrToDestFile(GetModelName(cur_mdl));
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define kMyClockMult ");
+ if (cur_mIIorIIX) {
+ WriteCStrToDestFile("2");
+ } else {
+ WriteCStrToDestFile("1");
+ }
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ WriteCompCondBool("WantCycByPriOp", timingacc != 0);
+ WriteCompCondBool("WantCloserCyc", timingacc >= 2);
+
+ if (gbk_ide_mvc == cur_ide) {
+ if (gbk_cpufam_x64 == gbo_cpufam) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("#define r_pc_p \"r15\"");
+ WriteDestFileLn("#define r_MaxCyclesToGo \"r14\"");
+ WriteDestFileLn("#define r_pc_pHi \"r13\"");
+ }
+
+ if (gbk_cpufam_ppc == gbo_cpufam) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("#define r_regs \"r14\"");
+ WriteDestFileLn("#define r_pc_p \"r15\"");
+ WriteDestFileLn("#define r_MaxCyclesToGo \"r16\"");
+ WriteDestFileLn("#define r_pc_pHi \"r17\"");
+ }
+
+ if (gbk_cpufam_arm == gbo_cpufam) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("#define r_regs \"r4\"");
+ WriteDestFileLn("#define r_pc_p \"r5\"");
+ if (gbk_targ_wcar != cur_targ) {
+ WriteDestFileLn("#define r_MaxCyclesToGo \"r6\"");
+ WriteDestFileLn("#define r_pc_pHi \"r7\"");
+ }
+ }
+ }
+
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define kRAMa_Size ");
+ WriteCStrToDestFile("0x");
+ WriteHexLongToOutput(1 << RAMa_Size);
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define kRAMb_Size ");
+ if (0 == RAMb_Size) {
+ WriteCStrToDestFile("0");
+ } else {
+ WriteCStrToDestFile("0x");
+ WriteHexLongToOutput(1 << RAMb_Size);
+ }
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+
+ if (NeedScrnHack) {
+ WriteCompCondBool("UseLargeScreenHack", NeedScrnHack);
+ }
+ WriteCompCondBool("IncludeVidMem", NeedVidMem);
+ if (NeedVidMem) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define kVidMemRAM_Size ");
+ WriteCStrToDestFile("0x");
+ WriteHexLongToOutput(VidMemSize);
+ WriteEndDestFileLn();
+ }
+
+ WriteBlankLineToDestFile();
+
+ WriteCompCondBool("EmVidCard", EmVidCard);
+ if (EmVidCard) {
+ WriteDestFileLn("#define kVidROM_Size 0x000800");
+ }
+
+ WriteBlankLineToDestFile();
+
+ if (cur_mIIorIIX) {
+ WriteDestFileLn("#define MaxATTListN 20");
+ } else {
+ WriteDestFileLn("#define MaxATTListN 16");
+ }
+
+ WriteCompCondBool("IncludeExtnPbufs",
+ (! WantMinExtn) && (gbk_apifam_gtk != gbo_apifam)
+ && (gbk_apifam_nds != gbo_apifam));
+ WriteCompCondBool("IncludeExtnHostTextClipExchange",
+ (! WantMinExtn) && (gbk_apifam_gtk != gbo_apifam)
+ && (gbk_apifam_sdl != gbo_apifam)
+ && (gbk_apifam_nds != gbo_apifam));
+
+ WriteBlankLineToDestFile();
+
+ WriteCompCondBool("Sony_SupportDC42", SonySupportDC42);
+ WriteCompCondBool("Sony_SupportTags", SonySupportTags);
+ WriteCompCondBool("Sony_WantChecksumsUpdated",
+ SonyWantChecksumsUpdated);
+ WriteDestFileLn("#define Sony_VerifyChecksums 0");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define CaretBlinkTime 0x");
+ WriteHexByteToOutput(cur_CaretBlinkTime);
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define SpeakerVol 0x");
+ WriteHexByteToOutput(cur_SpeakerVol);
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define DoubleClickTime 0x");
+ WriteHexByteToOutput(cur_DoubleClickTime);
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define MenuBlink 0x");
+ WriteHexByteToOutput(cur_MenuBlink);
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define AutoKeyThresh 0x");
+ WriteHexByteToOutput(cur_AutoKeyThresh);
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define AutoKeyRate 0x");
+ WriteHexByteToOutput(cur_AutoKeyRate);
+ WriteEndDestFileLn();
+
+ if (cur_mIIorIIX) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define pr_HilColRed 0x");
+ WriteHexWordToOutput(cur_HilColRed);
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define pr_HilColGreen 0x");
+ WriteHexWordToOutput(cur_HilColGreen);
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define pr_HilColBlue 0x");
+ WriteHexWordToOutput(cur_HilColBlue);
+ WriteEndDestFileLn();
+ }
+
+ if (! WantAutoLocation) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define CurMacLatitude 0x");
+ WriteHexLongToOutput(cur_InitLatitude);
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define CurMacLongitude 0x");
+ WriteHexLongToOutput(cur_InitLongitude);
+ WriteEndDestFileLn();
+ }
+ if (! WantAutoTimeZone) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define CurMacDelta 0x");
+ WriteHexLongToOutput(((WantTzDST ? 1UL : 0) << 31)
+ | (((ui5r)cur_TzDeltS) & 0x00FFFFFF));
+ WriteEndDestFileLn();
+ }
+
+ WriteBlankLineToDestFile();
+ WriteBlankLineToDestFile();
+
+ WriteConfigureWires();
+
+ WriteBlankLineToDestFile();
+
+
+
+ WriteBlankLineToDestFile();
+
+ WriteConfigureVIA1();
+
+
+ if (EmVIA2) {
+ WriteBlankLineToDestFile();
+ WriteConfigureVIA2();
+ }
+
+ WriteBlankLineToDestFile();
+ if (cur_mdl <= gbk_mdl_Plus) {
+ WriteDestFileLn("#define Mouse_Enabled SCC_InterruptsEnabled");
+ } else {
+ WriteDestFileLn("#define Mouse_Enabled() (! ADBMouseDisabled)");
+ }
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "#define VIA1_iCA1_PulseNtfy VIA1_iCA1_Sixtieth_PulseNtfy");
+ WriteDestFileLn(
+ "#define Sixtieth_PulseNtfy VIA1_iCA1_Sixtieth_PulseNtfy");
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "#define VIA1_iCA2_PulseNtfy"
+ " VIA1_iCA2_RTC_OneSecond_PulseNtfy");
+ WriteDestFileLn(
+ "#define RTC_OneSecond_PulseNtfy"
+ " VIA1_iCA2_RTC_OneSecond_PulseNtfy");
+
+ if (cur_mIIorIIX) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "#define VIA2_iCA1_PulseNtfy"
+ " VIA2_iCA1_Vid_VBLinterrupt_PulseNtfy");
+ WriteDestFileLn(
+ "#define Vid_VBLinterrupt_PulseNotify"
+ " VIA2_iCA1_Vid_VBLinterrupt_PulseNtfy");
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "#define VIA2_iCB1_PulseNtfy"
+ " VIA2_iCB1_ASC_interrupt_PulseNtfy");
+ WriteDestFileLn(
+ "#define ASC_interrupt_PulseNtfy"
+ " VIA2_iCB1_ASC_interrupt_PulseNtfy");
+ }
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("#define GetSoundInvertTime VIA1_GetT1InvertTime");
+
+ if (EmClassicKbrd) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("#define KYBD_ShiftInData VIA1_ShiftOutData");
+ WriteDestFileLn("#define KYBD_ShiftOutData VIA1_ShiftInData");
+ }
+ if (EmADB) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("#define ADB_ShiftInData VIA1_ShiftOutData");
+ WriteDestFileLn("#define ADB_ShiftOutData VIA1_ShiftInData");
+ }
+
+ if (! WantDisableRomCheck) {
+ WriteCompCondBool("DisableRomCheck", WantDisableRomCheck);
+ }
+ if (! WantDisableRamTest) {
+ WriteCompCondBool("DisableRamTest", WantDisableRamTest);
+ }
+
+ if (gbk_AHM_none != cur_AltHappyMac) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define CurAltHappyMac kAHM_");
+ WriteCStrToDestFile(GetAltHappyMacName(cur_AltHappyMac));
+ WriteEndDestFileLn();
+ }
+
+ WriteBlankLineToDestFile();
+ if (cur_mIIorIIX) {
+ WriteDestFileLn("#define kExtn_Block_Base 0x50F0C000");
+ } else {
+ WriteDestFileLn("#define kExtn_Block_Base 0x00F40000");
+ }
+ WriteDestFileLn("#define kExtn_ln2Spc 5");
+
+ WriteBlankLineToDestFile();
+ if (gbk_mdl_PB100 == cur_mdl) {
+ WriteDestFileLn("#define kROM_Base 0x00900000");
+ } else if (cur_mIIorIIX) {
+ WriteDestFileLn("#define kROM_Base 0x00800000");
+ } else {
+ WriteDestFileLn("#define kROM_Base 0x00400000");
+ }
+ WriteDestFileLn("#define kROM_ln2Spc 20");
+
+ WriteBlankLineToDestFile();
+ WriteCompCondBool("WantDisasm", WantDisasm);
+ WriteCompCondBool("ExtraAbnormalReports", falseblnr);
+}
+
+LOCALPROC WriteAppSpecificConfigFiles(void)
+{
+ WriteADstFile1("my_config_d",
+ "CNFGGLOB", ".h", "C Configuration file",
+ WriteAppCNFGGLOBContents);
+ WriteADstFile1("my_config_d",
+ "CNFGRAPI", ".h", "C API Configuration file",
+ WriteAppCNFGRAPIContents);
+ WriteADstFile1("my_config_d",
+ "EMCONFIG", ".h", "C Platform Independent Configuration file",
+ WriteAppEMCONFIGcontents);
+ WriteADstFile1("my_config_d",
+ "STRCONST", ".h", "Language Configuration file",
+ WriteAppSTRCONSTcontents);
+
+ if (gbk_sndapi_none != gbo_sndapi) {
+ WriteADstFile1("my_config_d",
+ "SOUNDGLU", ".h", "Sound Configuration file",
+ WriteAppSOUNDGLUcontents);
+ }
+}
--- /dev/null
+++ b/setup/STRUTILS.i
@@ -1,0 +1,277 @@
+/*
+ STRUTILS.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ STRing UTILitieS
+
+ Some very basic string macros and routines.
+*/
+
+
+#define PStrLength(s) (*(s))
+#define PStrToMyCharPtr(s) ((s) + 1)
+
+#define PStrMaxLength 255
+
+#define SizeOfListMyChar(n) (n)
+#define PStrToPtr(s) ((MyPtr)PStrToMyCharPtr(s))
+#define PStrToSize(s) (SizeOfListMyChar(PStrLength(s)))
+#define PStrToTotSize(s) (SizeOfListMyChar(PStrLength(s) + 1))
+ /* + 1 for length byte */
+
+#define PStrClear(s) PStrLength(s) = 0
+
+GLOBALPROC PStrCopy(ps3p r, ps3p s)
+{
+ MyMoveBytes((MyPtr)s, (MyPtr)r, PStrToTotSize(s));
+}
+
+GLOBALPROC PStrApndChar(ps3p s, MyCharR x)
+{
+ si4r n = s[0] + 1;
+
+ if (n <= PStrMaxLength) {
+ s[0] = (MyCharR)n;
+ s[n] = x;
+ }
+}
+
+GLOBALPROC PStrPrependChar(ps3p s, MyCharR x)
+{
+ ps3p p = s;
+ si4r n0 = *p++;
+ si4r n = n0 + 1;
+
+ if (n <= PStrMaxLength) {
+ MyMoveBytes((MyPtr)p, (MyPtr)(p + 1), SizeOfListMyChar(n0));
+ s[1] = x;
+ s[0] = (MyCharR)n;
+ }
+}
+
+GLOBALPROC PStrAppend(ps3p r, ps3p s)
+{
+ ps3p p = s;
+ ps3p q = r;
+ si4r m = *p++;
+ si4r n = *q++;
+
+ if (n + m > PStrMaxLength) {
+ m = PStrMaxLength - n;
+ }
+
+ *r = (MyCharR)(n + m);
+ MyMoveBytes((MyPtr)p, (MyPtr)(q + n), m);
+}
+
+GLOBALFUNC uimr CStrLength(char *s)
+{
+ char *p = s;
+
+ while (0 != *p++) {
+ }
+ return p - s - 1;
+}
+
+GLOBALPROC PStrFromCStr(ps3p r, /* CONST */ char *s)
+{
+ uimr L;
+
+ L = CStrLength(s);
+ if (L > PStrMaxLength) {
+ L = PStrMaxLength;
+ }
+ *r++ = (MyCharR)L;
+ MyMoveBytes((MyPtr)s, (MyPtr)r, L);
+}
+
+GLOBALPROC PStrFromChar(ps3p r, char x)
+{
+ r[0] = 1;
+ r[1] = x;
+}
+
+GLOBALPROC PStrFromPtr(MyPtr p, uimr L, ps3p s)
+{
+ uimr tL;
+
+ if (L <= PStrMaxLength) {
+ tL = L;
+ } else {
+ tL = PStrMaxLength;
+ }
+ s[0] = (MyCharR)tL;
+ MyMoveBytes(p, PStrToPtr(s), SizeOfListMyChar(tL));
+}
+
+GLOBALPROC PStrApndCStr(ps3p r, /* CONST */ char *s)
+{
+ MyPStr t;
+
+ PStrFromCStr(t, s);
+ PStrAppend(r, t);
+}
+
+GLOBALFUNC blnr PStrEq(ps3p s1, ps3p s2)
+{
+ register si4r i;
+ MyCharPtr p1 = s1;
+ MyCharPtr p2 = s2;
+ MyCharR n = *p1++;
+ MyCharR m = *p2++;
+
+ if (n != m) {
+ return falseblnr;
+ } else {
+ for (i = n; --i >= 0; ) {
+ if (*p1++ != *p2++) {
+ return falseblnr;
+ }
+ }
+ return trueblnr;
+ }
+}
+
+GLOBALFUNC blnr CStrEq(char *s1, char *s2)
+{
+ MyCharR c1;
+
+ while ((c1 = *s1++) == *s2++) {
+ if (0 == c1) {
+ return trueblnr;
+ }
+ }
+ return falseblnr;
+}
+
+GLOBALPROC CStrFromPtr(MyPtr p, uimr L, char *s)
+{
+ MyMoveBytes(p, (MyPtr)s, SizeOfListMyChar(L));
+ s[L] = (MyCharR)0;
+}
+
+GLOBALPROC CStrFromPStr(ps3p x, char *s)
+{
+ CStrFromPtr(PStrToMyCharPtr(x), PStrLength(x), s);
+}
+
+GLOBALPROC CStrCopy(char *r, char *s)
+{
+ while (0 != (*r++ = *s++)) {
+ }
+}
+
+LOCALPROC ReversePStr(ps3p s)
+{
+ MyCharR c;
+ MyCharR *p1 = PStrToMyCharPtr(s);
+ MyCharR *p2 = p1 + PStrLength(s) - 1;
+
+ while (p1 < p2) {
+ c = *p1;
+ *p1 = *p2;
+ *p2 = c;
+ ++p1;
+ --p2;
+ }
+}
+
+LOCALPROC PStrFromUimr(uimr v, ps3p s)
+{
+ MyCharR *p = PStrToMyCharPtr(s);
+ uimr newv;
+
+ do {
+ newv = v / (uimr)10;
+ *p++ = '0' + (v - newv * 10);
+ v = newv;
+ } while (v != 0);
+ s[0] = p - PStrToMyCharPtr(s);
+
+ ReversePStr(s);
+}
+
+LOCALFUNC uimr MyCharPtrToUimr(MyCharPtr p, MyCharR n)
+{
+ register si4r i;
+ uimr v = 0;
+
+ for (i = n; --i >= 0; ) {
+ v = (v * 10) + (*p++ - '0');
+ }
+
+ return v;
+}
+
+LOCALFUNC uimr PStrToUimr(ps3p s)
+{
+ MyCharPtr p = s;
+ MyCharR n = *p++;
+
+ return MyCharPtrToUimr(p, n);
+}
+
+LOCALFUNC simr PStrToSimr(ps3p s)
+{
+ simr v;
+ MyCharPtr p = s;
+ MyCharR n = *p++;
+
+ if (0 == n) {
+ v = 0;
+ } else if ('-' == p[0]) {
+ v = - MyCharPtrToUimr(++p, --n);
+ } else {
+ v = MyCharPtrToUimr(p, n);
+ }
+
+ return v;
+}
+
+LOCALPROC PStrFromSimr(simr v, ps3p s)
+{
+ if (v < 0) {
+ PStrFromUimr(- v, s);
+ PStrPrependChar(s, '-');
+ } else {
+ PStrFromUimr(v, s);
+ }
+}
+
+LOCALPROC PStrFromNUimr(uimr v, ui3r n, ps3p s)
+{
+ uimr i;
+ uimr newv;
+ MyCharR *p = PStrToMyCharPtr(s);
+
+ s[0] = n;
+ for (i = n + 1; 0 != --i; ) {
+ newv = v / (uimr)10;
+ *p++ = '0' + (v - newv * 10);
+ v = newv;
+ }
+
+ ReversePStr(s);
+}
+
+GLOBALPROC PStrApndNUimr(ps3p r, uimr v, ui3r n)
+{
+ MyPStr t;
+
+ PStrFromNUimr(v, n, t);
+ PStrAppend(r, t);
+}
+
+#define Have_STRUTILS 1
--- /dev/null
+++ b/setup/USFILDEF.i
@@ -1,0 +1,499 @@
+/*
+ USFILDEF.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ USe program SPecific FILe DEFinitions
+*/
+
+LOCALPROC NullProc(void)
+{
+}
+
+LOCALVAR unsigned int FileCounter;
+
+struct DoSrcFile_r
+{
+ MyPtr SavepDt;
+ char *s;
+ long Flgm;
+ int DepDir;
+ tDoDependsForC depends;
+ MyProc p;
+};
+
+typedef struct DoSrcFile_r DoSrcFile_r;
+
+#define DoSrcFile_gd() ((DoSrcFile_r *)(pDt))
+
+LOCALPROC DoASrcFileWithSetupProc0(
+ char *s, int DepDir, long Flgm, tDoDependsForC depends)
+{
+ DoSrcFile_gd()->s = s;
+ DoSrcFile_gd()->Flgm = Flgm;
+ DoSrcFile_gd()->DepDir = DepDir;
+ DoSrcFile_gd()->depends = depends;
+
+ DoSrcFile_gd()->p();
+
+ ++FileCounter;
+}
+
+LOCALPROC DoASrcFileWithSetupProc(
+ char *s, int DepDir, long Flgm, tDoDependsForC depends)
+{
+ if (0 == (Flgm & kCSrcFlgmNoSource))
+ if (0 == (Flgm & kCSrcFlgmSkip))
+ {
+ DoASrcFileWithSetupProc0(s, DepDir, Flgm, depends);
+ }
+}
+
+LOCALPROC DoAllSrcFilesWithSetup(MyProc p)
+{
+ DoSrcFile_r r;
+
+ r.SavepDt = pDt;
+ r.p = p;
+ pDt = (MyPtr)&r;
+
+ FileCounter = 0;
+ DoAllSrcFiles(DoASrcFileWithSetupProc);
+
+ pDt = r.SavepDt;
+}
+
+LOCALPROC DoAllSrcFilesSortWithSetup1(
+ char *s, int DepDir, long Flgm, tDoDependsForC depends)
+{
+ if (0 == (Flgm & kCSrcFlgmNoSource))
+ if (0 == (Flgm & kCSrcFlgmSkip))
+ {
+ if (0 != (Flgm & kCSrcFlgmSortFirst)) {
+ DoASrcFileWithSetupProc0(s, DepDir, Flgm, depends);
+ } else {
+ ++FileCounter;
+ }
+ }
+}
+
+LOCALPROC DoAllSrcFilesSortWithSetup2(
+ char *s, int DepDir, long Flgm, tDoDependsForC depends)
+{
+ if (0 == (Flgm & kCSrcFlgmNoSource))
+ if (0 == (Flgm & kCSrcFlgmSkip))
+ {
+ if (0 == (Flgm & kCSrcFlgmSortFirst)) {
+ DoASrcFileWithSetupProc0(s, DepDir, Flgm, depends);
+ } else {
+ ++FileCounter;
+ }
+ }
+}
+
+LOCALPROC DoAllSrcFilesSortWithSetup(MyProc p)
+{
+ DoSrcFile_r r;
+
+ r.SavepDt = pDt;
+ r.p = p;
+ pDt = (MyPtr)&r;
+
+ FileCounter = 0;
+ DoAllSrcFiles(DoAllSrcFilesSortWithSetup1);
+ FileCounter = 0;
+ DoAllSrcFiles(DoAllSrcFilesSortWithSetup2);
+
+ pDt = r.SavepDt;
+}
+
+LOCALFUNC char * GetSrcFileFileXtns(void)
+{
+ char *s;
+ blnr UseObjc = ((DoSrcFile_gd()->Flgm & kCSrcFlgmOjbc) != 0);
+
+ if (UseObjc) {
+ s = ".m";
+ } else {
+ s = ".c";
+ }
+
+ return s;
+}
+
+LOCALPROC WriteSrcFileFileName(void)
+{
+ WriteCStrToDestFile(DoSrcFile_gd()->s);
+ WriteCStrToDestFile(GetSrcFileFileXtns());
+}
+
+LOCALPROC WriteSrcFileFilePath(void)
+{
+ WriteFileInDirToDestFile0(Write_src_d_ToDestFile,
+ WriteSrcFileFileName);
+}
+
+LOCALPROC WriteSrcFileHeaderName(void)
+{
+ WriteCStrToDestFile(DoSrcFile_gd()->s);
+ WriteCStrToDestFile(".h");
+}
+
+LOCALPROC WriteSrcFileHeaderPath(void)
+{
+ WriteFileInDirToDestFile0(Write_src_d_ToDestFile,
+ WriteSrcFileHeaderName);
+}
+
+LOCALPROC WriteSrcFileObjName(void)
+{
+ WriteCStrToDestFile(DoSrcFile_gd()->s);
+ switch (cur_ide) {
+ case gbk_ide_msv:
+ case gbk_ide_dmc:
+ case gbk_ide_plc:
+ WriteCStrToDestFile(".obj");
+ break;
+ case gbk_ide_9pc:
+ WriteCStrToDestFile(".$O");
+ break;
+ default:
+ WriteCStrToDestFile(".o");
+ break;
+ }
+}
+
+LOCALPROC WriteSrcFileObjPath(void)
+{
+ WriteFileInDirToDestFile0(Write_obj_d_ToDestFile,
+ WriteSrcFileObjName);
+}
+
+LOCALPROC DoAllExtraHeaders2WithSetupProc(
+ char *s, int DepDir, long Flgm, tDoDependsForC depends)
+{
+ if (0 == (Flgm & kCSrcFlgmNoHeader))
+ if (0 != (Flgm & kCSrcFlgmNoSource))
+ if (0 == (Flgm & kCSrcFlgmSkip))
+ {
+ DoASrcFileWithSetupProc0(s, DepDir, Flgm, depends);
+ }
+}
+
+LOCALPROC DoAllExtraHeaders2WithSetup(MyProc p)
+{
+ DoSrcFile_r r;
+
+ r.SavepDt = pDt;
+ r.p = p;
+ pDt = (MyPtr)&r;
+
+ FileCounter = 0;
+ DoAllSrcFiles(DoAllExtraHeaders2WithSetupProc);
+
+ pDt = r.SavepDt;
+}
+
+LOCALPROC WriteExtraHeaderFileName(void)
+{
+ WriteCStrToDestFile(DoSrcFile_gd()->s);
+ WriteCStrToDestFile(".h");
+}
+
+LOCALPROC WriteExtraHeaderFilePath(void)
+{
+ WriteFileInDirToDestFile0(
+ ((kDepDirCnfg == DoSrcFile_gd()->DepDir)
+ ? Write_cfg_d_ToDestFile
+ : Write_src_d_ToDestFile),
+ WriteExtraHeaderFileName);
+}
+
+LOCALVAR unsigned int DocTypeCounter;
+
+struct DoDocType_r
+{
+ MyPtr SavepDt;
+ char *ShortName;
+ char *MacType;
+ char *LongName;
+ tWriteExtensionList WriteExtensionList;
+ MyProc p;
+};
+
+typedef struct DoDocType_r DoDocType_r;
+
+#define DoDocType_gd() ((DoDocType_r *)(pDt))
+
+LOCALPROC DoAllDocTypesWithSetupProc(char *ShortName,
+ char *MacType,
+ char *LongName,
+ tWriteExtensionList WriteExtensionList)
+{
+ DoDocType_gd()->ShortName = ShortName;
+ DoDocType_gd()->MacType = MacType;
+ DoDocType_gd()->LongName = LongName;
+ DoDocType_gd()->WriteExtensionList = WriteExtensionList;
+
+ DoDocType_gd()->p();
+
+ ++DocTypeCounter;
+}
+
+LOCALPROC DoAppAndAllDocTypes0(tWriteOneDocType p)
+{
+ p("APP", "APPL", "Application", NULL);
+ DoAllDocTypes(p);
+}
+
+LOCALPROC DoAppAndAllDocTypes(tWriteOneDocType p)
+{
+ p("APP", "APPL", "Application", NULL);
+ if (WantIconMaster) {
+ DoAllDocTypes(p);
+ }
+}
+
+LOCALPROC DoAllDocTypesWithSetup(MyProc p)
+{
+ DoDocType_r r;
+
+ r.SavepDt = pDt;
+ r.p = p;
+ pDt = (MyPtr)&r;
+
+ DocTypeCounter = 0;
+ DoAppAndAllDocTypes(DoAllDocTypesWithSetupProc);
+
+ pDt = r.SavepDt;
+}
+
+LOCALPROC WriteDocTypeIconShortName(void)
+{
+ WriteCStrToDestFile(DoDocType_gd()->ShortName);
+}
+
+LOCALPROC WriteDocTypeIconFileName(void)
+{
+ WriteCStrToDestFile("ICON");
+ WriteDocTypeIconShortName();
+ switch (gbo_targfam) {
+ case gbk_targfam_cmac:
+ WriteCStrToDestFile("M.r");
+ break;
+ case gbk_targfam_mach:
+ case gbk_targfam_carb:
+ WriteCStrToDestFile("O.icns");
+ break;
+ case gbk_targfam_mswn:
+ case gbk_targfam_wnce:
+ WriteCStrToDestFile("W.ico");
+ break;
+ }
+}
+
+LOCALPROC WriteDocTypeIconFilePath(void)
+{
+ WriteFileInDirToDestFile0(Write_src_d_ToDestFile,
+ WriteDocTypeIconFileName);
+}
+
+LOCALPROC WriteDocTypeIconMacType(void)
+{
+ WriteCStrToDestFile(DoDocType_gd()->MacType);
+}
+
+LOCALPROC WriteDocTypeCopyMachoFile(void)
+{
+ WriteCopyFile(WriteDocTypeIconFilePath,
+ Write_tmachores_d_ToDestFile);
+}
+
+typedef void (*tWriteOneFrameWorkType)(char *s);
+
+static void DoAllFrameWorks(tWriteOneFrameWorkType p)
+{
+ if (gbk_apifam_cco == gbo_apifam) {
+ p("AppKit");
+ p("AudioUnit");
+#if UseOpenGLinOSX
+ p("OpenGL");
+#endif
+ } else {
+ p("Carbon");
+#if UseOpenGLinOSX
+ p("OpenGL");
+ p("AGL");
+#endif
+ }
+}
+
+struct DoFrameWork_r
+{
+ MyPtr SavepDt;
+ char *s;
+ MyProc p;
+};
+
+typedef struct DoFrameWork_r DoFrameWork_r;
+
+#define DoFrameWork_gd() ((DoFrameWork_r *)(pDt))
+
+LOCALPROC DoAllFrameWorksWithSetupProc(char *s)
+{
+ DoFrameWork_gd()->s = s;
+
+ DoFrameWork_gd()->p();
+
+ ++FileCounter;
+}
+
+LOCALPROC DoAllFrameWorksWithSetup(MyProc p)
+{
+ DoFrameWork_r r;
+
+ r.SavepDt = pDt;
+ r.p = p;
+ pDt = (MyPtr)&r;
+
+ FileCounter = 0;
+ DoAllFrameWorks(DoAllFrameWorksWithSetupProc);
+
+ pDt = r.SavepDt;
+}
+
+LOCALPROC WriteFileToCFilesList(MyProc p)
+{
+ WriteBgnDestFileLn();
+ p();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC DoSrcExtraHeaderFile(void)
+{
+ WriteFileToCFilesList(WriteExtraHeaderFilePath);
+}
+
+LOCALPROC DoSrcFileAddToList(void)
+{
+ WriteFileToCFilesList(WriteSrcFileHeaderPath);
+ WriteFileToCFilesList(WriteSrcFileFilePath);
+}
+
+LOCALPROC WriteCFilesListContents(void)
+{
+ DoAllExtraHeaders2WithSetup(DoSrcExtraHeaderFile);
+ DoAllSrcFilesWithSetup(DoSrcFileAddToList);
+}
+
+LOCALPROC WriteCFilesList(void)
+{
+ /* list of c files */
+
+ WriteADstFile1("my_project_d",
+ "c_files", "", "list of c files",
+ WriteCFilesListContents);
+}
+
+LOCALPROC Write_tmachoShell(void)
+{
+ WriteRmDir(WriteAppNamePath);
+ WriteRmDir(Write_tmachobun_d_ToDestFile);
+ WriteMkDir(Write_tmachobun_d_ToDestFile);
+ WriteMkDir(Write_tmachocontents_d_ToDestFile);
+ WriteMkDir(Write_tmachomac_d_ToDestFile);
+ WriteMkDir(Write_tmachores_d_ToDestFile);
+ WriteMkDir(Write_tmacholang_d_ToDestFile);
+ DoAllDocTypesWithSetup(WriteDocTypeCopyMachoFile);
+ WriteCopyFile(WriteInfoPlistFilePath,
+ Write_tmachocontents_d_ToDestFile);
+ WriteEchoToNewFile(Write_tmachoLangDummyContents,
+ Write_tmachoLangDummyPath, trueblnr);
+ WriteEchoToNewFile(Write_tmachoPkgInfoContents,
+ Write_tmachoPkgInfoPath, falseblnr);
+ WriteMoveDir(Write_tmachobun_d_ToDestFile, WriteAppNamePath);
+}
+
+LOCALPROC Write_tmachoShellDeps(void)
+{
+ WriteMakeDependFile(Write_srcAppIconPath);
+}
+
+LOCALPROC WritepDtSrcPath(void)
+{
+ WriteFileInDirToDestFile0(Write_src_d_ToDestFile, WritepDtString);
+}
+
+LOCALPROC WritepDtCfgPath(void)
+{
+ WriteFileInDirToDestFile0(Write_cfg_d_ToDestFile, WritepDtString);
+}
+
+LOCALPROC DoSrcDependsMakeCompile(int DepDir, char *s)
+{
+ MyPtr SavepDt = pDt;
+ pDt = (MyPtr)s;
+ WriteMakeDependFile((kDepDirCnfg == DepDir)
+ ? WritepDtCfgPath
+ : WritepDtSrcPath);
+ pDt = SavepDt;
+}
+
+LOCALPROC DoSrcFileMakeCompileDeps(void)
+{
+ WriteMakeDependFile(WriteSrcFileFilePath);
+ if (DoSrcFile_gd()->depends != nullpr) {
+ DoSrcFile_gd()->depends(DoSrcDependsMakeCompile);
+ }
+ WriteMakeDependFile(WriteCNFGGLOBPath);
+}
+
+LOCALPROC DoSrcFileMakeCompileBody(void)
+{
+ WriteCompileC(WriteSrcFileFilePath, WriteSrcFileObjPath,
+ (DoSrcFile_gd()->Flgm & kCSrcFlgmUseAPI) != 0);
+ WriteBlankLineToDestFile();
+}
+
+LOCALPROC DoSrcFileMakeCompile(void)
+{
+ WriteMakeRule(WriteSrcFileObjPath,
+ DoSrcFileMakeCompileDeps,
+ DoSrcFileMakeCompileBody);
+
+}
+
+LOCALPROC DoSrcFileStandardMakeObjects(void)
+{
+ WriteBgnDestFileLn();
+ WriteSrcFileObjPath();
+ WriteSpaceToDestFile();
+ WriteBackSlashToDestFile();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC DoAllSrcFilesStandardMakeObjects(void)
+{
+ DoAllSrcFilesSortWithSetup(DoSrcFileStandardMakeObjects);
+}
+
+LOCALPROC DoSrcFileStandardEraseFile(void)
+{
+ WriteRmFile(WriteSrcFileObjPath);
+}
+
+LOCALPROC DoAllSrcFilesStandardErase(void)
+{
+ DoAllSrcFilesWithSetup(DoSrcFileStandardEraseFile);
+}
--- /dev/null
+++ b/setup/WRBGCFLS.i
@@ -1,0 +1,492 @@
+/*
+ WRBGCFLS.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite Bash Gnu C specific FiLeS
+*/
+
+
+#define WriteXCDcallgcc WriteCompileCExec
+#if 0
+LOCALPROC WriteXCDcallgcc(void)
+{
+#if 0
+ if ((gbk_ide_xcd == cur_ide) && (ide_vers >= 2100)
+ && (ide_vers < 2200))
+ {
+ /*
+ This doesn't seem to make any difference in default
+ Xcode 2.1 install. Current guess is that default
+ headers don't support MACOSX_DEPLOYMENT_TARGET,
+ but the ide is supporting 10.4 sdk that is
+ included but not installed by default.
+ */
+ WriteCStrToDestFile("export MACOSX_DEPLOYMENT_TARGET=10.");
+ if (gbk_cpufam_ppc == gbo_cpufam) {
+ WriteCStrToDestFile("1");
+ } else {
+ WriteCStrToDestFile("4");
+ }
+ WriteCStrToDestFile(" ; ");
+ }
+#endif
+ WriteCStrToDestFile("gcc");
+}
+#endif
+
+LOCALPROC WriteBgcCompileAsmLinkCommonOptions(void)
+{
+ if ((gbk_ide_xcd == cur_ide) && (ide_vers >= 2100)) {
+ switch (cur_targ) {
+ case gbk_targ_mach:
+ case gbk_targ_imch:
+ case gbk_targ_mc64:
+ case gbk_targ_mx11:
+ case gbk_targ_mi11:
+ case gbk_targ_mx64:
+ if (gbk_cpufam_x86 == gbo_cpufam) {
+ WriteCStrToDestFile(" -arch i386");
+ } else if (gbk_cpufam_x64 == gbo_cpufam) {
+ WriteCStrToDestFile(" -arch x86_64");
+ } else {
+ WriteCStrToDestFile(" -arch ppc");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (gbk_targfam_oind == gbo_targfam) {
+ if (gbk_cpufam_x64 == gbo_cpufam) {
+ WriteCStrToDestFile(" -m64");
+ }
+ } else if (gbk_targfam_lnds == gbo_targfam) {
+ WriteCStrToDestFile(" -marm -mthumb-interwork");
+ }
+}
+
+LOCALPROC WriteBgcLinkOSGlucompileCommonOptions(void)
+{
+ if ((gbk_ide_xcd == cur_ide) && (ide_vers >= 2200)) {
+ if ((gbk_apifam_osx == gbo_apifam)
+ || (gbk_apifam_cco == gbo_apifam))
+ {
+ if (gbk_cpufam_ppc == gbo_cpufam) {
+ WriteCStrToDestFile(" -mmacosx-version-min=10.1");
+ } else
+ if (gbk_cpufam_x64 == gbo_cpufam) {
+ WriteCStrToDestFile(" -mmacosx-version-min=10.5");
+ } else
+ {
+ WriteCStrToDestFile(" -mmacosx-version-min=10.4");
+ }
+ WriteCStrToDestFile(" -isysroot");
+ if (ide_vers >= 3200) {
+ WriteCStrToDestFile(" /Developer/SDKs/MacOSX10.6.sdk");
+ } else if ((ide_vers >= 3100)
+ || (gbk_cpufam_x64 == gbo_cpufam))
+ {
+ WriteCStrToDestFile(" /Developer/SDKs/MacOSX10.5.sdk");
+ } else {
+ WriteCStrToDestFile(" /Developer/SDKs/MacOSX10.4u.sdk");
+ }
+ }
+ }
+}
+
+LOCALPROC WriteBgcCompileLinkCommonOptions(void)
+{
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteCStrToDestFile(" -g");
+ }
+}
+
+LOCALPROC WriteBgcCOptions(void)
+{
+ WriteCStrToDestFile(
+ " -Wall -Wmissing-prototypes -Wno-uninitialized");
+
+ if (gbk_apifam_nds != gbo_apifam) {
+ WriteCStrToDestFile(" -Wundef -Wstrict-prototypes");
+ }
+ if (gbk_ide_cyg == cur_ide) {
+ if (gbk_targfam_cygw != gbo_targfam) {
+ WriteCStrToDestFile(" -mno-cygwin");
+ }
+ }
+ if (gbk_ide_xcd == cur_ide) {
+ WriteCStrToDestFile(" -fpascal-strings");
+ }
+ if (gbk_ide_xcd == cur_ide) {
+ switch (cur_targ) {
+ case gbk_targ_mach:
+ case gbk_targ_imch:
+ case gbk_targ_mc64:
+ case gbk_targ_mx11:
+ case gbk_targ_mi11:
+ case gbk_targ_mx64:
+ WriteCStrToDestFile(" -mdynamic-no-pic");
+ break;
+ }
+ }
+ WriteBgcCompileAsmLinkCommonOptions();
+ WriteBgcCompileLinkCommonOptions();
+
+ if (gbk_apifam_nds == gbo_apifam) {
+ WriteCStrToDestFile(" -march=armv5te -mtune=arm946e-s");
+ }
+
+ if (1 /* WantConfigDir */) {
+ WriteCStrToDestFile(" -I");
+ Write_cfg_d_ToDestFile();
+ WriteCStrToDestFile(" -I");
+ Write_src_d_ToDestFile();
+ }
+}
+
+LOCALPROC WriteBgcCOptOptions(void)
+{
+ if (gbk_dbg_on != gbo_dbg) {
+ /* WriteCStrToDestFile(" -O3"); */
+ if (gbk_targfam_lnds == gbo_targfam) {
+ WriteCStrToDestFile(" -O2");
+ } else {
+ WriteCStrToDestFile(" -Os");
+ }
+ } else {
+ WriteCStrToDestFile(" -O0");
+ }
+}
+
+LOCALPROC DoFrameWorkBGCaddFile(void)
+{
+ WriteCStrToDestFile(" -framework ");
+ WriteCStrToDestFile(DoFrameWork_gd()->s);
+}
+
+LOCALPROC Write_machoRsrcBgcDeps(void)
+{
+ WriteMakeDependFile(WriteMainRsrcSrcPath);
+ WriteMakeDependFile(Write_machoAppIconPath);
+}
+
+LOCALPROC Write_machoRsrcBgcBuild(void)
+{
+ WriteDestFileLn("/Developer/Tools/Rez \\");
+ ++DestFileIndent;
+ WriteDestFileLn("-i /Developer/Headers/FlatCarbon \\");
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("\"");
+ WriteMainRsrcSrcPath();
+ WriteCStrToDestFile("\" \\");
+ WriteEndDestFileLn();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("-o \"");
+ Write_machoRsrcPath();
+ WriteCStrToDestFile("\" \\");
+ WriteEndDestFileLn();
+ WriteDestFileLn("-useDF");
+ --DestFileIndent;
+}
+
+LOCALPROC WriteBashGccMakeFile(void)
+{
+ WriteDestFileLn("# make file generated by gryphel build system");
+
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptionsCommon = -c");
+ WriteBgcCOptions();
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptionsOSGLU = $(mk_COptionsCommon)");
+ WriteBgcLinkOSGlucompileCommonOptions();
+ WriteBgcCOptOptions();
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptions = $(mk_COptionsCommon)");
+ WriteBgcCOptOptions();
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(".PHONY: TheDefaultOutput clean");
+
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("TheDefaultOutput :");
+ WriteMakeDependFile(Write_machobinpath_ToDestFile);
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ DoAllSrcFilesWithSetup(DoSrcFileMakeCompile);
+
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("ObjFiles = ");
+ WriteBackSlashToDestFile();
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ DoAllSrcFilesStandardMakeObjects();
+ WriteBlankLineToDestFile();
+ --DestFileIndent;
+
+ if (HaveMacBundleApp) {
+ WriteBlankLineToDestFile();
+ WriteMakeRule(Write_machoAppIconPath,
+ Write_tmachoShellDeps,
+ Write_tmachoShell);
+ }
+ if (gbk_apifam_win == gbo_apifam) {
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteMainRsrcObjPath();
+ WriteCStrToDestFile(": ");
+ WriteMainRsrcSrcPath();
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("windres.exe");
+ WriteCStrToDestFile(" -i");
+ WritePathArgInMakeCmnd(WriteMainRsrcSrcPath);
+ WriteCStrToDestFile(" --input-format=rc -o");
+ WritePathArgInMakeCmnd(WriteMainRsrcObjPath);
+ WriteCStrToDestFile(" -O coff --include-dir SRC");
+ WriteEndDestFileLn();
+ --DestFileIndent;
+ WriteBlankLineToDestFile();
+ }
+
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ Write_machobinpath_ToDestFile();
+ WriteCStrToDestFile(" : $(ObjFiles)");
+ if (HaveMacBundleApp) {
+ WriteMakeDependFile(Write_machoAppIconPath);
+ }
+ if (HaveMacRrscs) {
+ WriteMakeDependFile(Write_machoRsrcPath);
+ }
+ if (gbk_apifam_win == gbo_apifam) {
+ WriteMakeDependFile(WriteMainRsrcObjPath);
+ }
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteXCDcallgcc();
+ WriteCStrToDestFile(" \\");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("-o");
+ if (gbk_apifam_nds == gbo_apifam) {
+ WritePathArgInMakeCmnd(WriteBinElfObjObjPath);
+ } else {
+ WritePathArgInMakeCmnd(Write_machobinpath_ToDestFile);
+ }
+ WriteCStrToDestFile(" \\");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("$(ObjFiles)");
+ if ((gbk_apifam_osx == gbo_apifam)
+ || (gbk_apifam_cco == gbo_apifam))
+ {
+ DoAllFrameWorksWithSetup(DoFrameWorkBGCaddFile);
+ if (ide_vers >= 4000) {
+ WriteCStrToDestFile(" -Wl,-no_pie");
+ }
+ } else if (gbk_apifam_win == gbo_apifam) {
+ WritePathArgInMakeCmnd(WriteMainRsrcObjPath);
+ if (gbk_targ_wcar == cur_targ) {
+ WriteCStrToDestFile(
+ " -lcommctrl -lcoredll -laygshell -lmmtimer");
+ } else {
+ WriteCStrToDestFile(
+ " -mwindows -lwinmm -lole32 -luuid");
+ if (gbk_ide_cyg == cur_ide) {
+ WriteCStrToDestFile(" -mno-cygwin");
+ }
+ }
+ } else if (gbk_apifam_gtk == gbo_apifam) {
+ WriteCStrToDestFile(" `pkg-config --libs gtk+-2.0`");
+ } else if (gbk_apifam_sdl == gbo_apifam) {
+ if (gbk_targfam_mach == gbo_targfam) {
+ WriteCStrToDestFile(" -L/usr/local/lib -lSDLmain"
+ " -lSDL -Wl,-framework,Cocoa");
+ } else {
+ WriteCStrToDestFile(" -lSDL");
+ }
+ } else if (gbk_apifam_sd2 == gbo_apifam) {
+ if (gbk_targfam_mach == gbo_targfam) {
+ WriteCStrToDestFile(
+ " -Wl,-framework,Cocoa,-framework,SDL2");
+ } else {
+ WriteCStrToDestFile(" -lSDL2");
+ }
+ } else if (gbk_apifam_nds == gbo_apifam) {
+ WriteCStrToDestFile(" -L$(DEVKITPRO)/libnds/lib");
+ WriteCStrToDestFile(" -lfilesystem -lfat -lnds9");
+ } else {
+ if (gbk_targfam_slrs == gbo_targfam) {
+ WriteCStrToDestFile(" -lposix4");
+ }
+#if MayUseSound
+ if (gbk_sndapi_alsa == gbo_sndapi) {
+ WriteCStrToDestFile(" -ldl");
+#if 0
+ WriteCStrToDestFile(" -lasound");
+#endif
+ } else if (gbk_sndapi_ddsp == gbo_sndapi) {
+ if ((gbk_targfam_nbsd == gbo_targfam)
+ || (gbk_targfam_obsd == gbo_targfam))
+ {
+ WriteCStrToDestFile(" -lossaudio");
+ }
+ }
+#endif
+#if 0
+ WriteCStrToDestFile(" -lXext");
+#endif
+ if (gbk_targfam_nbsd == gbo_targfam) {
+ WriteCStrToDestFile(" -L/usr/X11R7/lib");
+ WriteCStrToDestFile(" -R/usr/X11R7/lib");
+ } else if (gbk_targfam_dbsd == gbo_targfam) {
+ WriteCStrToDestFile(" -L/usr/pkg/lib");
+ } else if (gbk_targfam_minx == gbo_targfam) {
+ WriteCStrToDestFile(" -L/usr/pkg/X11R6/lib");
+ } else if (gbk_targfam_irix == gbo_targfam) {
+ WriteCStrToDestFile(" -L/usr/lib/X11");
+ } else {
+ WriteCStrToDestFile(" -L/usr/X11R6/lib");
+ }
+ WriteCStrToDestFile(" -lX11");
+ }
+ if (gbk_apifam_nds == gbo_apifam) {
+ WriteCStrToDestFile(" -specs=ds_arm9.specs");
+ }
+ WriteBgcCompileAsmLinkCommonOptions();
+ WriteBgcLinkOSGlucompileCommonOptions();
+ WriteBgcCompileLinkCommonOptions();
+ WriteEndDestFileLn();
+ --DestFileIndent;
+ if (gbk_dbg_on != gbo_dbg) {
+ switch (cur_ide) {
+ case gbk_ide_bgc:
+ if ((gbk_targfam_minx == gbo_targfam)
+ || (gbk_targfam_linx == gbo_targfam)
+ || (gbk_targfam_oind == gbo_targfam)
+ /*
+ for oi64, strip makes it larger!
+ but still compresses smaller.
+ */
+ || (gbk_targfam_fbsd == gbo_targfam)
+ || (gbk_targfam_obsd == gbo_targfam)
+ || (gbk_targfam_nbsd == gbo_targfam)
+ || (gbk_targfam_dbsd == gbo_targfam)
+ )
+ {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("strip --strip-unneeded");
+ WritePathArgInMakeCmnd(
+ Write_machobinpath_ToDestFile);
+ WriteEndDestFileLn();
+ } else if (gbk_targfam_irix == gbo_targfam) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("strip -s");
+ WritePathArgInMakeCmnd(
+ Write_machobinpath_ToDestFile);
+ WriteEndDestFileLn();
+ }
+ break;
+ case gbk_ide_xcd:
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("strip -u -r");
+ WritePathArgInMakeCmnd(
+ Write_machobinpath_ToDestFile);
+ WriteEndDestFileLn();
+ break;
+ case gbk_ide_dvc:
+ case gbk_ide_mgw:
+ case gbk_ide_cyg:
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("strip.exe");
+ WritePathArgInMakeCmnd(WriteAppNamePath);
+ WriteEndDestFileLn();
+ break;
+ default:
+ break;
+ }
+ }
+ if (gbk_apifam_nds == gbo_apifam) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(
+ "$(DEVKITARM)/bin/arm-eabi-objcopy.exe -O binary");
+ WritePathArgInMakeCmnd(WriteBinElfObjObjPath);
+ WritePathArgInMakeCmnd(WriteBinArmObjObjPath);
+ WriteEndDestFileLn();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("$(DEVKITARM)/bin/ndstool.exe -c");
+ WritePathArgInMakeCmnd(WriteAppNamePath);
+ WriteCStrToDestFile(" -9");
+ WritePathArgInMakeCmnd(WriteBinArmObjObjPath);
+ WriteCStrToDestFile(" -b $(DEVKITPRO)/libnds/icon.bmp");
+ WriteCStrToDestFile(
+ " \";www.devkitpro.org;www.drunkencoders.com\"");
+ WriteEndDestFileLn();
+ }
+ --DestFileIndent;
+
+ if (HaveMacRrscs) {
+ WriteBlankLineToDestFile();
+ WriteMakeRule(Write_machoRsrcPath,
+ Write_machoRsrcBgcDeps,
+ Write_machoRsrcBgcBuild);
+ }
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("clean :");
+ ++DestFileIndent;
+ WriteDestFileLn("rm -f $(ObjFiles)");
+ if (HaveMacBundleApp) {
+ WriteRmDir(WriteAppNamePath);
+ } else {
+ if (gbk_apifam_win == gbo_apifam) {
+ WriteRmFile(WriteMainRsrcObjPath);
+ } else if (gbk_apifam_nds == gbo_apifam) {
+ WriteRmFile(WriteBinElfObjObjPath);
+ WriteRmFile(WriteBinArmObjObjPath);
+ }
+ WriteRmFile(WriteAppNamePath);
+ }
+ --DestFileIndent;
+}
+
+LOCALPROC WriteBashGccSpecificFiles(void)
+{
+ if (HaveMacBundleApp) {
+ WritePListData();
+ }
+
+ if (WantSandbox) {
+ WriteEntitlementsData();
+ }
+
+ WriteADstFile1("my_project_d",
+ "Makefile", "", "Make file",
+ WriteBashGccMakeFile);
+}
--- /dev/null
+++ b/setup/WRCCCFLS.i
@@ -1,0 +1,138 @@
+/*
+ WRCCCFLS.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite generic Command line C Compiler specific FiLeS
+*/
+
+
+LOCALPROC WriteCccMakeFile(void)
+{
+ WriteDestFileLn("# make file generated by gryphel build system");
+
+ WriteBlankLineToDestFile();
+
+ WriteDestFileLn("mk_COptions = -c");
+ WriteCStrToDestFile(" -I");
+ Write_cfg_d_ToDestFile();
+ WriteCStrToDestFile(" -I");
+ Write_src_d_ToDestFile();
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("TheDefaultOutput : ");
+ Write_machobinpath_ToDestFile();
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ DoAllSrcFilesWithSetup(DoSrcFileMakeCompile);
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("ObjFiles = ");
+ WriteBackSlashToDestFile();
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ DoAllSrcFilesStandardMakeObjects();
+ WriteBlankLineToDestFile();
+ --DestFileIndent;
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ Write_machobinpath_ToDestFile();
+ WriteCStrToDestFile(" : $(ObjFiles)");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteDestFileLn("cc \\");
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("-o ");
+ WriteQuoteToDestFile();
+ Write_machobinpath_ToDestFile();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" \\");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("$(ObjFiles)");
+#if 0
+ WriteCStrToDestFile(" -lXext");
+#endif
+ WriteCStrToDestFile(" -L/usr/X11R6/lib -lX11");
+ WriteEndDestFileLn();
+ --DestFileIndent;
+ --DestFileIndent;
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("clean :");
+ ++DestFileIndent;
+ WriteDestFileLn("rm -f $(ObjFiles)");
+ WriteRmFile(WriteAppNamePath);
+ --DestFileIndent;
+}
+
+LOCALPROC WriteCccSpecificFiles(void)
+{
+ WriteADstFile1("my_project_d",
+ "Makefile", "", "Make file",
+ WriteCccMakeFile);
+}
+
+LOCALPROC Write9pcMkFile(void)
+{
+ WriteDestFileLn("# mkfile generated by gryphel build system");
+
+ WriteBlankLineToDestFile();
+
+ WriteDestFileLn("</$objtype/mkfile");
+ WriteBlankLineToDestFile();
+
+ WriteDestFileLn("BIN=/$objtype/bin/games");
+ WriteDestFileLn("CFLAGS=-p -D__plan9__ -Icfg -Isrc $CFLAGS");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("TARG=");
+ Write_machobinpath_ToDestFile();
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ DoAllSrcFilesWithSetup(DoSrcFileMakeCompile);
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("OFILES=");
+ WriteBackSlashToDestFile();
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ DoAllSrcFilesStandardMakeObjects();
+ WriteBlankLineToDestFile();
+ --DestFileIndent;
+
+ WriteDestFileLn("$TARG: $OFILES");
+ ++DestFileIndent;
+ WriteDestFileLn("$LD -o $target $OFILES");
+ --DestFileIndent;
+ WriteBlankLineToDestFile();
+
+ WriteDestFileLn("default:V: $TARG");
+ WriteBlankLineToDestFile();
+
+ WriteDestFileLn("</sys/src/cmd/mkone");
+}
+
+LOCALPROC Write9pcSpecificFiles(void)
+{
+ WriteADstFile1("my_project_d",
+ "mkfile", "", "mk file",
+ Write9pcMkFile);
+}
--- /dev/null
+++ b/setup/WRCNFGAP.i
@@ -1,0 +1,431 @@
+/*
+ WRCNFGAP.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite "CNFGrAPi.h"
+*/
+
+LOCALPROC WriteOSXLocalTalkCNFGRAPI(void)
+{
+ WriteDestFileLn("#include <unistd.h>");
+ WriteDestFileLn("#include <netinet/in.h>");
+ WriteDestFileLn("#include <sys/socket.h>");
+ WriteDestFileLn("#include <net/if.h>");
+ WriteDestFileLn("#include <net/route.h>");
+ WriteDestFileLn("#include <net/if_dl.h>");
+ WriteDestFileLn("#include <arpa/inet.h>");
+ WriteDestFileLn("#include <sys/select.h>");
+ WriteDestFileLn("#include <sys/ioctl.h>");
+ WriteDestFileLn("#include <sys/sysctl.h>");
+ WriteDestFileLn("#include <net/bpf.h>");
+}
+
+LOCALPROC WriteCommonCNFGRAPIContents(void)
+{
+ WriteDestFileLn("/*");
+ ++DestFileIndent;
+ WriteDestFileLn(
+ "Configuration options used by platform specific code.");
+ WriteConfigurationWarning();
+ --DestFileIndent;
+ WriteDestFileLn("*/");
+
+
+ if (gbo_TstCompErr) {
+ WriteDestFileLn("#error \"Testing Compile Time Error\"");
+ }
+
+ if (gbk_ide_msv == cur_ide) {
+ if (ide_vers >= 8000) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("#define _CRT_SECURE_NO_DEPRECATE 1");
+ }
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "/* ignore warning generated by system includes */");
+ if (ide_vers >= 6000) {
+ WriteDestFileLn("#pragma warning(push)");
+ }
+ WriteDestFileLn("#pragma warning(disable : 4201 4115 4214)");
+ }
+
+ WriteBlankLineToDestFile();
+
+ if (gbk_apifam_osx == gbo_apifam) {
+ if (gbk_targfam_carb == gbo_targfam) {
+ /* kIdeMW8 or kIdeMPW3_6_a1 */
+ if (gbk_ide_mw8 == cur_ide) {
+ WriteDestFileLn("#include <MacHeadersCarbon.h>");
+ } else
+ {
+ WriteDestFileLn("#include <Carbon.h>");
+ WriteDestFileLn("#include <stdlib.h>");
+ WriteDestFileLn("#include <string.h>");
+#if UseOpenGLinOSX
+ WriteDestFileLn("#include <agl.h>");
+#endif
+ }
+ WriteDestFileLn("#define UsingCarbonLib 1");
+ } else {
+ /* kIdeMW8 or kIdeBashGcc or kIdeAPB */
+ if (gbk_ide_mw8 == cur_ide) {
+ WriteDestFileLn("#include <MSL MacHeadersMach-O.h>");
+ }
+ WriteDestFileLn("#include <Carbon/Carbon.h>");
+#if UseOpenGLinOSX
+ WriteDestFileLn("#include <AGL/agl.h>");
+#endif
+#if UseMachinOSX
+ WriteDestFileLn("#include <mach/mach_interface.h>");
+ WriteDestFileLn("#include <mach/mach_port.h>");
+#endif
+ WriteDestFileLn("#include <unistd.h>");
+ /* for nanosleep */
+
+ if (WantLocalTalk) {
+ WriteOSXLocalTalkCNFGRAPI();
+ }
+ }
+ } else if (gbk_apifam_cco == gbo_apifam) {
+ WriteDestFileLn("#import <Cocoa/Cocoa.h>");
+#if MayUseSound
+ if (MySoundEnabled) {
+ WriteDestFileLn("#include <CoreAudio/CoreAudio.h>");
+ WriteDestFileLn("#include <AudioUnit/AudioUnit.h>");
+ }
+#endif
+#if UseOpenGLinOSX
+ WriteDestFileLn("#include <OpenGL/gl.h>");
+#endif
+ WriteDestFileLn("#include <stdio.h>");
+ WriteDestFileLn("#include <stdlib.h>");
+ WriteDestFileLn("#include <string.h>");
+ WriteDestFileLn("#include <sys/param.h>");
+ WriteDestFileLn("#include <sys/time.h>");
+ if (WantUnTranslocate) {
+ WriteDestFileLn("#include <dlfcn.h>");
+ }
+ if (WantLocalTalk) {
+ WriteOSXLocalTalkCNFGRAPI();
+ }
+ } else if (gbk_apifam_xwn == gbo_apifam) {
+ blnr HaveAppPathLink = falseblnr;
+ blnr HaveSysctlPath = (gbk_targfam_fbsd == gbo_targfam);
+
+ switch (gbo_targfam) {
+ case gbk_targfam_linx:
+ case gbk_targfam_nbsd:
+ case gbk_targfam_dbsd:
+ case gbk_targfam_oind:
+ HaveAppPathLink = trueblnr;
+ break;
+ default:
+ break;
+ }
+
+ if (gbk_targfam_minx == gbo_targfam) {
+ WriteDestFileLn(
+ "/* get nanosleep and gettimeofday. ugh */");
+ WriteDestFileLn("#define _POSIX_SOURCE 1");
+ WriteDestFileLn("#define _POSIX_C_SOURCE 200112L");
+ }
+ WriteDestFileLn("#include <stdio.h>");
+ WriteDestFileLn("#include <stdlib.h>");
+ WriteDestFileLn("#include <string.h>");
+ WriteDestFileLn("#include <time.h>");
+ WriteDestFileLn("#include <sys/time.h>");
+ WriteDestFileLn("#include <sys/times.h>");
+ WriteDestFileLn("#include <X11/Xlib.h>");
+ WriteDestFileLn("#include <X11/Xutil.h>");
+ WriteDestFileLn("#include <X11/keysym.h>");
+ WriteDestFileLn("#include <X11/keysymdef.h>");
+ WriteDestFileLn("#include <X11/Xatom.h>");
+#if 1
+ WriteDestFileLn("#include <fcntl.h>");
+#endif
+ /* if (WantActvCode) */ {
+ /* also now used for export file */
+ WriteDestFileLn("#include <sys/stat.h>");
+ }
+#if MayUseSound
+ if ((gbk_sndapi_alsa == gbo_sndapi)
+ || (gbk_sndapi_ddsp == gbo_sndapi))
+ {
+ WriteDestFileLn("#include <errno.h>");
+ }
+#endif
+ if (HaveAppPathLink /* for readlink */
+#if MayUseSound
+ || (gbk_sndapi_ddsp == gbo_sndapi)
+#endif
+ ) /* for write */
+ {
+ WriteDestFileLn("#include <unistd.h>");
+ }
+ if (HaveSysctlPath) {
+ WriteDestFileLn("#include <sys/sysctl.h>");
+ }
+#if MayUseSound
+ if (MySoundEnabled) {
+ switch (gbo_sndapi) {
+ case gbk_sndapi_alsa:
+ WriteDestFileLn("#include <dlfcn.h>");
+#if 0
+ WriteDestFileLn("#include <alsa/asoundlib.h>");
+#endif
+ break;
+ case gbk_sndapi_ddsp:
+ WriteDestFileLn("#include <sys/ioctl.h>");
+ if (gbk_targfam_obsd == gbo_targfam) {
+ WriteDestFileLn("#include <soundcard.h>");
+ } else {
+ WriteDestFileLn("#include <sys/soundcard.h>");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+#endif
+
+ WriteBlankLineToDestFile();
+ WriteCompCondBool("CanGetAppPath",
+ HaveAppPathLink || HaveSysctlPath);
+ WriteCompCondBool("HaveAppPathLink", HaveAppPathLink);
+ if (HaveAppPathLink) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define TheAppPathLink \"");
+ switch (gbo_targfam) {
+ case gbk_targfam_nbsd:
+ WriteCStrToDestFile("/proc/curproc/exe");
+ break;
+ case gbk_targfam_dbsd:
+ WriteCStrToDestFile("/proc/curproc/file");
+ break;
+ case gbk_targfam_oind:
+ WriteCStrToDestFile("/proc/self/path/a.out");
+ break;
+ case gbk_targfam_linx:
+ default:
+ WriteCStrToDestFile("/proc/self/exe");
+ break;
+ }
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+ }
+ WriteCompCondBool("HaveSysctlPath", HaveSysctlPath);
+
+#if MayUseSound
+ if (MySoundEnabled) {
+ if (gbk_sndapi_ddsp == gbo_sndapi) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define AudioDevPath \"");
+ switch (gbo_targfam) {
+ case gbk_targfam_nbsd:
+ case gbk_targfam_obsd:
+ WriteCStrToDestFile("/dev/audio");
+ break;
+ case gbk_targfam_fbsd:
+ case gbk_targfam_dbsd:
+ default:
+ WriteCStrToDestFile("/dev/dsp");
+ break;
+ }
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+ }
+ }
+#endif
+
+ } else if (gbk_apifam_nds == gbo_apifam) {
+ WriteDestFileLn("#define ARM9 1");
+
+ WriteDestFileLn("#include <nds.h>");
+ WriteDestFileLn("#include <filesystem.h>");
+ WriteDestFileLn("#include <fat.h>");
+
+ WriteDestFileLn("#include <stdio.h>");
+ WriteDestFileLn("#include <stdlib.h>");
+ WriteDestFileLn("#include <string.h>");
+ WriteDestFileLn("#include <time.h>");
+ WriteDestFileLn("#include <sys/time.h>");
+ WriteDestFileLn("#include <sys/times.h>");
+ WriteDestFileLn("#include <fcntl.h>");
+ WriteDestFileLn("#include <unistd.h>");
+ } else if (gbk_apifam_gtk == gbo_apifam) {
+ WriteDestFileLn("#include <gtk/gtk.h>");
+ WriteDestFileLn("#include <gdk/gdkkeysyms.h>");
+ WriteDestFileLn("#include <stdio.h>");
+ WriteDestFileLn("#include <stdlib.h>");
+ WriteDestFileLn("#include <string.h>");
+ WriteDestFileLn("#include <time.h>");
+ WriteDestFileLn("#include <sys/time.h>");
+ WriteDestFileLn("#include <sys/times.h>");
+ } else if (gbk_apifam_sdl == gbo_apifam) {
+ WriteDestFileLn("#include <SDL/SDL.h>");
+ WriteDestFileLn("#include <stdio.h>");
+ WriteDestFileLn("#include <stdlib.h>");
+ WriteDestFileLn("#include <string.h>");
+ } else if (gbk_apifam_sd2 == gbo_apifam) {
+ WriteDestFileLn("#include <SDL2/SDL.h>");
+ WriteDestFileLn("#include <stdio.h>");
+ WriteDestFileLn("#include <stdlib.h>");
+ WriteDestFileLn("#include <string.h>");
+ } else if (gbk_apifam_win == gbo_apifam) {
+ if ((gbk_ide_mvc == cur_ide)
+ && (gbk_targfam_wnce == gbo_targfam))
+ {
+ WriteDestFileLn("#define WIN32 1");
+ WriteDestFileLn("#define _WIN32 1");
+ WriteDestFileLn("#define WINNT 1");
+ WriteDestFileLn("#define UNDER_CE 1");
+ WriteDestFileLn("#define __CEGCC__ 1");
+ WriteDestFileLn("#define __CEGCC32__ 1");
+ WriteDestFileLn("#define __MINGW32__ 1");
+ WriteDestFileLn("#define __MINGW32CE__ 1");
+ WriteDestFileLn("#define __COREDLL__ 1");
+ WriteDestFileLn("#define UNICODE 1");
+ WriteDestFileLn("#define _UNICODE 1");
+ WriteDestFileLn("#define _M_ARM 1");
+ WriteBlankLineToDestFile();
+ }
+ if (gbk_ide_mw8 == cur_ide) {
+ WriteDestFileLn("#include <Win32Headers.h>");
+ } else
+ {
+ WriteDestFileLn("#include <windows.h>");
+ WriteDestFileLn("#include <time.h>");
+ if (gbk_ide_lcc == cur_ide) {
+ WriteDestFileLn("#include <shellapi.h>");
+ WriteDestFileLn("#include <mmsystem.h>");
+ }
+ }
+ WriteDestFileLn("#include <shlobj.h>");
+ WriteDestFileLn("#include <tchar.h>");
+ if (gbk_targfam_wnce == gbo_targfam) {
+ WriteDestFileLn("#include <aygshell.h>");
+ WriteDestFileLn("#include <commdlg.h>");
+ }
+ if (gbk_ide_mvc == cur_ide) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("#define _tWinMain WinMain");
+ }
+ if (gbk_ide_plc == cur_ide) {
+ WriteDestFileLn("#define _MAX_PATH MAX_PATH");
+ }
+ } else {
+ if (gbk_ide_mw8 == cur_ide) {
+ WriteDestFileLn("#include <MacHeaders.h>");
+ WriteDestFileLn("#include <CursorDevices.h>");
+ WriteDestFileLn("#define ShouldDefineQDGlobals 0");
+ } else
+ if (gbk_ide_mpw == cur_ide) {
+ WriteDestFileLn("#include <MacTypes.h>");
+ if (gbk_cpufam_68k != gbo_cpufam) {
+ WriteDestFileLn("#include <MixedMode.h>");
+ }
+ WriteDestFileLn("#include <Gestalt.h>");
+ WriteDestFileLn("#include <MacErrors.h>");
+ WriteDestFileLn("#include <MacMemory.h>");
+ WriteDestFileLn("#include <OSUtils.h>");
+ WriteDestFileLn("#include <QuickdrawText.h>");
+ WriteDestFileLn("#include <QuickDraw.h>");
+ if (gbk_cpufam_68k == gbo_cpufam) {
+ WriteDestFileLn("#include <SegLoad.h>");
+ }
+ WriteDestFileLn("#include <IntlResources.h>");
+ WriteDestFileLn("#include <Events.h>");
+ WriteDestFileLn("#include <Script.h>");
+ WriteDestFileLn("#include <Files.h>");
+ WriteDestFileLn("#include <Resources.h>");
+ WriteDestFileLn("#include <Fonts.h>");
+ WriteDestFileLn("#include <TextUtils.h>");
+ WriteDestFileLn("#include <FixMath.h>");
+ WriteDestFileLn("#include <ToolUtils.h>");
+ WriteDestFileLn("#include <Menus.h>");
+ WriteDestFileLn("#include <Scrap.h>");
+ WriteDestFileLn("#include <Controls.h>");
+ WriteDestFileLn("#include <ControlDefinitions.h>");
+ WriteDestFileLn("#include <AppleEvents.h>");
+ WriteDestFileLn("#include <Processes.h>");
+ WriteDestFileLn("#include <EPPC.h>");
+ WriteDestFileLn("#include <MacWindows.h>");
+ WriteDestFileLn("#include <TextEdit.h>");
+ WriteDestFileLn("#include <Dialogs.h>");
+ WriteDestFileLn("#include <Devices.h>");
+ WriteDestFileLn("#include <Palettes.h>");
+ WriteDestFileLn("#include <StandardFile.h>");
+ WriteDestFileLn("#include <Aliases.h>");
+ WriteDestFileLn("#include <Folders.h>");
+ WriteDestFileLn("#include <Balloons.h>");
+ WriteDestFileLn("#include <DiskInit.h>");
+ WriteDestFileLn("#include <LowMem.h>");
+ WriteDestFileLn("#include <Appearance.h>");
+ WriteDestFileLn("#include <Navigation.h>");
+ WriteDestFileLn("#include <Sound.h>");
+ WriteDestFileLn("#include <CursorDevices.h>");
+ WriteDestFileLn("#include <Traps.h>");
+ }
+ }
+
+ if ((gbk_ide_msv == cur_ide) && (ide_vers >= 6000)) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("/* restore warnings */");
+ WriteDestFileLn("#pragma warning(pop)");
+ }
+
+ WriteBlankLineToDestFile();
+
+ if (gbk_cpufam_68k == gbo_cpufam) {
+ if (gbk_ide_mpw == cur_ide) {
+ WriteDestFileLn("#define ShouldUnloadDataInit 1");
+ WriteDestFileLn("#define Windows85APIAvail 0");
+ WriteDestFileLn("#define NeedLongGlue 1");
+ }
+ }
+
+#if MayUseSound
+ if (MySoundEnabled) {
+ if (gbk_sndapi_alsa == gbo_sndapi)
+ if (gbk_cpufam_arm == gbo_cpufam)
+ {
+ WriteDestFileLn("#define RaspbianWorkAround 1");
+ }
+ }
+#endif
+
+ if (HaveMacBundleApp) {
+ WriteDestFileLn("#define MyAppIsBundle 1");
+ }
+ if (gbk_apifam_cco == gbo_apifam) {
+ WriteCompCondBool("WantUnTranslocate",
+ WantUnTranslocate);
+ }
+ if (gbk_apifam_win == gbo_apifam) {
+ if (WantIconMaster) {
+ WriteDestFileLn("#define InstallFileIcons 1");
+ }
+ }
+ if ((gbk_apifam_mac == gbo_apifam)
+ || (gbk_apifam_osx == gbo_apifam))
+ {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define kMacCreatorSig ");
+ WriteSingleQuoteToDestFile();
+ WriteCStrToDestFile(kMacCreatorSig);
+ WriteSingleQuoteToDestFile();
+ WriteEndDestFileLn();
+ }
+}
--- /dev/null
+++ b/setup/WRCNFGGL.i
@@ -1,0 +1,438 @@
+/*
+ WRCNFGGL.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite "CNFGGLob.h"
+*/
+
+
+LOCALPROC WriteConfigurationWarning(void)
+{
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "This file is automatically generated by the build system,");
+ WriteDestFileLn(
+ "which tries to know what options are valid in what");
+ WriteDestFileLn(
+ "combinations. Avoid changing this file manually unless");
+ WriteDestFileLn(
+ "you know what you're doing.");
+}
+
+LOCALPROC WriteCommonCNFGGLOBContents(void)
+{
+ WriteDestFileLn("/*");
+ ++DestFileIndent;
+ WriteDestFileLn(
+ "Configuration options used by both platform specific");
+ WriteDestFileLn(
+ "and platform independent code.");
+ WriteConfigurationWarning();
+ --DestFileIndent;
+ WriteDestFileLn("*/");
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("/* adapt to current compiler/host processor */");
+
+ if (gbk_ide_mw8 == cur_ide) {
+ WriteDestFileLn("/* make sure this is correct CNFGGLOB */");
+
+ WriteCheckPreDef("__MWERKS__");
+ switch (gbo_cpufam) {
+ case gbk_cpufam_68k:
+ WriteCheckPreDef("__MC68K__");
+ if (gbk_targ_mfpu == cur_targ) {
+ WriteCheckPreDef("__MC68881__");
+ } else {
+ WriteCheckPreNDef("__MC68881__");
+ }
+ break;
+ case gbk_cpufam_ppc:
+ WriteCheckPreDef("__POWERPC__");
+ break;
+ case gbk_cpufam_x86:
+ WriteCheckPreDef("__INTEL__");
+ break;
+ }
+ } else if ((gbk_ide_bgc == cur_ide)
+ || (gbk_ide_xcd == cur_ide)
+ || (gbk_ide_mvc == cur_ide))
+ {
+ switch (gbo_cpufam) {
+ case gbk_cpufam_x86:
+ WriteDestFileLn("#ifdef __x86_64__");
+ WriteDestFileLn("#error \"source is configured for"
+ " 32 bit compiler\"");
+ WriteDestFileLn("#endif");
+ break;
+ case gbk_cpufam_x64:
+ WriteDestFileLn("#ifdef __i386__");
+ WriteDestFileLn("#error \"source is configured for"
+ " 64 bit compiler\"");
+ WriteDestFileLn("#endif");
+ break;
+ }
+ }
+
+ WriteBlankLineToDestFile();
+
+#if NeedIntFormatInfo
+ WriteCompCondBool("MostSigByteFirst",
+ (gbk_cpufam_68k == gbo_cpufam)
+ || (gbk_cpufam_ppc == gbo_cpufam));
+ WriteCompCondBool("LeastSigByteFirst",
+ (gbk_cpufam_x86 == gbo_cpufam)
+ || (gbk_cpufam_x64 == gbo_cpufam));
+ WriteCompCondBool("TwosCompSigned",
+ (gbk_cpufam_68k == gbo_cpufam)
+ || (gbk_cpufam_ppc == gbo_cpufam)
+ || (gbk_cpufam_x86 == gbo_cpufam)
+ || (gbk_cpufam_x64 == gbo_cpufam));
+#endif
+
+ if (gbk_cpufam_68k == gbo_cpufam) {
+ WriteDestFileLn("#define HaveCPUfamM68K 1");
+ }
+
+ if ((gbk_ide_bgc == cur_ide)
+ || (gbk_ide_xcd == cur_ide)
+ || (gbk_ide_mvc == cur_ide)
+ || (gbk_ide_cyg == cur_ide)
+ || (gbk_ide_dkp == cur_ide))
+ {
+ WriteDestFileLn(
+ "#define MayInline inline __attribute__((always_inline))");
+ } else
+ if (gbk_ide_snc == cur_ide) {
+ WriteDestFileLn("#define MayInline inline");
+ } else
+ if (gbk_ide_mw8 == cur_ide) {
+ WriteDestFileLn("#define MayInline __inline__");
+ } else
+ if (gbk_ide_msv == cur_ide) {
+ if (ide_vers >= 6000) {
+ WriteDestFileLn("#define MayInline __forceinline");
+ } else {
+ WriteDestFileLn("#define MayInline __inline");
+ }
+ } else
+ {
+ /* WriteDestFileLn("#define MayInline"); */
+ }
+
+ if ((gbk_ide_bgc == cur_ide)
+ || (gbk_ide_xcd == cur_ide)
+ || (gbk_ide_mvc == cur_ide)
+ || (gbk_ide_cyg == cur_ide)
+ || (gbk_ide_dkp == cur_ide))
+ {
+ WriteDestFileLn(
+ "#define MayNotInline __attribute__((noinline))");
+ } else
+ if ((gbk_ide_msv == cur_ide) && (ide_vers >= 7000)) {
+ WriteDestFileLn("#define MayNotInline __declspec(noinline)");
+ } else
+ {
+ /* WriteDestFileLn("#define MayNotInline"); */
+ }
+
+ if (gbk_ide_mvc == cur_ide) {
+ if ((gbk_cpufam_68k == gbo_cpufam)
+ || (gbk_cpufam_ppc == gbo_cpufam))
+ {
+ WriteDestFileLn("#define BigEndianUnaligned 1");
+ WriteDestFileLn("#define LittleEndianUnaligned 0");
+ } else if ((gbk_cpufam_x86 == gbo_cpufam)
+ || (gbk_cpufam_x64 == gbo_cpufam))
+ {
+ WriteDestFileLn("#define BigEndianUnaligned 0");
+ WriteDestFileLn("#define LittleEndianUnaligned 1");
+ } else {
+ WriteDestFileLn("#define BigEndianUnaligned 0");
+ WriteDestFileLn("#define LittleEndianUnaligned 0");
+ }
+
+ if (gbk_cpufam_x86 == gbo_cpufam) {
+ WriteDestFileLn(
+ "#define my_reg_call __attribute__ ((regparm(3)))");
+ }
+
+ if (gbk_cpufam_x86 == gbo_cpufam) {
+ WriteDestFileLn(
+ "#define my_osglu_call __attribute__ "
+ "((force_align_arg_pointer))");
+ }
+
+ WriteDestFileLn("#define my_cond_rare(x) "
+ "(__builtin_expect(x, 0))");
+ WriteDestFileLn("#define Have_ASR 1");
+ if (gbk_cpufam_x64 == gbo_cpufam) {
+ WriteDestFileLn("#define HaveUi6Div 1");
+ }
+ if (gbk_targ_wcar == cur_targ) {
+ WriteDestFileLn("#define HaveUi5to6Mul 0");
+ }
+ if ((gbk_cpufam_x64 == gbo_cpufam)
+ || (gbk_cpufam_ppc == gbo_cpufam)
+ || (gbk_cpufam_arm == gbo_cpufam))
+ {
+ WriteDestFileLn("#define HaveGlbReg 1");
+ }
+ WriteDestFileLn(
+ "#define my_align_8 __attribute__ ((aligned (8)))");
+ }
+
+ WriteCompCondBool("SmallGlobals", gbk_cpufam_68k == gbo_cpufam);
+
+ if ((gbk_ide_bgc == cur_ide)
+ || (gbk_ide_xcd == cur_ide)
+ || (gbk_ide_mvc == cur_ide)
+ || (gbk_ide_ccc == cur_ide)
+ || (gbk_ide_dvc == cur_ide)
+ || (gbk_ide_mgw == cur_ide)
+ || (gbk_ide_dmc == cur_ide)
+ || (gbk_ide_lcc == cur_ide)
+ || (gbk_ide_cyg == cur_ide)
+ || (gbk_ide_dkp == cur_ide)
+ )
+ {
+ WriteDestFileLn("#define cIncludeUnused 0");
+ } else {
+ WriteDestFileLn("#define cIncludeUnused 1");
+ }
+
+ if (gbk_ide_lcc == cur_ide) {
+ WriteDestFileLn("#define UnusedParam(x)");
+ } else {
+ WriteDestFileLn("#define UnusedParam(p) (void) p");
+ }
+
+ if (gbk_ide_msv == cur_ide) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("/* --- set up compiler options --- */");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("/* ignore integer conversion warnings */");
+ WriteDestFileLn(
+ "#pragma warning(disable : 4244 4761 4018 4245 4024 4305)");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("/* ignore unused inline warning */");
+ WriteDestFileLn("#pragma warning(disable : 4514 4714)");
+#if 0
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("/* ignore type redefinition warning */");
+ WriteDestFileLn("#pragma warning(disable : 4142)");
+#endif
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "/* ignore unary minus operator"
+ " applied to unsigned type warning */");
+ WriteDestFileLn("#pragma warning(disable : 4146)");
+
+ if (cur_mIIorIIX
+ || (em_cpu_vers >= 2))
+ {
+ /* C4127: conditional expression is constant */
+ /*
+ C4701: local variable may have been used without having
+ been initialized
+ */
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("/* more warnings */");
+ WriteDestFileLn("#pragma warning(disable : 4127 4701)");
+ }
+
+ } else if (gbk_ide_plc == cur_ide) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("#pragma warn(disable: 2135 2137)");
+ }
+
+ if (gbk_ide_mw8 == cur_ide) {
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("#ifdef OptForSpeed");
+ WriteDestFileLn("#pragma optimize_for_size off");
+ WriteDestFileLn("#endif");
+ }
+ }
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("/* --- integer types ---- */");
+
+ /*
+ define signed and unsigned integer types
+ for 8 bits, 16 bits, 32 bits, and so on.
+
+ the computer might not have integer types
+ of a given size. in this case should define
+ a type of correct size, such as a structure
+ type, even if the computer can't directly do
+ integer operations on it. then set
+ HaveReal?i?b to 0.
+ */
+
+ /* 8 bits */
+
+ /* (ui3b)0 - (ui3b)1 == (ui3b)255 */
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("typedef unsigned char ui3b;");
+ WriteDestFileLn("#define HaveRealui3b 1");
+
+ /* sizeof(si3b) == sizeof(ui3b) */
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("typedef signed char si3b;");
+ WriteDestFileLn("#define HaveRealsi3b 1");
+
+ /* 16 bits */
+
+ /* (ui4b)0 - (ui4b)1 == (ui4b)65535 */
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("typedef unsigned short ui4b;");
+ WriteDestFileLn("#define HaveRealui4b 1");
+
+ /* sizeof(si4b) == sizeof(ui4b) */
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("typedef short si4b;");
+ WriteDestFileLn("#define HaveRealsi4b 1");
+
+ /* 32 bits */
+
+ /* (ui5b)0 - (ui5b)1 == (ui5b)4294967295 */
+ WriteBlankLineToDestFile();
+ if (gbk_cpufam_x64 == gbo_cpufam) {
+ WriteDestFileLn("typedef unsigned int ui5b;");
+ } else {
+ WriteDestFileLn("typedef unsigned long ui5b;");
+ }
+ WriteDestFileLn("#define HaveRealui5b 1");
+
+ /* sizeof(si5b) == sizeof(ui5b) */
+ WriteBlankLineToDestFile();
+ if (gbk_cpufam_x64 == gbo_cpufam) {
+ WriteDestFileLn("typedef int si5b;");
+ } else {
+ WriteDestFileLn("typedef long si5b;");
+ }
+ WriteDestFileLn("#define HaveRealsi5b 1");
+
+ /* 64 bits */ /* this is mostly for illustration, not used */
+#if 0
+ struct ui6b {
+ ui5b f0;
+ ui5b f1;
+ };
+ typedef struct ui6b ui6b;
+
+ struct si6b {
+ ui5b f0;
+ si5b f1;
+ };
+ typedef struct si6b si6b;
+#endif
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("#define HaveRealui6b 0");
+ WriteDestFileLn("#define HaveRealsi6b 0");
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("/* --- integer representation types ---- */");
+
+ /*
+ for each integer type, define
+ the most efficient representation
+ for parameter passing and temporary
+ variables on the current
+ computer.
+ */
+
+ WriteBlankLineToDestFile();
+#if ModPPCi3rTypes
+ if (gbk_cpufam_ppc == gbo_cpufam) {
+ WriteDestFileLn("typedef ui5b ui3r;");
+ WriteDestFileLn("#define ui3beqr 0");
+ } else
+#endif
+ {
+ WriteDestFileLn("typedef ui3b ui3r;");
+ WriteDestFileLn("#define ui3beqr 1");
+ }
+
+ WriteBlankLineToDestFile();
+#if ModPPCi3rTypes
+ if (gbk_cpufam_ppc == gbo_cpufam) {
+ WriteDestFileLn("typedef si5b si3r;");
+ WriteDestFileLn("#define si3beqr 0");
+ } else
+#endif
+ {
+ WriteDestFileLn("typedef si3b si3r;");
+ WriteDestFileLn("#define si3beqr 1");
+ }
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("typedef ui4b ui4r;");
+ WriteDestFileLn("#define ui4beqr 1");
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("typedef si4b si4r;");
+ WriteDestFileLn("#define si4beqr 1");
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("typedef ui5b ui5r;");
+ WriteDestFileLn("#define ui5beqr 1");
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("typedef si5b si5r;");
+ WriteDestFileLn("#define si5beqr 1");
+
+ if (gbk_ide_mvc == cur_ide) {
+ if (gbk_cpufam_x86 == gbo_cpufam)
+ {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("/* for probable register parameters */");
+ WriteDestFileLn("#define ui4rr ui5r");
+ WriteDestFileLn("#define ui3rr ui5r");
+ } else if (gbk_cpufam_x64 == gbo_cpufam) {
+#if 0
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("/* for probable register parameters */");
+ WriteDestFileLn("#define ui4rr unsigned long int");
+ WriteDestFileLn("#define ui3rr unsigned long int");
+#endif
+ WriteDestFileLn("#define si5rr signed long");
+ }
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "#define MySwapUi5r(x) ((ui5r)__builtin_bswap32(x))");
+ WriteDestFileLn("#define HaveMySwapUi5r 1");
+ }
+}
+
+LOCALPROC Write64bitConfig(void)
+{
+ WriteBlankLineToDestFile();
+ if (gbk_ide_msv == cur_ide) {
+ WriteDestFileLn("typedef signed __int64 si6r;");
+ WriteDestFileLn("typedef signed __int64 si6b;");
+ WriteDestFileLn("typedef unsigned __int64 ui6r;");
+ WriteDestFileLn("typedef unsigned __int64 ui6b;");
+ WriteDestFileLn("#define LIT64(a) a##Ui64");
+ } else {
+ WriteDestFileLn("typedef signed long long si6r;");
+ WriteDestFileLn("typedef signed long long si6b;");
+ WriteDestFileLn("typedef unsigned long long ui6r;");
+ WriteDestFileLn("typedef unsigned long long ui6b;");
+ WriteDestFileLn("#define LIT64(a) a##ULL");
+ }
+}
--- /dev/null
+++ b/setup/WRDMCFLS.i
@@ -1,0 +1,100 @@
+/*
+ WRDMCFLS.i
+ Copyright (C) 2010 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite Digital Mars Compiler specific FiLeS
+*/
+
+
+LOCALPROC WriteMainRsrcObjDMCbuild(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("rcc.exe -o");
+ WriteMainRsrcObjPath();
+ WriteSpaceToDestFile();
+ WriteMainRsrcSrcPath();
+ WriteCStrToDestFile(" -I");
+ Write_src_d_ToDestFile();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteDMCclMakeFile(void)
+{
+ WriteDestFileLn("# make file generated by gryphel build system");
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptions = -c -r -WA");
+ /* -o+space seems to generate bad code, compiler version 8.42n */
+ WriteCStrToDestFile(" -I");
+ Write_cfg_d_ToDestFile();
+ WriteCStrToDestFile(" -I");
+ Write_src_d_ToDestFile();
+ WriteEndDestFileLn();
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("TheDefaultOutput:");
+ WriteMakeDependFile(WriteAppNamePath);
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ WriteBlankLineToDestFile();
+ DoAllSrcFilesWithSetup(DoSrcFileMakeCompile);
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("ObjFiles = \\");
+ ++DestFileIndent;
+ DoAllSrcFilesStandardMakeObjects();
+ WriteBlankLineToDestFile();
+ --DestFileIndent;
+
+ WriteBlankLineToDestFile();
+ WriteMakeRule(WriteMainRsrcObjPath,
+ WriteMainRsrcObjMSCdeps, WriteMainRsrcObjDMCbuild);
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteAppNamePath();
+ WriteCStrToDestFile(": $(ObjFiles) ");
+ WriteMainRsrcObjPath();
+ WriteEndDestFileLn();
+
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(
+ "dmc.exe -L/exet:nt/su:windows:4.0 $(ObjFiles) ");
+ WriteMainRsrcObjPath();
+ WriteCStrToDestFile(" -o\"");
+ WriteAppNamePath();
+ WriteCStrToDestFile(
+ "\" winmm.lib ole32.lib uuid.lib comdlg32.lib shell32.lib"
+ " gdi32.lib");
+ WriteEndDestFileLn();
+ --DestFileIndent;
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("clean:");
+ ++DestFileIndent;
+ DoAllSrcFilesStandardErase();
+ WriteRmFile(WriteMainRsrcObjPath);
+ WriteRmFile(WriteAppNamePath);
+ --DestFileIndent;
+}
+
+LOCALPROC WriteDMCSpecificFiles(void)
+{
+ WriteADstFile1("my_project_d",
+ "Makefile", "", "Make file",
+ WriteDMCclMakeFile);
+}
--- /dev/null
+++ b/setup/WRDVCFLS.i
@@ -1,0 +1,170 @@
+/*
+ WRDVCFLS.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite bloodshed DeV-C++ specific FiLeS
+*/
+
+
+static void DoSrcFileDvcAddFile(void)
+{
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("[Unit");
+ WriteUnsignedToOutput(FileCounter + 1);
+ WriteCStrToDestFile("]");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("FileName=");
+ WriteSrcFileFilePath();
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("CompileCpp=0");
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Folder=");
+ WriteAppVariationStr();
+ WriteEndDestFileLn();
+ WriteDestFileLn("Compile=1");
+ WriteDestFileLn("Link=1");
+ WriteDestFileLn("Priority=1000");
+ WriteDestFileLn("OverrideBuildCmd=0");
+ WriteDestFileLn("BuildCmd=");
+}
+
+LOCALPROC WriteDevCProjectFile(void)
+{
+ WriteDestFileLn("[Project]");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("FileName=");
+ WriteStrAppAbbrev();
+ WriteCStrToDestFile(".dev");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Name=");
+ WriteAppVariationStr();
+ WriteEndDestFileLn();
+
+ DoAllSrcFilesWithSetup(NullProc);
+ ++FileCounter; /* main.rc */
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("UnitCount=");
+ WriteUnsignedToOutput(FileCounter);
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("Type=0");
+ WriteDestFileLn("Ver=1");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Includes=");
+ Write_cfg_d_ToDestFile();
+ WriteCStrToDestFile(" ");
+ Write_src_d_ToDestFile();
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("PrivateResource=");
+ WriteAppVariationStr();
+ WriteCStrToDestFile("_private.rc");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("ResourceIncludes=");
+ Write_src_d_ToDestFile();
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("IsCpp=0");
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("ObjectOutput=");
+ Write_obj_d_ToDestFile();
+ WriteEndDestFileLn();
+ WriteDestFileLn("OverrideOutput=1");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("OverrideOutputName=");
+ WriteAppNamePath();
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("IncludeVersionInfo=0");
+ WriteDestFileLn("CompilerSet=0");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteDestFileLn("CompilerSettings=000000000000000100");
+ WriteDestFileLn(
+ "Compiler= -Wall -Wstrict-prototypes"
+ " -Wno-uninitialized -O0_@@_");
+ } else {
+ WriteDestFileLn("CompilerSettings=000000000000000000");
+ WriteDestFileLn(
+ "Compiler= -Wall -Wstrict-prototypes"
+ " -Wno-uninitialized -Os_@@_");
+ }
+ WriteDestFileLn("Linker=-lwinmm -lole32 -luuid_@@_");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("[VersionInfo]");
+ WriteDestFileLn("Major=0");
+ WriteDestFileLn("Minor=1");
+ WriteDestFileLn("Release=1");
+ WriteDestFileLn("Build=1");
+ WriteDestFileLn("LanguageID=1033");
+ WriteDestFileLn("CharsetID=1252");
+ WriteDestFileLn("CompanyName=");
+ WriteDestFileLn("FileVersion=");
+ WriteDestFileLn("FileDescription=Developed using the Dev-C++ IDE");
+ WriteDestFileLn("InternalName=");
+ WriteDestFileLn("LegalCopyright=");
+ WriteDestFileLn("LegalTrademarks=");
+ WriteDestFileLn("OriginalFilename=");
+ WriteDestFileLn("ProductName=");
+ WriteDestFileLn("ProductVersion=");
+ WriteDestFileLn("AutoIncBuildNr=0");
+
+ DoAllSrcFilesWithSetup(DoSrcFileDvcAddFile);
+
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("[Unit");
+ WriteUnsignedToOutput(++FileCounter);
+ WriteCStrToDestFile("]");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("FileName=");
+ WriteMainRsrcSrcPath();
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("CompileCpp=0");
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Folder=");
+ WriteAppVariationStr();
+ WriteEndDestFileLn();
+ WriteDestFileLn("Compile=1");
+ WriteDestFileLn("Link=0");
+ WriteDestFileLn("Priority=1000");
+ WriteDestFileLn("OverrideBuildCmd=0");
+ WriteDestFileLn("BuildCmd=");
+
+ WriteBlankLineToDestFile();
+}
+
+LOCALPROC WriteDevCSpecificFiles(void)
+{
+ WriteADstFile1("my_project_d",
+ vStrAppAbbrev, ".dev", "Project file",
+ WriteDevCProjectFile);
+}
--- /dev/null
+++ b/setup/WRLCCFLS.i
@@ -1,0 +1,252 @@
+/*
+ WRLCCFLS.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite LCC-win32 specific FiLeS
+*/
+
+
+LOCALPROC DoSrcFileLccAddFile(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("File");
+ WriteUnsignedToOutput(FileCounter + 1);
+ WriteCStrToDestFile("=");
+ WriteSrcFileFilePath();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteLccErrFileName(void)
+{
+ WriteStrAppAbbrev();
+ WriteCStrToDestFile(".err");
+}
+
+LOCALPROC WriteLccErrFilePath(void)
+{
+ WriteFileInDirToDestFile0(Write_obj_d_ToDestFile,
+ WriteLccErrFileName);
+}
+
+LOCALPROC WriteLccW32WorkSpaceFile(void)
+{
+ WriteDestFileLn("; Wedit project file. Syntax: Name = value");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("[");
+ WriteAppVariationStr();
+ WriteCStrToDestFile("]");
+ WriteEndDestFileLn();
+
+ DoAllSrcFilesWithSetup(NullProc);
+ ++FileCounter; /* main.rc */
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("PrjFiles=");
+ WriteUnsignedToOutput(FileCounter);
+ WriteEndDestFileLn();
+
+ DoAllSrcFilesWithSetup(DoSrcFileLccAddFile);
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("File");
+ WriteUnsignedToOutput(++FileCounter);
+ WriteCStrToDestFile("=");
+ WriteMainRsrcSrcPath();
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("ProjectFlags=0");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Name=");
+ WriteAppVariationStr();
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("ProjectPath=");
+ WriteCStrToDestFile("c:\\output");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("SourcesDir=");
+ /* setting it to my_c_src_d does not work */
+ WriteCStrToDestFile("c:\\output");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Includes=");
+ Write_cfg_d_ToDestFile();
+ WriteCStrToDestFile(" ");
+ Write_src_d_ToDestFile();
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("MakeDir=");
+ Write_obj_d_ToDestFile();
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Exe=");
+ WriteAppNamePath();
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("DbgExeName=");
+ WriteAppNamePath();
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("DbgDir=");
+ Write_obj_d_ToDestFile();
+ WriteEndDestFileLn();
+
+ switch (gbo_dbg) {
+ case gbk_dbg_on:
+ WriteDestFileLn("CompilerFlags=6728");
+ break;
+ case gbk_dbg_test:
+ WriteDestFileLn("CompilerFlags=580");
+ break;
+ case gbk_dbg_off:
+ WriteDestFileLn("CompilerFlags=581");
+ break;
+ }
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Libraries=");
+ WriteCStrToDestFile("shell32.lib ole32.lib uuid.lib winmm.lib");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("ErrorFile=");
+ WriteLccErrFilePath();
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("CurrentFile=");
+ WriteCNFGGLOBPath();
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("OpenFiles=1");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("OpenFile1=");
+ WriteQuoteToDestFile();
+ WriteCNFGGLOBPath();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" 1 29 14 532 435");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteLccW32SpecificFiles(void)
+{
+ WriteADstFile1("my_project_d",
+ vStrAppAbbrev, ".prj", "Project file",
+ WriteLccW32WorkSpaceFile);
+}
+
+
+LOCALPROC WriteMainRsrcObjLccbuild(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("lrc.exe -fo");
+ WriteMainRsrcObjPath();
+ WriteSpaceToDestFile();
+ WriteMainRsrcSrcPath();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteLccW32clMakeFile(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(
+ "# make file generated by gryphel build system");
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptions= -c");
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteCStrToDestFile(" -O");
+ } else {
+ WriteCStrToDestFile(" -g4");
+ }
+ WriteCStrToDestFile(" -A");
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("TheDefaultOutput:");
+ WriteMakeDependFile(WriteAppNamePath);
+ WriteEndDestFileLn();
+ WriteBlankLineToDestFile();
+ WriteBlankLineToDestFile();
+ DoAllSrcFilesWithSetup(DoSrcFileMakeCompile);
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("ObjFiles=\\");
+ ++DestFileIndent;
+ DoAllSrcFilesStandardMakeObjects();
+ WriteBlankLineToDestFile();
+ --DestFileIndent;
+
+ WriteBlankLineToDestFile();
+ WriteBlankLineToDestFile();
+ WriteMakeRule(WriteMainRsrcObjPath,
+ WriteMainRsrcObjMSCdeps, WriteMainRsrcObjLccbuild);
+ WriteBlankLineToDestFile();
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteAppNamePath();
+ WriteCStrToDestFile(": $(ObjFiles) ");
+ WriteMainRsrcObjPath();
+ WriteEndDestFileLn();
+
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("lcclnk.exe");
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteCStrToDestFile(" -s");
+ }
+ WriteCStrToDestFile(" -subsystem windows -o ");
+ WriteAppNamePath();
+ WriteCStrToDestFile(" $(ObjFiles) ");
+ WriteMainRsrcObjPath();
+ WriteCStrToDestFile(" \\");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteDestFileLn(
+ "shell32.lib winmm.lib ole32.lib uuid.lib");
+ --DestFileIndent;
+ --DestFileIndent;
+ WriteBlankLineToDestFile();
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("clean:");
+ ++DestFileIndent;
+ DoAllSrcFilesStandardErase();
+ WriteRmFile(WriteMainRsrcObjPath);
+ WriteRmFile(WriteAppNamePath);
+ --DestFileIndent;
+}
+
+LOCALPROC WriteLccW32clSpecificFiles(void)
+{
+ WriteADstFile1("my_project_d",
+ "Makefile", "", "Make file",
+ WriteLccW32clMakeFile);
+}
--- /dev/null
+++ b/setup/WRMACRES.i
@@ -1,0 +1,321 @@
+/*
+ WRMACRES.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite MACintosh RESources configuration
+*/
+
+
+LOCALPROC WriteBeginResResource(char *types, int id)
+{
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("resource '");
+ WriteCStrToDestFile(types);
+ WriteSingleQuoteToDestFile();
+ WriteCStrToDestFile(" (");
+ WriteUnsignedToOutput(id);
+ WriteCStrToDestFile(") {");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+}
+
+LOCALPROC WriteEndResResource(void)
+{
+ --DestFileIndent;
+ WriteDestFileLn("};");
+}
+
+LOCALPROC WriteQuotedInclude(char *name)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#include ");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(name);
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteResTypeComma(char *types)
+{
+ WriteBgnDestFileLn();
+ WriteSingleQuoteToDestFile();
+ WriteCStrToDestFile(types);
+ WriteSingleQuoteToDestFile();
+ WriteCStrToDestFile(",");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteAFREFres(char *types, int i)
+{
+ WriteBeginResResource("FREF", 128 + i);
+ WriteResTypeComma(types);
+
+ WriteBgnDestFileLn();
+ WriteUnsignedToOutput(i);
+ WriteCStrToDestFile(",");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteQuoteToDestFile();
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+ WriteEndResResource();
+}
+
+LOCALPROC WriteDocTypeDefIconId(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#define ");
+ WriteDocTypeIconShortName();
+ WriteCStrToDestFile("IconId ");
+ WriteUnsignedToOutput(128 + DocTypeCounter);
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteDocTypeFREFres(void)
+{
+ WriteAFREFres(DoDocType_gd()->MacType, DocTypeCounter);
+}
+
+LOCALPROC WriteDocTypeBNDLFREF(void)
+{
+ WriteBgnDestFileLn();
+ if (0 != DocTypeCounter) {
+ WriteCStrToDestFile(",");
+ }
+ WriteUnsignedToOutput(DocTypeCounter);
+ WriteCStrToDestFile(", ");
+ WriteUnsignedToOutput(128 + DocTypeCounter);
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteDocTypeBNDLICN(void)
+{
+ WriteBgnDestFileLn();
+ if (0 != DocTypeCounter) {
+ WriteCStrToDestFile(",");
+ }
+ WriteUnsignedToOutput(DocTypeCounter);
+ WriteCStrToDestFile(", ");
+ WriteDocTypeIconShortName();
+ WriteCStrToDestFile("IconId");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteDocTypeIncludeIconFile(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("#include ");
+ WriteQuoteToDestFile();
+ WriteDocTypeIconFileName();
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteMacResConfigContents(void)
+{
+ WriteBlankLineToDestFile();
+ if (gbk_ide_mw8 == cur_ide) {
+ if (gbk_targfam_mach == gbo_targfam) {
+ WriteDestFileLn("#include <Carbon/Carbon.r>");
+ } else {
+ WriteQuotedInclude("Types.r");
+ WriteQuotedInclude("Icons.r");
+ }
+ } else
+ if ((gbk_ide_bgc == cur_ide)
+ || (gbk_ide_xcd == cur_ide)
+ || (gbk_ide_mvc == cur_ide))
+ {
+ WriteQuotedInclude("Carbon.r");
+ } else
+ if (gbk_ide_mpw == cur_ide) {
+ WriteQuotedInclude("Types.r");
+ WriteQuotedInclude("Icons.r");
+ }
+
+ WriteBlankLineToDestFile();
+
+ WriteCDefQuote("kStrAppName", WriteStrAppUnabrevName);
+ WriteCDefQuote("kAppVariationStr", WriteAppVariationStr);
+ WriteCDefQuote("kStrCopyrightYear", WriteAppCopyrightYearStr);
+ WriteCDefQuote("kStrHomePage", WriteHomePage);
+
+ if (gbk_targfam_mach != gbo_targfam) {
+ if (gbk_targfam_carb == gbo_targfam) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("data 'plst' (0) {");
+ ++DestFileIndent;
+ WriteDestFileLn("$\"00\"");
+ --DestFileIndent;
+ WriteDestFileLn("};");
+ }
+
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("data '");
+ WriteCStrToDestFile(kMacCreatorSig);
+ WriteCStrToDestFile("' (0, \"Owner resource\") {");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteDestFileLn("$\"00\"");
+ --DestFileIndent;
+ WriteDestFileLn("};");
+
+ WriteBeginResResource("vers", 1);
+ WriteBgnDestFileLn();
+ WriteDec2CharToOutput(MajorVersion);
+ WriteCStrToDestFile(",");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteDec2CharToOutput(MinorVersion);
+#if 0
+ WriteCStrToDestFile(" * 16 + ");
+ WriteCStrToDestFile(kMinorSubVersion);
+#endif
+ WriteCStrToDestFile(",");
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("release,");
+ WriteDestFileLn("0x0,");
+ WriteDestFileLn("0,");
+
+ WriteBgnDestFileLn();
+ WriteQuoteToDestFile();
+ WriteVersionStr();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(",");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteQuoteToDestFile();
+ WriteGetInfoString();
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+ WriteEndResResource();
+
+#if 0
+ WriteBeginResResource("vers", 2);
+ WriteDestFileLn("0x0,");
+ WriteDestFileLn("0x0,");
+ WriteDestFileLn("release,");
+ WriteDestFileLn("0x0,");
+ WriteDestFileLn("0,");
+ WriteBgnDestFileLn();
+ WriteQuoteToDestFile();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(",");
+ WriteEndDestFileLn();
+ WriteBgnDestFileLn();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(kShortDescription);
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+ WriteEndResResource();
+#endif
+
+ if (gbk_ide_mw8 != cur_ide) {
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("resource 'SIZE' (-1) {");
+ ++DestFileIndent;
+ WriteDestFileLn("reserved,");
+ WriteDestFileLn("acceptSuspendResumeEvents,");
+ WriteDestFileLn("reserved,");
+ WriteDestFileLn("canBackground,");
+ WriteDestFileLn("multiFinderAware,");
+ WriteDestFileLn("backgroundAndForeground,");
+ WriteDestFileLn("dontGetFrontClicks,");
+ WriteDestFileLn("ignoreChildDiedEvents,");
+ WriteDestFileLn("is32BitCompatible,");
+
+ /*
+ following 4 should be "reserved"
+ if api not available
+ */
+ WriteDestFileLn("isHighLevelEventAware,");
+ WriteDestFileLn("localAndRemoteHLEvents,");
+ WriteDestFileLn("isStationeryAware,");
+ WriteDestFileLn("useTextEditServices,");
+
+ WriteDestFileLn("reserved,");
+ WriteDestFileLn("reserved,");
+ WriteDestFileLn("reserved,");
+
+ WriteBgnDestFileLn();
+ WriteUnsignedToOutput(TotMemSize + (2UL * 1024 * 1024));
+ WriteCStrToDestFile(",");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteUnsignedToOutput(TotMemSize + (512UL * 1024));
+ WriteEndDestFileLn();
+ WriteEndResResource();
+ }
+
+ WriteBlankLineToDestFile();
+ DoAllDocTypesWithSetup(WriteDocTypeDefIconId);
+
+
+ DoAllDocTypesWithSetup(WriteDocTypeFREFres);
+ WriteAFREFres("****", DocTypeCounter);
+
+ WriteBeginResResource("BNDL", 128);
+ WriteResTypeComma(kMacCreatorSig);
+
+ WriteDestFileLn("0,");
+ WriteDestFileLn("{");
+ ++DestFileIndent;
+ WriteResTypeComma("FREF");
+
+ WriteDestFileLn("{");
+ ++DestFileIndent;
+ DoAllDocTypesWithSetup(WriteDocTypeBNDLFREF);
+ WriteDocTypeBNDLFREF();
+ --DestFileIndent;
+ WriteDestFileLn("},");
+
+ WriteResTypeComma("ICN#");
+
+ WriteDestFileLn("{");
+ ++DestFileIndent;
+ DoAllDocTypesWithSetup(WriteDocTypeBNDLICN);
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(",");
+ WriteUnsignedToOutput(DocTypeCounter);
+ WriteCStrToDestFile(", 0");
+ WriteEndDestFileLn();
+ --DestFileIndent;
+ WriteDestFileLn("}");
+ --DestFileIndent;
+ WriteDestFileLn("}");
+ WriteEndResResource();
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("#define SmallIconAPIAvail 1");
+ WriteDestFileLn("#define ColorIconAPIAvail 1");
+
+ WriteBlankLineToDestFile();
+ DoAllDocTypesWithSetup(WriteDocTypeIncludeIconFile);
+ }
+}
+
+LOCALPROC WriteCommonCNFGRSRC(void)
+{
+ WriteADstFile1("my_config_d",
+ "CNFGRSRC", ".h", " Configuration file",
+ WriteMacResConfigContents);
+}
--- /dev/null
+++ b/setup/WRMPLIST.i
@@ -1,0 +1,314 @@
+/*
+ WRMPLIST.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite Macintosh PLIST
+*/
+
+
+enum {
+ kPListRaw, /* native plist data */
+ kPListPLC, /* metrowerks property list compiler */
+ kNumPListFormats
+};
+
+LOCALVAR int CurPListFormat = kPListPLC;
+
+LOCALPROC WritePListProcString(MyProc p)
+{
+ if (CurPListFormat == kPListRaw) {
+ WriteXMLtagBeginProcValEndLine("string", p);
+ } else {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("string ");
+ WriteQuoteToDestFile();
+ p();
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+ }
+}
+
+LOCALPROC WritePListString(char *s)
+{
+ MyPtr SavepDt = pDt;
+
+ pDt = (MyPtr)s;
+ WritePListProcString(WritepDtString);
+ pDt = SavepDt;
+}
+
+LOCALPROC WritePListKeyProcString(char *k, MyProc p)
+{
+ if (CurPListFormat == kPListRaw) {
+ WriteXMLtagBeginValEndLine("key", k);
+ WriteXMLtagBeginProcValEndLine("string", p);
+ } else {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("key ");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(k);
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" value string ");
+ WriteQuoteToDestFile();
+ p();
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+ }
+}
+
+LOCALPROC WritePListKeyString(char *k, char *s)
+{
+ MyPtr SavepDt = pDt;
+
+ pDt = (MyPtr)s;
+ WritePListKeyProcString(k, WritepDtString);
+ pDt = SavepDt;
+}
+
+LOCALPROC WritePListBeginKeyArray(char *k)
+{
+ if (CurPListFormat == kPListRaw) {
+ WriteXMLtagBeginValEndLine("key", k);
+ WriteBeginXMLtagLine("array");
+ } else {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("key ");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(k);
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" value array");
+ WriteEndDestFileLn();
+ WriteDestFileLn("[");
+ ++DestFileIndent;
+ }
+}
+
+LOCALPROC WritePListEndKeyArray(void)
+{
+ if (CurPListFormat == kPListRaw) {
+ WriteEndXMLtagLine("array");
+ } else {
+ --DestFileIndent;
+ WriteDestFileLn("]");
+ }
+}
+
+LOCALPROC WritePListBeginDict(void)
+{
+ if (CurPListFormat == kPListRaw) {
+ WriteBeginXMLtagLine("dict");
+ } else {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("dictionary");
+ WriteEndDestFileLn();
+ WriteDestFileLn("{");
+ ++DestFileIndent;
+ }
+}
+
+LOCALPROC WritePListEndDict(void)
+{
+ if (CurPListFormat == kPListRaw) {
+ WriteEndXMLtagLine("dict");
+ } else {
+ --DestFileIndent;
+ WriteDestFileLn("}");
+ }
+}
+
+LOCALPROC WriteInfoPList(MyProc p)
+{
+ CurPListFormat = kPListRaw;
+
+ WriteDestFileLn("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+#if 0
+ WriteDestFileLn(
+ "<!DOCTYPE plist SYSTEM \"file://"
+ "localhost/System/Library/DTDs/PropertyList.dtd\">");
+ WriteDestFileLn("<plist version=\"0.9\">");
+#else
+ if ((gbk_ide_xcd == cur_ide) && (ide_vers >= 3100)) {
+ WriteDestFileLn(
+ "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\""
+ " \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
+ } else {
+ WriteDestFileLn(
+ "<!DOCTYPE plist PUBLIC \"-//"
+ "Apple Computer//DTD PLIST 1.0//EN\""
+ " \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
+ }
+ WriteDestFileLn("<plist version=\"1.0\">");
+#endif
+
+ p();
+
+ WriteDestFileLn("</plist>");
+}
+
+LOCALPROC WriteMainPLC(MyProc p)
+{
+ CurPListFormat = kPListPLC;
+
+ WriteDestFileLn("plist");
+ WriteDestFileLn("{");
+ ++DestFileIndent;
+
+ p();
+
+ --DestFileIndent;
+ WriteDestFileLn("}");
+}
+
+LOCALPROC WritepDtIconTypeName(void)
+{
+ WriteStrAppUnabrevName();
+ WriteSpaceToDestFile();
+ WriteCStrToDestFile(DoDocType_gd()->LongName);
+}
+
+LOCALPROC WriteOneExtension2Array(char *s)
+{
+ WritePListString(s);
+}
+
+LOCALPROC WriteOneCFBundleDocumentType(void)
+{
+ if (0 != DocTypeCounter) {
+ WritePListBeginDict();
+ if (DoDocType_gd()->WriteExtensionList != nullpr) {
+ WritePListBeginKeyArray("CFBundleTypeExtensions");
+ DoDocType_gd()->WriteExtensionList(
+ WriteOneExtension2Array);
+ WritePListEndKeyArray();
+ }
+ WritePListKeyProcString("CFBundleTypeIconFile",
+ WriteDocTypeIconFileName);
+ WritePListKeyProcString("CFBundleTypeName",
+ WritepDtIconTypeName);
+ WritePListBeginKeyArray("CFBundleTypeOSTypes");
+ WritePListProcString(WriteDocTypeIconMacType);
+ WritePListEndKeyArray();
+ WritePListKeyString("CFBundleTypeRole", "Editor");
+ WritePListEndDict();
+ }
+}
+
+LOCALPROC WriteTheBundleIdentifier(void)
+{
+ WriteCStrToDestFile(kBundleIdentifier);
+ if (WantIconMaster) {
+ WriteCStrToDestFile(".im");
+ }
+}
+
+LOCALPROC WriteMyInfoPListContents(void)
+{
+ WritePListBeginDict();
+
+ /* in order preferred by latest xcode (alphabetical) */
+
+ WritePListKeyString("CFBundleDevelopmentRegion", "English");
+
+ WritePListBeginKeyArray("CFBundleDocumentTypes");
+ WritePListBeginDict();
+ WritePListBeginKeyArray("CFBundleTypeOSTypes");
+ WritePListString("****");
+ WritePListEndKeyArray();
+ WritePListKeyString("CFBundleTypeRole", "Editor");
+ WritePListEndDict();
+ DoAllDocTypesWithSetup(WriteOneCFBundleDocumentType);
+ WritePListEndKeyArray();
+
+ WritePListKeyString("CFBundleExecutable", vStrAppAbbrev);
+ WritePListKeyProcString("CFBundleGetInfoString",
+ WriteGetInfoString);
+ WritePListKeyString("CFBundleIconFile", "ICONAPPO.icns");
+ WritePListKeyProcString("CFBundleIdentifier",
+ WriteTheBundleIdentifier);
+ WritePListKeyString("CFBundleInfoDictionaryVersion", "6.0");
+ WritePListKeyProcString("CFBundleName", WriteStrAppUnabrevName);
+ WritePListKeyString("CFBundlePackageType", "APPL");
+ WritePListKeyProcString("CFBundleShortVersionString",
+ WriteVersionStr);
+ WritePListKeyProcString("CFBundleSignature",
+ Write_MacCreatorSigOrGeneric);
+ WritePListKeyProcString("CFBundleVersion", WriteVersionStr);
+ WritePListKeyString("LSRequiresCarbon", "1");
+ if (gbk_apifam_cco == gbo_apifam) {
+ WritePListKeyString("NSHighResolutionCapable", "1");
+ }
+ if (WantGraphicsSwitching) {
+ WritePListKeyString("NSSupportsAutomaticGraphicsSwitching",
+ "1");
+ }
+ if (gbk_apifam_sd2 == gbo_apifam) {
+ WritePListKeyString("SDL_FILESYSTEM_BASE_DIR_TYPE",
+ "parent");
+ }
+
+ WritePListEndDict();
+}
+
+LOCALPROC WriteMainPLCData(void)
+{
+ /* plist source */
+ WriteMainPLC(WriteMyInfoPListContents);
+}
+
+LOCALPROC WriteInfoPListData(void)
+{
+ /* Info.plist file */
+ WriteInfoPList(WriteMyInfoPListContents);
+}
+
+LOCALPROC WritePListData(void)
+{
+ if (gbk_ide_mw8 == cur_ide) {
+ WriteADstFile1("my_config_d",
+ "main", ".plc", "plist source",
+ WriteMainPLCData);
+ } else
+ {
+ WriteADstFile1("my_config_d",
+ "Info", ".plist", "plist source",
+ WriteInfoPListData);
+ }
+}
+
+LOCALPROC WriteEntitlementsData(void)
+{
+ WriteOpenDestFile("my_config_d",
+ vStrAppAbbrev, ".entitlements", "entitlements");
+
+ WriteDestFileLn("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ WriteDestFileLn(
+ "<!DOCTYPE plist PUBLIC"
+ " \"-//Apple//DTD PLIST 1.0//EN\""
+ " \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
+ WriteDestFileLn("<plist version=\"1.0\">");
+ WriteDestFileLn("<dict>");
+ ++DestFileIndent;
+ WriteDestFileLn("<key>com.apple.security.app-sandbox</key>");
+ WriteDestFileLn("<true/>");
+ WriteDestFileLn("<key>"
+ "com.apple.security.files.user-selected.read-write"
+ "</key>");
+ WriteDestFileLn("<true/>");
+ --DestFileIndent;
+ WriteDestFileLn("</dict>");
+ WriteDestFileLn("</plist>");
+
+ WriteCloseDestFile();
+}
--- /dev/null
+++ b/setup/WRMPWFLS.i
@@ -1,0 +1,360 @@
+/*
+ WRMPWFLS.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite Macintosh Programmer's Workshop specific FiLeS
+*/
+
+
+LOCALPROC WriteLONGGLUEContents(void)
+{
+ ++DestFileIndent;
+ WriteDestFileLn("CASE ON");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("IMPORT long_main: CODE ");
+ WriteBlankLineToDestFile();
+ --DestFileIndent;
+ WriteDestFileLn("main PROC EXPORT");
+ ++DestFileIndent;
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("JMP (long_main).L");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("ENDP");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("END");
+ --DestFileIndent;
+}
+
+LOCALPROC WriteLongGlueObjName(void)
+{
+ WriteCStrToDestFile("LONGGLUE.o");
+}
+
+LOCALPROC WriteLongGlueObjPath(void)
+{
+ WriteFileInDirToDestFile0(Write_obj_d_ToDestFile,
+ WriteLongGlueObjName);
+}
+
+LOCALPROC WriteLongGlueSourceName(void)
+{
+ WriteCStrToDestFile("LONGGLUE.S");
+}
+
+LOCALPROC WriteLongGlueSourcePath(void)
+{
+ WriteFileInDirToDestFile0(Write_cfg_d_ToDestFile,
+ WriteLongGlueSourceName);
+}
+
+LOCALPROC DoLongGlueMakeCompileDeps(void)
+{
+ WriteMakeDependFile(WriteLongGlueSourcePath);
+}
+
+LOCALPROC DoLongGlueMakeCompileBody(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Asm");
+ WritePathArgInMakeCmnd(WriteLongGlueSourcePath);
+ WriteCStrToDestFile(" -o");
+ WritePathArgInMakeCmnd(WriteLongGlueObjPath);
+ WriteCStrToDestFile(" -model far");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC DoSrcFileMPWMakeObjects(void)
+{
+ WriteBgnDestFileLn();
+ WriteQuoteToDestFile();
+ WriteSrcFileObjPath();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" \266");
+ WriteEndDestFileLn();
+}
+
+static void WriteMPWCOptions(blnr fast)
+{
+ if (gbk_cpufam_68k == gbo_cpufam) {
+ WriteCStrToDestFile(" -proto strict -w 17 -align mac68k -b");
+ if (gbk_targ_mfpu == cur_targ) {
+ WriteCStrToDestFile(" -mc68020 -mc68881 -elems881");
+ }
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteCStrToDestFile(" -mbg off");
+ }
+ WriteCStrToDestFile(" -model farCode");
+ } else if (gbk_cpufam_ppc == gbo_cpufam) {
+ WriteCStrToDestFile(" -proto strict -w 17");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteCStrToDestFile(" -traceback");
+ }
+ }
+ if (gbk_dbg_on != gbo_dbg) {
+ if (fast) {
+ if (gbk_cpufam_68k == gbo_cpufam) {
+ WriteCStrToDestFile(" -opt speed");
+ } else if (gbk_cpufam_ppc == gbo_cpufam) {
+ WriteCStrToDestFile(" -opt speed");
+ }
+ } else {
+ if (gbk_cpufam_68k == gbo_cpufam) {
+ WriteCStrToDestFile(" -opt space");
+ } else if (gbk_cpufam_ppc == gbo_cpufam) {
+ WriteCStrToDestFile(" -opt size");
+ /* this may not be reliable? */
+ }
+ }
+ }
+
+ WriteCStrToDestFile(" -i ");
+ WriteQuoteToDestFile();
+ Write_cfg_d_ToDestFile();
+ WriteQuoteToDestFile();
+
+ WriteCStrToDestFile(" -i ");
+ WriteQuoteToDestFile();
+ Write_src_d_ToDestFile();
+ WriteQuoteToDestFile();
+}
+
+LOCALPROC WriteMainRsrcObjDeps(void)
+{
+ WriteMakeDependFile(WriteMainRsrcSrcPath);
+}
+
+LOCALPROC WriteMainRsrcObjMPWbody(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Rez -t rsrc -c RSED -i \"{RIncludes}\"");
+
+ WriteCStrToDestFile(" -i ");
+ WriteQuoteToDestFile();
+ Write_cfg_d_ToDestFile();
+ WriteQuoteToDestFile();
+
+ WriteCStrToDestFile(" -i ");
+ WriteQuoteToDestFile();
+ Write_src_d_ToDestFile();
+ WriteQuoteToDestFile();
+
+ WriteCStrToDestFile(" ");
+ WriteQuoteToDestFile();
+ WriteMainRsrcSrcPath();
+ WriteQuoteToDestFile();
+
+ WriteCStrToDestFile(" -o ");
+ WriteQuoteToDestFile();
+ WriteMainRsrcObjPath();
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteMPWMakeFile(void)
+{
+ WriteDestFileLn("# make file generated by gryphel build system");
+
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptions =");
+ WriteMPWCOptions(falseblnr);
+ WriteEndDestFileLn();
+ WriteBlankLineToDestFile();
+
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("TheDefaultOutput \304");
+ WriteMakeDependFile(Write_machobinpath_ToDestFile);
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+
+ if (gbk_cpufam_68k == gbo_cpufam) {
+ WriteMakeRule(WriteLongGlueObjPath,
+ DoLongGlueMakeCompileDeps,
+ DoLongGlueMakeCompileBody);
+ }
+
+ DoAllSrcFilesWithSetup(DoSrcFileMakeCompile);
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("ObjFiles = \266");
+ ++DestFileIndent;
+ DoAllSrcFilesSortWithSetup(DoSrcFileMPWMakeObjects);
+ WriteBlankLineToDestFile();
+ --DestFileIndent;
+
+ if (HaveMacBundleApp) {
+ WriteBlankLineToDestFile();
+ WriteMakeRule(Write_machoAppIconPath,
+ Write_tmachoShellDeps,
+ Write_tmachoShell);
+ }
+
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("\"");
+ Write_machobinpath_ToDestFile();
+ WriteCStrToDestFile("\" \304");
+ WriteCStrToDestFile(" {ObjFiles}");
+ if (HaveMacBundleApp) {
+ WriteMakeDependFile(Write_machoAppIconPath);
+ } else {
+ WriteMakeDependFile(WriteMainRsrcObjPath);
+ }
+ if (gbk_cpufam_68k == gbo_cpufam) {
+ WritePathArgInMakeCmnd(WriteLongGlueObjPath);
+ }
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ if (HaveMacRrscs) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Duplicate -y \"");
+ WriteMainRsrcObjPath();
+ WriteCStrToDestFile("\" \"");
+ Write_machobinpath_ToDestFile();
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+ }
+
+ WriteBgnDestFileLn();
+ if (gbk_cpufam_68k == gbo_cpufam) {
+ WriteCStrToDestFile("Link");
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteCStrToDestFile(" -rn");
+ }
+ WriteCStrToDestFile(
+ " -model far -sg Main"
+ "=STDCLIB,SANELIB,CSANELib,SADEV,STDIO");
+ } else if (gbk_cpufam_ppc == gbo_cpufam) {
+ WriteCStrToDestFile("PPCLink");
+ }
+
+ if (gbk_targ_carb == cur_targ) {
+ WriteCStrToDestFile(" -m main");
+ }
+ WriteCStrToDestFile(" -t APPL -c ");
+ WriteCStrToDestFile(kMacCreatorSig);
+ WriteCStrToDestFile(" \266");
+ WriteEndDestFileLn();
+
+ ++DestFileIndent;
+
+ WriteDestFileLn("{ObjFiles} \266");
+
+ if (gbk_targ_carb == cur_targ) {
+ WriteDestFileLn("\"{SharedLibraries}CarbonLib\" \266");
+#if UseOpenGLinOSX
+ WriteDestFileLn(
+ "\"{SharedLibraries}OpenGLLibraryStub\" \266");
+#endif
+ WriteDestFileLn("\"{PPCLibraries}PPCToolLibs.o\" \266");
+ WriteDestFileLn("\"{PPCLibraries}PPCCRuntime.o\" \266");
+ WriteDestFileLn("\"{SharedLibraries}StdCLib\" \266");
+ } else if (gbk_targ_mppc == cur_targ) {
+ WriteDestFileLn("\"{PPCLibraries}PPCToolLibs.o\" \266");
+ WriteDestFileLn("\"{PPCLibraries}PPCCRuntime.o\" \266");
+ WriteDestFileLn("\"{PPCLibraries}StdCRuntime.o\" \266");
+ WriteDestFileLn(
+ "\"{SharedLibraries}InterfaceLib\" \266");
+ WriteDestFileLn("\"{SharedLibraries}MathLib\" \266");
+ WriteDestFileLn("\"{SharedLibraries}StdCLib\" \266");
+ WriteDestFileLn("-weaklib AppearanceLib \266");
+ WriteDestFileLn(
+ "\"{SharedLibraries}AppearanceLib\" \266");
+ WriteDestFileLn("-weaklib MenusLib \266");
+ WriteDestFileLn("\"{SharedLibraries}MenusLib\" \266");
+ WriteDestFileLn("-weaklib NavigationLib \266");
+ WriteDestFileLn(
+ "\"{SharedLibraries}NavigationLib\" \266");
+ WriteDestFileLn("-weaklib DragLib \266");
+ WriteDestFileLn("\"{SharedLibraries}DragLib\" \266");
+ WriteDestFileLn("-weaklib WindowsLib \266");
+ WriteDestFileLn("\"{SharedLibraries}WindowsLib\" \266");
+ } else if (gbk_targ_m68k == cur_targ) {
+ WriteDestFileLn("\"{Libraries}Interface.o\" \266");
+ WriteDestFileLn("\"{Libraries}Navigation.o\" \266");
+ WriteDestFileLn("\"{Libraries}MacRuntime.o\" \266");
+ /* WriteDestFileLn("\"{Libraries}MathLib.o\" \266"); */
+ } else if (gbk_targ_mfpu == cur_targ) {
+ WriteDestFileLn("\"{Libraries}Interface.o\" \266");
+ WriteDestFileLn("\"{Libraries}Navigation.o\" \266");
+ WriteDestFileLn("\"{Libraries}MacRuntime.o\" \266");
+ /*
+ WriteDestFileLn("\"{Libraries}MathLib881.o\" \266");
+ */
+ }
+ if (gbk_cpufam_68k == gbo_cpufam) {
+ WriteBgnDestFileLn();
+ WriteQuoteToDestFile();
+ WriteLongGlueObjPath();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" \266");
+ WriteEndDestFileLn();
+ }
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("-o");
+ WritePathArgInMakeCmnd(Write_machobinpath_ToDestFile);
+ WriteEndDestFileLn();
+ --DestFileIndent;
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("SetFile -d . -m .");
+ if (! HaveMacBundleApp) {
+ WriteCStrToDestFile(" -a B");
+ }
+ WriteCStrToDestFile(" \"");
+ Write_machobinpath_ToDestFile();
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+ --DestFileIndent;
+
+ if (HaveMacRrscs) {
+ WriteBlankLineToDestFile();
+ WriteMakeRule(WriteMainRsrcObjPath,
+ WriteMainRsrcObjDeps, WriteMainRsrcObjMPWbody);
+ }
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("clean \304");
+ ++DestFileIndent;
+ WriteDestFileLn("Delete -i {ObjFiles}");
+ if (HaveMacBundleApp) {
+ WriteRmDir(WriteAppNamePath);
+ } else {
+ WriteRmFile(WriteAppNamePath);
+ WriteRmFile(WriteMainRsrcObjPath);
+ }
+ --DestFileIndent;
+ WriteBlankLineToDestFile();
+}
+
+LOCALPROC WriteMPWSpecificFiles(void)
+{
+ if (gbk_cpufam_68k == gbo_cpufam) {
+ WriteADstFile1("my_config_d",
+ "LONGGLUE", ".S", "entry point glue for large program",
+ WriteLONGGLUEContents);
+ }
+
+ if (HaveMacBundleApp) {
+ WritePListData();
+ }
+
+ WriteADstFile1("my_project_d",
+ "Makefile", "", "Make file",
+ WriteMPWMakeFile);
+}
--- /dev/null
+++ b/setup/WRMSCFLS.i
@@ -1,0 +1,2005 @@
+/*
+ WRMSCFLS.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite Microsoft C specific FiLeS
+*/
+
+
+LOCALPROC WriteMSVCQuotedDefine(char *s)
+{
+ WriteCStrToDestFile(" /D ");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(s);
+ WriteQuoteToDestFile();
+}
+
+LOCALPROC WriteCLexeFlags(void)
+{
+ blnr WinCE = (gbk_targfam_wnce == gbo_targfam);
+ WriteCStrToDestFile("/nologo");
+
+#if 0
+ if (gbk_dbg_on != gbo_dbg) {
+ /* Optimizations : Minimize Size */
+ WriteCStrToDestFile(" /O1");
+ } else
+#endif
+ {
+ /* Maximize chance of correct compile */
+ /* Optimizations : Disabled */
+ WriteCStrToDestFile(" /Od");
+ }
+ if (WinCE) {
+ WriteCStrToDestFile(
+ " /D _WIN32_WCE=420 /D WIN32_PLATFORM_PSPC=400"
+ " /D UNDER_CE=420");
+ if (gbk_cpufam_arm == gbo_cpufam) {
+ WriteCStrToDestFile(
+ " /D \"ARM\" /D \"_ARM_\" /D \"ARMV4\"");
+ } else {
+ WriteCStrToDestFile(
+ " /D \"_i386_\" /D \"_X86_\" /D \"x86\" /D \"i_386_\"");
+ }
+ } else {
+ WriteMSVCQuotedDefine("WIN32");
+ WriteMSVCQuotedDefine("_WINDOWS");
+ }
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteMSVCQuotedDefine("_DEBUG");
+ } else {
+ WriteMSVCQuotedDefine("NDEBUG");
+ }
+ if (WinCE) {
+ WriteMSVCQuotedDefine("UNICODE");
+ WriteMSVCQuotedDefine("_UNICODE");
+ } else {
+ if (ide_vers >= 6000) {
+ WriteMSVCQuotedDefine("_MBCS");
+ }
+ }
+
+ if ((gbk_dbg_on == gbo_dbg) && (gbk_targ_wx86 == cur_targ)) {
+ WriteCStrToDestFile(" /Gm"); /* minimal rebuild */
+ }
+
+ /* WriteCStrToDestFile(" /GX"); enable exception handling */
+
+ if (WinCE) {
+ if (gbk_cpufam_x86 == gbo_cpufam) {
+ WriteCStrToDestFile(" /Gs8192");
+ /* in the default template. why? */
+ }
+ }
+
+ if (gbk_dbg_on == gbo_dbg) {
+ if (ide_vers >= 7000) {
+ WriteCStrToDestFile(" /RTC1");
+ } else {
+ WriteCStrToDestFile(" /GZ");
+ }
+ } else {
+ WriteCStrToDestFile(" /GF"); /* string pooling */
+ }
+
+ if (WinCE) {
+ if (gbk_cpufam_arm == gbo_cpufam) {
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteCStrToDestFile(" /M$(CECrtMTDebug)");
+ } else {
+ WriteCStrToDestFile(" /MC");
+ }
+ }
+ /*
+ default template doesn't do this for
+ x86. why not?
+ */
+ } else {
+ if (gbk_dbg_on == gbo_dbg) {
+ if ((ide_vers >= 8000)
+ || (gbk_cpufam_x64 == gbo_cpufam))
+ {
+ WriteCStrToDestFile(" /MTd");
+ } else {
+ WriteCStrToDestFile(" /MLd");
+ }
+ } else {
+ if ((ide_vers >= 8000)
+ || (gbk_cpufam_x64 == gbo_cpufam))
+ {
+ WriteCStrToDestFile(" /MT");
+ } else {
+ WriteCStrToDestFile(" /ML");
+ }
+ }
+ }
+
+#if 0
+ if (ide_vers < 8000) {
+ WriteCStrToDestFile(" /GS");
+ /* became default later */
+ /*
+ perhaps instead use /GS- in later versions
+ maybe this should be an option set in SPBASDEF
+ */
+ }
+#endif
+
+ WriteCStrToDestFile(" /W4");
+
+ WriteCStrToDestFile(" /c");
+
+ if ((ide_vers >= 7000) && (ide_vers < 9000)) {
+ /* Detect 64-bit Portability Issues */
+ WriteCStrToDestFile(" /Wp64");
+ }
+
+ if (ide_vers >= 7000) {
+ /* and probably earlier, at least back to 6.0 */
+ /* Enable Function-Level Linking */
+ WriteCStrToDestFile(" /Gy");
+ }
+
+ if (gbk_dbg_on == gbo_dbg) {
+ /* Debug Information Format */
+ if (WinCE || (gbk_targ_wx64 == cur_targ)) {
+ WriteCStrToDestFile(" /Zi");
+ } else {
+ WriteCStrToDestFile(" /ZI");
+ }
+ }
+}
+
+LOCALPROC WriteRCexeFlags(void)
+{
+ blnr WinCE = (gbk_targfam_wnce == gbo_targfam);
+
+ WriteCStrToDestFile("/l 0x409 /d ");
+ WriteQuoteToDestFile();
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteCStrToDestFile("_DEBUG");
+ } else {
+ WriteCStrToDestFile("NDEBUG");
+ }
+ WriteQuoteToDestFile();
+ if (WinCE) {
+ WriteCStrToDestFile(
+ " /d UNDER_CE=420 /d _WIN32_WCE=420 /d \"UNICODE\""
+ " /d \"_UNICODE\" /d WIN32_PLATFORM_PSPC=400 /r");
+ if (gbk_cpufam_arm == gbo_cpufam) {
+ WriteCStrToDestFile(
+ " /d \"ARM\" /d \"_ARM_\" /d \"ARMV4\"");
+ } else {
+ WriteCStrToDestFile(
+ " /d \"_i386_\" /d \"_X86_\" /d \"x86\"");
+ }
+ }
+}
+
+LOCALPROC WriteFileToMSVCSource(MyProc p)
+{
+ WriteDestFileLn("# Begin Source File");
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("SOURCE=");
+ p();
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("# End Source File");
+}
+
+LOCALPROC WriteDocTypeMSVCresource(void)
+{
+ WriteFileToMSVCSource(WriteDocTypeIconFilePath);
+}
+
+LOCALPROC WriteMSVCBeginGroup(char *group, char *filter)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("# Begin Group ");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(group);
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("# PROP Default_Filter ");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(filter);
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteMSVCEndGroup(void)
+{
+ WriteDestFileLn("# End Group");
+}
+
+LOCALPROC WriteMSVCdbgLevelName(void)
+{
+ char *s;
+
+ switch (gbo_dbg) {
+ case gbk_dbg_on:
+ s = "Debug";
+ break;
+ case gbk_dbg_test:
+ s = "Test";
+ break;
+ case gbk_dbg_off:
+ s = "Release";
+ break;
+ default:
+ s = "(unknown Debug Level)";
+ break;
+ }
+
+ WriteCStrToDestFile(s);
+}
+
+LOCALPROC WriteMSVCTargetName00(void)
+{
+ blnr WinCE = (gbk_targfam_wnce == gbo_targfam);
+ WriteCStrToDestFile("Win32");
+ if (WinCE) {
+ if (gbk_cpufam_arm == gbo_cpufam) {
+ WriteCStrToDestFile(" (WCE ARMV4)");
+ } else {
+ WriteCStrToDestFile(" (WCE emulator)");
+ }
+ } else {
+ WriteCStrToDestFile(" (x86)");
+ }
+}
+
+LOCALPROC WriteMSVCTargetName0(void)
+{
+ WriteStrAppAbbrev();
+ WriteCStrToDestFile(" - ");
+ WriteMSVCTargetName00();
+ WriteSpaceToDestFile();
+ WriteMSVCdbgLevelName();
+}
+
+LOCALPROC WriteMSVCTargetName(void)
+{
+ WriteQuoteToDestFile();
+ WriteMSVCTargetName0();
+ WriteQuoteToDestFile();
+}
+
+LOCALPROC WriteMSVCMakefileName(void)
+{
+ WriteQuoteToDestFile();
+ WriteStrAppAbbrev();
+ if (gbk_targfam_wnce == gbo_targfam) {
+ WriteCStrToDestFile(".vcn");
+ } else {
+ WriteCStrToDestFile(".mak");
+ }
+ WriteQuoteToDestFile();
+}
+
+LOCALPROC WriteMSVCQuotedProp(char *p, char *s)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("# PROP ");
+ WriteCStrToDestFile(p);
+ WriteSpaceToDestFile();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(s);
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC DoSrcFileMSVCAddFile(void)
+{
+ WriteDestFileLn("# Begin Source File");
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("SOURCE=");
+ WriteSrcFileFilePath();
+ WriteEndDestFileLn();
+#if 0
+ if (gbk_dbg_on != gbo_dbg) {
+ if (fast) {
+ WriteDestFileLn("# ADD CPP /O2 /Ob2");
+ }
+ }
+#endif
+ WriteDestFileLn("# End Source File");
+}
+
+LOCALPROC DoSrcFileMSVCAddHeader(void)
+{
+ if ((DoSrcFile_gd()->Flgm & kCSrcFlgmNoHeader) == 0) {
+ WriteDestFileLn("# Begin Source File");
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("SOURCE=");
+ WriteSrcFileHeaderPath();
+ WriteEndDestFileLn();
+ WriteDestFileLn("# End Source File");
+ }
+}
+
+LOCALPROC DoExtraHeaderMSVCAdd(void)
+{
+ WriteDestFileLn("# Begin Source File");
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("SOURCE=");
+ WriteExtraHeaderFilePath();
+ WriteEndDestFileLn();
+ WriteDestFileLn("# End Source File");
+}
+
+LOCALFUNC char * MSVCWorkspaceExt(void)
+{
+ return (gbk_targfam_wnce == gbo_targfam)
+ ? ".vcw" : ".dsw";
+}
+
+LOCALFUNC char * MSVCProjectExt(void)
+{
+ return (gbk_targfam_wnce == gbo_targfam)
+ ? ".vcp" : ".dsp";
+}
+
+LOCALPROC WriteMSVCWorkSpaceFile(void)
+{
+ blnr WinCE = (gbk_targfam_wnce == gbo_targfam);
+ if (WinCE) {
+ WriteDestFileLn(
+ "Microsoft eMbedded Visual Tools Workspace File,"
+ " Format Version 4.00");
+ } else {
+ WriteDestFileLn(
+ "Microsoft Developer Studio Workspace File,"
+ " Format Version 6.00");
+ }
+ WriteDestFileLn(
+ "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "############################################################"
+ "###################");
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Project: ");
+ WriteQuoteToDestFile();
+ WriteStrAppAbbrev();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("=.");
+ WriteBackSlashToDestFile();
+ WriteStrAppAbbrev();
+ WriteCStrToDestFile(MSVCProjectExt());
+ WriteCStrToDestFile(" - Package Owner=<4>");
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("Package=<5>");
+ WriteDestFileLn("{{{");
+ WriteDestFileLn("}}}");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("Package=<4>");
+ WriteDestFileLn("{{{");
+ WriteDestFileLn("}}}");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "############################################################"
+ "###################");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("Global:");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("Package=<5>");
+ WriteDestFileLn("{{{");
+ WriteDestFileLn("}}}");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("Package=<3>");
+ WriteDestFileLn("{{{");
+ WriteDestFileLn("}}}");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(
+ "############################################################"
+ "###################");
+ WriteBlankLineToDestFile();
+}
+
+LOCALPROC WriteMSVCProjectFile(void)
+{
+ blnr WinCE = (gbk_targfam_wnce == gbo_targfam);
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("# Microsoft ");
+ if (WinCE) {
+ WriteCStrToDestFile("eMbedded Visual Tools");
+ } else {
+ WriteCStrToDestFile("Developer Studio");
+ }
+ WriteCStrToDestFile(" Project File - Name=");
+ WriteQuoteToDestFile();
+ WriteStrAppAbbrev();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" - Package Owner=<4>");
+ WriteEndDestFileLn();
+
+ if (WinCE) {
+ WriteDestFileLn(
+ "# Microsoft eMbedded Visual Tools Generated Build File,"
+ " Format Version 6.02");
+ } else {
+ WriteDestFileLn(
+ "# Microsoft Developer Studio Generated Build File,"
+ " Format Version 6.00");
+ }
+ WriteDestFileLn("# ** DO NOT EDIT **");
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("# TARGTYPE ");
+ WriteQuoteToDestFile();
+ WriteMSVCTargetName00();
+ WriteCStrToDestFile(" Application");
+ WriteQuoteToDestFile();
+ if (WinCE) {
+ if (gbk_cpufam_arm == gbo_cpufam) {
+ WriteCStrToDestFile(" 0xa301");
+ } else {
+ WriteCStrToDestFile(" 0xa601");
+ }
+ } else {
+ WriteCStrToDestFile(" 0x0101");
+ }
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("CFG=");
+ /* WriteAppVariationStr(); */
+ WriteMSVCTargetName0();
+ WriteEndDestFileLn();
+
+ WriteDestFileLn(
+ "!MESSAGE This is not a valid makefile."
+ " To build this project using NMAKE,");
+ WriteDestFileLn("!MESSAGE use the Export Makefile command and run");
+ WriteDestFileLn("!MESSAGE ");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("!MESSAGE NMAKE /f ");
+ WriteMSVCMakefileName();
+ WriteCStrToDestFile(".");
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("!MESSAGE ");
+ WriteDestFileLn(
+ "!MESSAGE You can specify a configuration when running NMAKE");
+ WriteDestFileLn(
+ "!MESSAGE by defining the macro CFG on the command line."
+ " For example:");
+ WriteDestFileLn("!MESSAGE ");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("!MESSAGE NMAKE /f ");
+ WriteMSVCMakefileName();
+ WriteCStrToDestFile(" CFG=");
+ WriteMSVCTargetName();
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("!MESSAGE ");
+ WriteDestFileLn("!MESSAGE Possible choices for configuration are:");
+ WriteDestFileLn("!MESSAGE ");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("!MESSAGE ");
+ WriteMSVCTargetName();
+ WriteCStrToDestFile(" (based on ");
+ WriteQuoteToDestFile();
+ WriteMSVCTargetName00();
+ WriteCStrToDestFile(" Application");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(")");
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("!MESSAGE ");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("# Begin Project");
+ WriteDestFileLn("# PROP AllowPerConfigDependencies 0");
+
+ WriteMSVCQuotedProp("Scc_ProjName", "");
+ WriteMSVCQuotedProp("Scc_LocalPath", "");
+
+ if (WinCE) {
+ WriteDestFileLn("# PROP ATL_Project 2"); /* not needed ? */
+ }
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("CPP=");
+ WriteCompileCExec();
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("MTL=midl.exe");
+ WriteDestFileLn("RSC=rc.exe");
+ WriteDestFileLn("# PROP BASE Use_MFC 0");
+ WriteDestFileLn("# PROP BASE Use_Debug_Libraries 1");
+
+ WriteMSVCQuotedProp("BASE Output_Dir", "Debug");
+ WriteMSVCQuotedProp("BASE Intermediate_Dir", "Debug");
+ WriteMSVCQuotedProp("BASE Target_Dir", "");
+
+ WriteDestFileLn("# PROP Use_MFC 0");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteDestFileLn("# PROP Use_Debug_Libraries 1");
+ } else {
+ WriteDestFileLn("# PROP Use_Debug_Libraries 0");
+ }
+
+ WriteMSVCQuotedProp("Output_Dir", obj_d_name);
+ WriteMSVCQuotedProp("Intermediate_Dir", obj_d_name);
+
+ WriteDestFileLn("# PROP Ignore_Export_Lib 0");
+
+ WriteMSVCQuotedProp("Target_Dir", "");
+
+ WriteDestFileLn("# ADD BASE CPP");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("# ADD CPP ");
+ WriteCLexeFlags();
+ if (! WinCE) {
+ WriteCStrToDestFile(" /FD");
+ }
+ WriteCStrToDestFile(" /I ");
+ WriteQuoteToDestFile();
+ Write_cfg_d_ToDestFile();
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("# ADD BASE MTL");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("# ADD MTL /nologo /D ");
+ WriteQuoteToDestFile();
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteCStrToDestFile("_DEBUG");
+ } else {
+ WriteCStrToDestFile("NDEBUG");
+ }
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" /mktyplib203 /win32");
+ if (WinCE) {
+ WriteCStrToDestFile(" /o \"NUL\"");
+ }
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("# ADD BASE RSC");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("# ADD RSC ");
+ WriteRCexeFlags();
+ WriteCStrToDestFile(" /I ");
+ WriteQuoteToDestFile();
+ Write_src_d_ToDestFile();
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("BSC32=bscmake.exe");
+ WriteDestFileLn("# ADD BASE BSC32");
+ WriteDestFileLn("# ADD BSC32 /nologo");
+ WriteDestFileLn("LINK32=link.exe");
+ WriteDestFileLn("# ADD BASE LINK32");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("# ADD LINK32");
+ if (WinCE) {
+ WriteCStrToDestFile(
+ " commctrl.lib coredll.lib aygshell.lib Mmtimer.lib");
+ } else {
+ WriteCStrToDestFile(
+ " kernel32.lib user32.lib gdi32.lib"
+ " winspool.lib comdlg32.lib advapi32.lib shell32.lib"
+ " ole32.lib oleaut32.lib uuid.lib winmm.lib");
+ }
+ WriteCStrToDestFile(" /nologo");
+ if (WinCE) {
+ WriteCStrToDestFile(
+ " /base:\"0x00010000\" /stack:0x10000,0x1000"
+ " /entry:\"WinMainCRTStartup\""
+ " /nodefaultlib:\"$(CENoDefaultLib)\"");
+ }
+
+ WriteCStrToDestFile(" /subsystem:");
+ if (WinCE) {
+ WriteCStrToDestFile("$(CESubsystem)");
+ } else {
+ WriteCStrToDestFile("windows");
+ }
+
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteCStrToDestFile(" /debug");
+ } else {
+ WriteCStrToDestFile(" /incremental:no");
+ }
+ WriteCStrToDestFile(" /machine:");
+ if (gbk_cpufam_arm == gbo_cpufam) {
+ WriteCStrToDestFile("ARM");
+ } else {
+ if (WinCE) {
+ WriteCStrToDestFile("IX86");
+ } else {
+ WriteCStrToDestFile("I386"); /* maybe should be IX86 ? */
+ }
+ }
+
+ WriteCStrToDestFile(" /out:");
+ WriteQuoteToDestFile();
+ WriteAppNameStr();
+ WriteQuoteToDestFile();
+ if (WinCE) {
+ if (gbk_cpufam_arm == gbo_cpufam) {
+ WriteCStrToDestFile(" /align:\"4096\"");
+ /* is this really needed ? */
+ } else {
+ WriteCStrToDestFile(
+ " $(CEx86Corelibc) /nodefaultlib:\"OLDNAMES.lib\"");
+ }
+ }
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteCStrToDestFile(" /pdbtype:sept");
+ }
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("# Begin Target");
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("# Name ");
+ WriteMSVCTargetName();
+ WriteEndDestFileLn();
+
+ WriteMSVCBeginGroup("Source Files",
+ "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat");
+ DoAllSrcFilesWithSetup(
+ DoSrcFileMSVCAddFile);
+ WriteFileToMSVCSource(WriteMainRsrcSrcPath);
+ WriteMSVCEndGroup();
+
+ WriteMSVCBeginGroup("Header Files", "h;hpp;hxx;hm;inl");
+ DoAllSrcFilesWithSetup(
+ DoSrcFileMSVCAddHeader);
+ WriteMSVCEndGroup();
+
+ WriteMSVCBeginGroup("Resource Files",
+ "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe");
+ DoAllDocTypesWithSetup(WriteDocTypeMSVCresource);
+ WriteMSVCEndGroup();
+
+ WriteMSVCBeginGroup("Include Files", "h;hpp;hxx;hm;inl");
+ DoAllExtraHeaders2WithSetup(DoExtraHeaderMSVCAdd);
+ WriteMSVCEndGroup();
+
+ WriteDestFileLn("# End Target");
+ WriteDestFileLn("# End Project");
+}
+
+LOCALPROC WriteMSVCSpecificFiles(void)
+{
+ WriteADstFile1("my_project_d",
+ vStrAppAbbrev, MSVCWorkspaceExt(), "Workspace file",
+ WriteMSVCWorkSpaceFile);
+ WriteADstFile1("my_project_d",
+ vStrAppAbbrev, MSVCProjectExt(), "Project file",
+ WriteMSVCProjectFile);
+}
+
+LOCALPROC WriteXMLQuotedProp(char *s, MyProc p)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(s);
+ WriteCStrToDestFile("=");
+ WriteQuoteToDestFile();
+ p();
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteMSVCPlatformName(void)
+{
+ if (gbk_targ_wx64 == cur_targ) {
+ WriteCStrToDestFile("x64");
+ } else {
+ WriteCStrToDestFile("Win32");
+ }
+}
+
+LOCALPROC WriteMSVCXMLPlatformProps(void)
+{
+ WriteXMLQuotedProp("Name", WriteMSVCPlatformName);
+}
+
+LOCALPROC WriteMSVCXMLPlatforms(void)
+{
+ WriteXMLtaglinewithprops("Platform", WriteMSVCXMLPlatformProps);
+}
+
+LOCALPROC WriteMSVCXMLConfigurationName(void)
+{
+ WriteMSVCdbgLevelName();
+ WriteCStrToDestFile("|");
+ WriteMSVCPlatformName();
+}
+
+LOCALPROC WriteMSVCXMLConfigurationProps(void)
+{
+ WriteXMLQuotedProp("Name", WriteMSVCXMLConfigurationName);
+ WriteXMLQuotedProp("OutputDirectory", Write_obj_d_ToDestFile);
+ WriteXMLQuotedProp("IntermediateDirectory", Write_obj_d_ToDestFile);
+ WriteDestFileLn("ConfigurationType=\"1\"");
+ WriteDestFileLn("CharacterSet=\"2\"");
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteDestFileLn("WholeProgramOptimization=\"0\"");
+ }
+}
+
+LOCALPROC WriteMSVCToolConfig(char *s, MyProc p)
+{
+ WriteDestFileLn("<Tool");
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Name=");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(s);
+ WriteQuoteToDestFile();
+ WriteEndDestFileLn();
+ if (NULL != p) {
+ p();
+ }
+ --DestFileIndent;
+ WriteDestFileLn("/>");
+}
+
+LOCALPROC WriteMSVCCompilerToolConfig(void)
+{
+#if 0
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteDestFileLn("Optimization=\"1\"");
+ WriteDestFileLn("FavorSizeOrSpeed=\"0\"");
+ WriteDestFileLn("WholeProgramOptimization=\"false\"");
+ WriteDestFileLn("OmitFramePointers=\"true\"");
+ } else
+#endif
+ {
+ /* Maximize chance of correct compile */
+ WriteDestFileLn("Optimization=\"0\"");
+ }
+
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteDestFileLn(
+ "PreprocessorDefinitions=\"WIN32;_DEBUG;_WINDOWS\"");
+ WriteDestFileLn("MinimalRebuild=\"true\"");
+ } else {
+ WriteDestFileLn(
+ "PreprocessorDefinitions=\"WIN32;NDEBUG;_WINDOWS\"");
+ WriteDestFileLn("StringPooling=\"true\"");
+ }
+
+ WriteXMLQuotedProp("AdditionalIncludeDirectories",
+ Write_cfg_d_ToDestFile);
+
+ WriteDestFileLn("ExceptionHandling=\"0\"");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteDestFileLn("BasicRuntimeChecks=\"3\"");
+ if (ide_vers >= 8000) {
+ WriteDestFileLn("RuntimeLibrary=\"1\"");
+ } else {
+ WriteDestFileLn("RuntimeLibrary=\"5\"");
+ }
+ } else {
+ if (ide_vers >= 8000) {
+ WriteDestFileLn("RuntimeLibrary=\"0\"");
+ } else {
+ WriteDestFileLn("RuntimeLibrary=\"4\"");
+ }
+ }
+ if (ide_vers < 8000) {
+ WriteDestFileLn("BufferSecurityCheck=\"false\"");
+ /* perhaps later versions also */
+ /* maybe this should be an option set in SPBASDEF */
+ }
+ WriteDestFileLn("EnableFunctionLevelLinking=\"true\"");
+ WriteDestFileLn("UsePrecompiledHeader=\"0\"");
+ WriteDestFileLn("WarningLevel=\"4\"");
+ if (ide_vers < 9000) {
+ WriteDestFileLn("Detect64BitPortabilityProblems=\"true\"");
+ }
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteDestFileLn("DebugInformationFormat=\"4\"");
+ } else {
+ WriteDestFileLn("DebugInformationFormat=\"0\"");
+ }
+ WriteDestFileLn("CompileAs=\"0\"");
+}
+
+LOCALPROC WriteMSVCResourceCompilerToolConfig(void)
+{
+ WriteXMLQuotedProp("AdditionalIncludeDirectories",
+ Write_src_d_ToDestFile);
+}
+
+LOCALPROC WriteMSVCLinkerToolConfig(void)
+{
+ WriteDestFileLn("AdditionalDependencies=\"winmm.lib\"");
+ WriteXMLQuotedProp("OutputFile", WriteAppNamePath);
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteDestFileLn("LinkIncremental=\"2\"");
+ } else {
+ WriteDestFileLn("LinkIncremental=\"1\"");
+ }
+ if (ide_vers >= 8000) {
+ WriteDestFileLn("GenerateManifest=\"false\"");
+ }
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteDestFileLn("GenerateDebugInformation=\"true\"");
+ } else {
+ WriteDestFileLn("GenerateDebugInformation=\"false\"");
+ }
+ WriteDestFileLn("SubSystem=\"2\"");
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteDestFileLn("OptimizeReferences=\"2\"");
+ WriteDestFileLn("EnableCOMDATFolding=\"2\"");
+ }
+ if (ide_vers >= 9000) {
+ WriteDestFileLn("RandomizedBaseAddress=\"1\"");
+ WriteDestFileLn("DataExecutionPrevention=\"0\"");
+ }
+ if (gbk_targ_wx64 == cur_targ) {
+ WriteDestFileLn("TargetMachine=\"17\"");
+ } else {
+ WriteDestFileLn("TargetMachine=\"1\"");
+ }
+}
+
+LOCALPROC WriteMSVCXMLConfigurationBody(void)
+{
+ WriteMSVCToolConfig("VCPreBuildEventTool", NULL);
+ WriteMSVCToolConfig("VCCustomBuildTool", NULL);
+ if (ide_vers >= 7100) {
+ WriteMSVCToolConfig("VCXMLDataGeneratorTool", NULL);
+ }
+ WriteMSVCToolConfig("VCWebServiceProxyGeneratorTool", NULL);
+ WriteMSVCToolConfig("VCMIDLTool", NULL);
+ WriteMSVCToolConfig("VCCLCompilerTool",
+ WriteMSVCCompilerToolConfig);
+ if (ide_vers >= 8000) {
+ WriteMSVCToolConfig("VCManagedResourceCompilerTool", NULL);
+ }
+ WriteMSVCToolConfig("VCResourceCompilerTool",
+ WriteMSVCResourceCompilerToolConfig);
+ WriteMSVCToolConfig("VCPreLinkEventTool", NULL);
+ WriteMSVCToolConfig("VCLinkerTool", WriteMSVCLinkerToolConfig);
+ if (ide_vers >= 8000) {
+ WriteMSVCToolConfig("VCALinkTool", NULL);
+ WriteMSVCToolConfig("VCManifestTool", NULL);
+ WriteMSVCToolConfig("VCXDCMakeTool", NULL);
+ WriteMSVCToolConfig("VCBscMakeTool", NULL);
+ WriteMSVCToolConfig("VCFxCopTool", NULL);
+ WriteMSVCToolConfig("VCAppVerifierTool", NULL);
+ } else if (ide_vers >= 7100) {
+ WriteMSVCToolConfig("VCManagedWrapperGeneratorTool", NULL);
+ WriteMSVCToolConfig("VCAuxiliaryManagedWrapperGeneratorTool",
+ NULL);
+ }
+ if (ide_vers < 9000) {
+ WriteMSVCToolConfig("VCWebDeploymentTool", NULL);
+ }
+ WriteMSVCToolConfig("VCPostBuildEventTool", NULL);
+}
+
+LOCALPROC WriteMSVCXMLConfigurations(void)
+{
+ WriteXMLtaggedLinesWithProps("Configuration",
+ WriteMSVCXMLConfigurationProps,
+ WriteMSVCXMLConfigurationBody);
+}
+
+LOCALPROC WriteMSVCXMLSourceFilesProps(void)
+{
+ WriteDestFileLn("Name=\"Source Files\"");
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Filter=\"cpp;c");
+ if (ide_vers >= 8000) {
+ WriteCStrToDestFile(";cc");
+ }
+ WriteCStrToDestFile(";cxx;def;odl;idl;hpj;bat;asm");
+ if (ide_vers >= 7100) {
+ WriteCStrToDestFile(";asmx");
+ }
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+ if (ide_vers >= 7100) {
+ WriteDestFileLn(
+ "UniqueIdentifier=\"{"
+ "00020000-0000-0000-0000-000000000000}\"");
+ }
+}
+
+LOCALPROC DoMSVCXMLAddFile(MyProc p)
+{
+ WriteDestFileLn("<File");
+ ++DestFileIndent;
+ WriteXMLQuotedProp("RelativePath", p);
+ WriteDestFileLn(">");
+ --DestFileIndent;
+ WriteDestFileLn("</File>");
+}
+
+LOCALPROC DoSrcFileMSVCXMLAddFile(void)
+{
+ DoMSVCXMLAddFile(WriteSrcFileFilePath);
+}
+
+LOCALPROC WriteMSVCXMLSourceFilesBody(void)
+{
+ DoAllSrcFilesWithSetup(DoSrcFileMSVCXMLAddFile);
+}
+
+LOCALPROC WriteMSVCXMLHeaderFilesProps(void)
+{
+ WriteDestFileLn("Name=\"Header Files\"");
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("Filter=\"h;hpp;hxx;hm;inl;inc");
+ if (ide_vers >= 7100) {
+ WriteCStrToDestFile(";xsd");
+ }
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+ if (ide_vers >= 7100) {
+ WriteDestFileLn(
+ "UniqueIdentifier=\"{"
+ "00030000-0000-0000-0000-000000000000}\"");
+ }
+}
+
+LOCALPROC DoSrcFileMSVCXMLAddHeader(void)
+{
+ if ((DoSrcFile_gd()->Flgm & kCSrcFlgmNoHeader) == 0) {
+ DoMSVCXMLAddFile(WriteSrcFileHeaderPath);
+ }
+}
+
+LOCALPROC WriteMSVCXMLHeaderFilesBody(void)
+{
+ DoAllSrcFilesWithSetup(DoSrcFileMSVCXMLAddHeader);
+}
+
+LOCALPROC WriteMSVCXMLResourceFilesProps(void)
+{
+ WriteDestFileLn("Name=\"Resource Files\"");
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(
+ "Filter=\"rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;"
+ "jpeg;jpe");
+ if (ide_vers >= 7100) {
+ WriteCStrToDestFile(";resx");
+ }
+ if (ide_vers >= 8000) {
+ WriteCStrToDestFile(";tiff;tif;png;wav");
+ }
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+ if (ide_vers >= 7100) {
+ WriteDestFileLn(
+ "UniqueIdentifier=\"{"
+ "00040000-0000-0000-0000-000000000000}\"");
+ }
+}
+
+LOCALPROC WriteDocTypeMSVCXMLresource(void)
+{
+ DoMSVCXMLAddFile(WriteDocTypeIconFilePath);
+}
+
+LOCALPROC WriteMSVCXMLResourceFilesBody(void)
+{
+ DoMSVCXMLAddFile(WriteMainRsrcSrcPath);
+ DoAllDocTypesWithSetup(WriteDocTypeMSVCXMLresource);
+}
+
+LOCALPROC WriteMSVCXMLIncludeFilesProps(void)
+{
+ WriteDestFileLn("Name=\"Include Files\"");
+ WriteDestFileLn("Filter=\"h;hpp;hxx;hm;inl;inc;xsd\"");
+}
+
+LOCALPROC DoMSVCXMLAddAddExtraHeader(void)
+{
+ DoMSVCXMLAddFile(WriteExtraHeaderFilePath);
+}
+
+LOCALPROC WriteMSVCXMLIncludeFilesBody(void)
+{
+ DoAllExtraHeaders2WithSetup(DoMSVCXMLAddAddExtraHeader);
+}
+
+LOCALPROC WriteMSVCXMLFiles(void)
+{
+ WriteXMLtaggedLinesWithProps("Filter",
+ WriteMSVCXMLSourceFilesProps,
+ WriteMSVCXMLSourceFilesBody);
+ WriteXMLtaggedLinesWithProps("Filter",
+ WriteMSVCXMLHeaderFilesProps,
+ WriteMSVCXMLHeaderFilesBody);
+ WriteXMLtaggedLinesWithProps("Filter",
+ WriteMSVCXMLResourceFilesProps,
+ WriteMSVCXMLResourceFilesBody);
+ WriteXMLtaggedLinesWithProps("Filter",
+ WriteMSVCXMLIncludeFilesProps,
+ WriteMSVCXMLIncludeFilesBody);
+}
+
+LOCALPROC WriteMSVCXMLSolutionFile(void)
+{
+ if (ide_vers >= 8000) {
+ WriteDestFileLn("\357\273\277"); /* UTF-8 byte-order mark */
+ }
+
+ if (ide_vers >= 11000) {
+ WriteDestFileLn(
+ "Microsoft Visual Studio Solution File,"
+ " Format Version 12.00");
+ if (ide_vers >= 15000) {
+ WriteDestFileLn("# Visual Studio 15");
+ } else if (ide_vers >= 14000) {
+ WriteDestFileLn("# Visual Studio 14");
+ } else if (ide_vers >= 12000) {
+ WriteDestFileLn("# Visual Studio 2013");
+ } else {
+ WriteDestFileLn("# Visual Studio 2012");
+ }
+ } else if (ide_vers >= 10000) {
+ WriteDestFileLn(
+ "Microsoft Visual Studio Solution File,"
+ " Format Version 11.00");
+ WriteDestFileLn("# Visual Studio 2010");
+ } else if (ide_vers >= 9000) {
+ WriteDestFileLn(
+ "Microsoft Visual Studio Solution File,"
+ " Format Version 10.00");
+ /* WriteDestFileLn("# Visual C++ Express 2008"); */
+ WriteDestFileLn("# Visual Studio 2008");
+ } else if (ide_vers >= 8000) {
+ WriteDestFileLn(
+ "Microsoft Visual Studio Solution File,"
+ " Format Version 9.00");
+ /* WriteDestFileLn("# Visual C++ Express 2005"); */
+ WriteDestFileLn("# Visual Studio 2005");
+ } else if (ide_vers >= 7100) {
+ WriteDestFileLn(
+ "Microsoft Visual Studio Solution File,"
+ " Format Version 8.00");
+ } else {
+ WriteDestFileLn(
+ "Microsoft Visual Studio Solution File,"
+ " Format Version 7.00");
+ }
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(
+ "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"");
+ WriteStrAppAbbrev();
+ WriteCStrToDestFile("\", \"");
+ WriteStrAppAbbrev();
+ if (ide_vers >= 10000) {
+ WriteCStrToDestFile(".vcxproj");
+ } else {
+ WriteCStrToDestFile(".vcproj");
+ }
+ WriteCStrToDestFile(
+ "\", \"{00010000-0000-0000-0000-000000000000}\"");
+ WriteEndDestFileLn();
+ if ((ide_vers >= 7100) && (ide_vers < 8000)) {
+ ++DestFileIndent;
+ WriteDestFileLn(
+ "ProjectSection(ProjectDependencies)"" = postProject");
+ WriteDestFileLn("EndProjectSection");
+ --DestFileIndent;
+ }
+ WriteDestFileLn("EndProject");
+ WriteDestFileLn("Global");
+ ++DestFileIndent;
+ if (ide_vers >= 8000) {
+ WriteDestFileLn(
+ "GlobalSection(SolutionConfigurationPlatforms)"
+ " = preSolution");
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteMSVCXMLConfigurationName();
+ WriteCStrToDestFile(" = ");
+ WriteMSVCXMLConfigurationName();
+ WriteEndDestFileLn();
+ --DestFileIndent;
+ WriteDestFileLn("EndGlobalSection");
+ WriteDestFileLn(
+ "GlobalSection(ProjectConfigurationPlatforms)"
+ " = postSolution");
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(
+ "{00010000-0000-0000-0000-000000000000}.");
+ WriteMSVCXMLConfigurationName();
+ WriteCStrToDestFile(".ActiveCfg = ");
+ WriteMSVCXMLConfigurationName();
+ WriteEndDestFileLn();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(
+ "{00010000-0000-0000-0000-000000000000}.");
+ WriteMSVCXMLConfigurationName();
+ WriteCStrToDestFile(".Build.0 = ");
+ WriteMSVCXMLConfigurationName();
+ WriteEndDestFileLn();
+ --DestFileIndent;
+ WriteDestFileLn("EndGlobalSection");
+ WriteDestFileLn(
+ "GlobalSection(SolutionProperties) = preSolution");
+ ++DestFileIndent;
+ WriteDestFileLn("HideSolutionNode = FALSE");
+ --DestFileIndent;
+ WriteDestFileLn("EndGlobalSection");
+ } else {
+ WriteDestFileLn(
+ "GlobalSection(SolutionConfiguration) = preSolution");
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ if (ide_vers >= 7100) {
+ WriteMSVCdbgLevelName();
+ } else {
+ WriteCStrToDestFile("ConfigName.0");
+ }
+ WriteCStrToDestFile(" = ");
+ WriteMSVCdbgLevelName();
+ WriteEndDestFileLn();
+ --DestFileIndent;
+ WriteDestFileLn("EndGlobalSection");
+ if (ide_vers < 7100) {
+ WriteCStrToDestFile(
+ "GlobalSection(ProjectDependencies)"
+ " = postSolution");
+ WriteCStrToDestFile("EndGlobalSection");
+ }
+ WriteDestFileLn(
+ "GlobalSection(ProjectConfiguration) = postSolution");
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(
+ "{00010000-0000-0000-0000-000000000000}.");
+ WriteMSVCdbgLevelName();
+ WriteCStrToDestFile(".ActiveCfg = ");
+ WriteMSVCXMLConfigurationName();
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(
+ "{00010000-0000-0000-0000-000000000000}.");
+ WriteMSVCdbgLevelName();
+ WriteCStrToDestFile(".Build.0 = ");
+ WriteMSVCXMLConfigurationName();
+ WriteEndDestFileLn();
+ --DestFileIndent;
+ WriteDestFileLn("EndGlobalSection");
+ WriteDestFileLn(
+ "GlobalSection(ExtensibilityGlobals) = postSolution");
+ WriteDestFileLn("EndGlobalSection");
+ WriteDestFileLn(
+ "GlobalSection(ExtensibilityAddIns) = postSolution");
+ WriteDestFileLn("EndGlobalSection");
+ }
+ --DestFileIndent;
+ WriteDestFileLn("EndGlobal");
+}
+
+LOCALPROC WriteMSVCXMLProjectProps(void)
+{
+ WriteDestFileLn("ProjectType=\"Visual C++\"");
+ if (ide_vers >= 9000) {
+ WriteDestFileLn("Version=\"9.00\"");
+ } else if (ide_vers >= 8000) {
+ WriteDestFileLn("Version=\"8.00\"");
+ } else if (ide_vers >= 7100) {
+ WriteDestFileLn("Version=\"7.10\"");
+ } else {
+ WriteDestFileLn("Version=\"7.00\"");
+ }
+ WriteXMLQuotedProp("Name", WriteStrAppAbbrev);
+ WriteDestFileLn(
+ "ProjectGUID=\"{00010000-0000-0000-0000-000000000000}\"");
+ if (ide_vers >= 8000) {
+ WriteXMLQuotedProp("RootNamespace", WriteStrAppAbbrev);
+ }
+ WriteDestFileLn("Keyword=\"Win32Proj\"");
+ if (ide_vers >= 9000) {
+ WriteDestFileLn("TargetFrameworkVersion=\"131072\"");
+ }
+}
+
+LOCALPROC WriteMSVCXMLProjectBody(void)
+{
+ WriteXMLtaggedLines("Platforms", WriteMSVCXMLPlatforms);
+ if (ide_vers >= 8000) {
+ WriteXMLtaggedLines("ToolFiles", NULL);
+ }
+ WriteXMLtaggedLines("Configurations", WriteMSVCXMLConfigurations);
+ if (ide_vers >= 7100) {
+ WriteXMLtaggedLines("References", NULL);
+ }
+ WriteXMLtaggedLines("Files", WriteMSVCXMLFiles);
+ WriteXMLtaggedLines("Globals", NULL);
+}
+
+LOCALPROC WriteMSVCXMLProjectFile(void)
+{
+ WriteDestFileLn(
+ "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>");
+ WriteXMLtaggedLinesWithProps("VisualStudioProject",
+ WriteMSVCXMLProjectProps,
+ WriteMSVCXMLProjectBody);
+}
+
+LOCALPROC WriteMSVCXMLSpecificFiles(void)
+{
+ WriteADstFile1("my_project_d",
+ vStrAppAbbrev, ".sln", "Solutions file",
+ WriteMSVCXMLSolutionFile);
+ WriteADstFile1("my_project_d",
+ vStrAppAbbrev, ".vcproj", "Project file",
+ WriteMSVCXMLProjectFile);
+}
+
+LOCALPROC DoSrcFileNMakeAddObjFile(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("\"");
+ WriteSrcFileObjPath();
+ WriteCStrToDestFile("\" \\");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteMainRsrcObjMSCbuild(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("rc.exe ");
+ WriteRCexeFlags();
+ WriteCStrToDestFile(" /fo\"");
+ WriteMainRsrcObjPath();
+ WriteCStrToDestFile("\"");
+ WriteCStrToDestFile(" /i");
+ WriteQuoteToDestFile();
+ Write_src_d_ToDestFile();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" \"");
+ WriteMainRsrcSrcPath();
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteNMakeMakeFile(void)
+{
+ blnr WinCE = (gbk_targfam_wnce == gbo_targfam);
+
+ WriteDestFileLn("# make file generated by gryphel build system");
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptions=");
+ WriteCLexeFlags();
+ WriteCStrToDestFile(" /I\"");
+ Write_cfg_d_ToDestFile();
+ WriteCStrToDestFile("\\\\\"");
+ /* yes, a double backslash is what is needed */
+ WriteCStrToDestFile(" /Fo\"");
+ Write_obj_d_ToDestFile();
+ WriteCStrToDestFile("\\\\\"");
+ WriteCStrToDestFile(" /Fd\"");
+ Write_obj_d_ToDestFile();
+ WriteCStrToDestFile("\\\\\"");
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("TheDefaultOutput :");
+ WriteMakeDependFile(WriteAppNamePath);
+ WriteEndDestFileLn();
+ WriteBlankLineToDestFile();
+ WriteBlankLineToDestFile();
+ DoAllSrcFilesWithSetup(DoSrcFileMakeCompile);
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("ObjFiles= \\");
+ ++DestFileIndent;
+ DoAllSrcFilesSortWithSetup(DoSrcFileNMakeAddObjFile);
+ --DestFileIndent;
+ WriteBlankLineToDestFile();
+ WriteBlankLineToDestFile();
+ WriteBlankLineToDestFile();
+ WriteMakeRule(WriteMainRsrcObjPath,
+ WriteMainRsrcObjMSCdeps, WriteMainRsrcObjMSCbuild);
+ WriteBlankLineToDestFile();
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("\"");
+ WriteAppNamePath();
+ WriteCStrToDestFile("\" : $(ObjFiles) \"");
+ WriteMainRsrcObjPath();
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteDestFileLn("link.exe @<<");
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("/out:\"");
+ WriteAppNamePath();
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("/nologo");
+ if (WinCE) {
+ WriteCStrToDestFile(" /subsystem:windowsce,4.20");
+ } else {
+ WriteCStrToDestFile(" /subsystem:windows");
+ }
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteCStrToDestFile(" /debug");
+ } else {
+ WriteCStrToDestFile(" /incremental:no");
+ }
+ WriteCStrToDestFile(" /opt:ref /opt:icf");
+ /*
+ more or less default, but putting this in
+ makes difference at least in visual studio 2005
+ */
+ WriteEndDestFileLn();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("/pdb:\"");
+ Write_obj_d_ToDestFile();
+ WriteCStrToDestFile("\\");
+ WriteStrAppAbbrev();
+ WriteCStrToDestFile(".pdb\"");
+ WriteCStrToDestFile(" /machine:");
+ if (gbk_cpufam_arm == gbo_cpufam) {
+ WriteCStrToDestFile("ARM");
+ } else if (gbk_cpufam_x64 == gbo_cpufam) {
+ if (ide_vers >= 7100) {
+ WriteCStrToDestFile("X64");
+ } else {
+ WriteCStrToDestFile("AMD64");
+ }
+ } else {
+ if (ide_vers >= 7100) {
+ WriteCStrToDestFile("X86");
+ } else {
+ WriteCStrToDestFile("I386");
+ }
+ }
+ WriteEndDestFileLn();
+ if (WinCE) {
+ WriteDestFileLn("/base:\"0x00010000\"");
+ WriteDestFileLn("/stack:0x10000,0x1000");
+ WriteDestFileLn("/entry:WinMainCRTStartup");
+ WriteDestFileLn("/align:4096");
+ }
+ if (ide_vers >= 9000) {
+ WriteDestFileLn("/dynamicbase:no");
+ /* smaller exe, maybe not as secure */
+ }
+ if (WinCE) {
+ WriteDestFileLn("commctrl.lib");
+ WriteDestFileLn("coredll.lib");
+ WriteDestFileLn("aygshell.lib");
+ WriteDestFileLn("Mmtimer.lib");
+ WriteDestFileLn("/nodefaultlib:libc.lib");
+ WriteDestFileLn("/nodefaultlib:libcd.lib");
+ WriteDestFileLn("/nodefaultlib:libcmt.lib");
+ WriteDestFileLn("/nodefaultlib:libcmtd.lib");
+ WriteDestFileLn("/nodefaultlib:msvcrt.lib");
+ WriteDestFileLn("/nodefaultlib:msvcrtd.lib");
+ } else {
+ WriteDestFileLn("winmm.lib");
+ WriteDestFileLn("kernel32.lib");
+ WriteDestFileLn("user32.lib");
+ WriteDestFileLn("gdi32.lib");
+ WriteDestFileLn("winspool.lib");
+ WriteDestFileLn("comdlg32.lib");
+ WriteDestFileLn("advapi32.lib");
+ WriteDestFileLn("shell32.lib");
+ WriteDestFileLn("ole32.lib");
+ WriteDestFileLn("oleaut32.lib");
+ WriteDestFileLn("uuid.lib");
+ if ((gbk_cpufam_x64 == gbo_cpufam)
+ && (ide_vers >= 7000)
+ && (ide_vers < 7100))
+ {
+ WriteDestFileLn("bufferoverflowU.lib");
+ }
+ }
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("\"");
+ WriteMainRsrcObjPath();
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+ WriteDestFileLn("$(ObjFiles)");
+ --DestFileIndent;
+ --DestFileIndent;
+ WriteDestFileLn("<<");
+ WriteBlankLineToDestFile();
+
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("CLEAN :");
+ ++DestFileIndent;
+ DoAllSrcFilesStandardErase();
+ WriteRmFile(WriteMainRsrcObjPath);
+ WriteRmFile(WriteAppNamePath);
+ --DestFileIndent;
+}
+
+LOCALPROC WriteNMakeSpecificFiles(void)
+{
+ WriteADstFile1("my_project_d",
+ "MAKEFILE", "", "Make file",
+ WriteNMakeMakeFile);
+}
+
+LOCALPROC DoSrcFileMSVC10XMLAddFile(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<ClCompile Include=\"");
+ WriteSrcFileFilePath();
+ WriteCStrToDestFile("\" />");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC DoSrcFileMSVC10XMLAddHeaderFile(void)
+{
+ if ((DoSrcFile_gd()->Flgm & kCSrcFlgmNoHeader) == 0) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<ClInclude Include=\"");
+ WriteSrcFileHeaderPath();
+ WriteCStrToDestFile("\" />");
+ WriteEndDestFileLn();
+ }
+}
+
+LOCALPROC DoMSVC10XMLAddAddExtraHeader(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<ClInclude Include=\"");
+ WriteExtraHeaderFilePath();
+ WriteCStrToDestFile("\" />");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC DoMSVC10XMLAddDocType(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<None Include=\"");
+ WriteDocTypeIconFilePath();
+ WriteCStrToDestFile("\" />");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteMSVC10OutDir(void)
+{
+ WriteCStrToDestFile(".\\");
+}
+
+LOCALPROC WriteMSVC10IntDir(void)
+{
+ Write_obj_d_ToDestFile();
+ WriteCStrToDestFile("\\");
+}
+
+LOCALPROC WriteMSVCXML10ProjectFile(void)
+{
+ WriteCStrToDestFile("\357\273\277"); /* UTF-8 byte-order mark */
+ WriteDestFileLn("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(
+ "<Project DefaultTargets=\"Build\"");
+ if (ide_vers >= 15000) {
+ WriteCStrToDestFile(
+ " ToolsVersion=\"15.0\"");
+ } else if (ide_vers >= 14000) {
+ WriteCStrToDestFile(
+ " ToolsVersion=\"14.0\"");
+ } else if (ide_vers >= 12000) {
+ WriteCStrToDestFile(
+ " ToolsVersion=\"12.0\"");
+ } else {
+ WriteCStrToDestFile(
+ " ToolsVersion=\"4.0\"");
+ }
+ WriteCStrToDestFile(
+ " xmlns="
+ "\"http://schemas.microsoft.com/developer/msbuild/2003\">"
+ );
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteDestFileLn("<ItemGroup Label=\"ProjectConfigurations\">");
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<ProjectConfiguration Include=\"");
+ WriteMSVCXMLConfigurationName();
+ WriteCStrToDestFile("\">");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteXMLtagBeginProcValEndLine("Configuration",
+ WriteMSVCdbgLevelName);
+ WriteXMLtagBeginProcValEndLine("Platform",
+ WriteMSVCPlatformName);
+ --DestFileIndent;
+ WriteDestFileLn("</ProjectConfiguration>");
+ --DestFileIndent;
+ WriteDestFileLn("</ItemGroup>");
+
+ WriteDestFileLn("<PropertyGroup Label=\"Globals\">");
+ ++DestFileIndent;
+ WriteXMLtagBeginValEndLine("ProjectGuid",
+ "{00010000-0000-0000-0000-000000000000}");
+ WriteXMLtagBeginValEndLine("Keyword", "Win32Proj");
+ WriteXMLtagBeginProcValEndLine("RootNamespace",
+ WriteStrAppAbbrev);
+ if (ide_vers >= 15000) {
+ WriteXMLtagBeginValEndLine(
+ "WindowsTargetPlatformVersion", "10.0.14393.0");
+ }
+ --DestFileIndent;
+ WriteDestFileLn("</PropertyGroup>");
+
+ WriteDestFileLn("<Import Project=\""
+ "$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<PropertyGroup Condition=\""
+ "'$(Configuration)|$(Platform)'=='");
+ WriteMSVCXMLConfigurationName();
+ WriteCStrToDestFile("'\" Label=\"Configuration\">");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteXMLtagBeginValEndLine("ConfigurationType",
+ "Application");
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteXMLtagBeginValEndLine("WholeProgramOptimization",
+ "false");
+ }
+ if (ide_vers >= 11000) {
+ if (ide_vers >= 14000) {
+ WriteXMLtagBeginValEndLine("PlatformToolset",
+ "v141");
+ } else if (ide_vers >= 14000) {
+ WriteXMLtagBeginValEndLine("PlatformToolset",
+ "v140");
+ } else if (ide_vers >= 12000) {
+ WriteXMLtagBeginValEndLine("PlatformToolset",
+ "v120");
+ } else {
+ WriteXMLtagBeginValEndLine("PlatformToolset",
+ "v110");
+ }
+ }
+ WriteXMLtagBeginValEndLine("CharacterSet", "MultiByte");
+ --DestFileIndent;
+ WriteDestFileLn("</PropertyGroup>");
+
+ WriteDestFileLn("<Import Project=\""
+ "$(VCTargetsPath)\\Microsoft.Cpp.props\" />");
+ WriteDestFileLn("<ImportGroup Label=\"ExtensionSettings\">");
+ WriteDestFileLn("</ImportGroup>");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<ImportGroup");
+ WriteCStrToDestFile(" Label=\"PropertySheets\"");
+ WriteCStrToDestFile(
+ " Condition=\"'$(Configuration)|$(Platform)'=='");
+ WriteMSVCXMLConfigurationName();
+ WriteCStrToDestFile("'\">");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteDestFileLn("<Import Project=\""
+ "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\""
+ " Condition=\"exists('$(UserRootDir)\\"
+ "Microsoft.Cpp.$(Platform).user.props')\""
+ " Label=\"LocalAppDataPlatform\" />");
+ --DestFileIndent;
+ WriteDestFileLn("</ImportGroup>");
+
+ WriteDestFileLn("<PropertyGroup Label=\"UserMacros\" />");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<PropertyGroup");
+ WriteCStrToDestFile(
+ " Condition=\"'$(Configuration)|$(Platform)'=='");
+ WriteMSVCXMLConfigurationName();
+ WriteCStrToDestFile("'\"");
+ WriteCStrToDestFile(">");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteXMLtagBeginProcValEndLine("OutDir", WriteMSVC10OutDir);
+ WriteXMLtagBeginProcValEndLine("IntDir", WriteMSVC10IntDir);
+
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagBeginValEndLine("LinkIncremental", "true");
+ } else {
+ WriteXMLtagBeginValEndLine("LinkIncremental", "false");
+ }
+
+ WriteXMLtagBeginValEndLine("GenerateManifest", "false");
+ WriteEndXMLtagLine("PropertyGroup");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<ItemDefinitionGroup"
+ " Condition=\"'$(Configuration)|$(Platform)'=='");
+ WriteMSVCXMLConfigurationName();
+ WriteCStrToDestFile("'\">");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteBeginXMLtagLine("ClCompile");
+ WriteXMLtagBeginValEndLine("WarningLevel", "Level4");
+ WriteXMLtagBeginValEndLine("PrecompiledHeader",
+ "NotUsing");
+
+#if 0
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteXMLtagBeginValEndLine("Optimization",
+ "MinSpace");
+ WriteXMLtagBeginValEndLine("FavorSizeOrSpeed",
+ "Neither");
+ WriteXMLtagBeginValEndLine(
+ "WholeProgramOptimization", "false");
+ WriteXMLtagBeginValEndLine("OmitFramePointers",
+ "true");
+ } else
+#endif
+ {
+ /* Maximize chance of correct compile */
+ WriteXMLtagBeginValEndLine("Optimization",
+ "Disabled");
+ }
+
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteDestFileLn("<PreprocessorDefinitions>"
+ "WIN32;_DEBUG;_WINDOWS;"
+ "%(PreprocessorDefinitions)"
+ "</PreprocessorDefinitions>");
+ if (gbk_targ_wx64 != cur_targ) {
+ WriteXMLtagBeginValEndLine("MinimalRebuild",
+ "true");
+ }
+ WriteXMLtagBeginValEndLine("BasicRuntimeChecks",
+ "EnableFastChecks");
+ WriteXMLtagBeginValEndLine("RuntimeLibrary",
+ "MultiThreadedDebug");
+ if (gbk_targ_wx64 == cur_targ) {
+ WriteXMLtagBeginValEndLine(
+ "DebugInformationFormat",
+ "ProgramDatabase");
+ } else {
+ WriteXMLtagBeginValEndLine(
+ "DebugInformationFormat",
+ "EditAndContinue");
+ }
+ } else {
+ WriteDestFileLn("<PreprocessorDefinitions>"
+ "WIN32;NDEBUG;_WINDOWS;"
+ "%(PreprocessorDefinitions)"
+ "</PreprocessorDefinitions>");
+ WriteXMLtagBeginValEndLine("StringPooling", "true");
+ WriteXMLtagBeginValEndLine("RuntimeLibrary",
+ "MultiThreaded");
+ /*
+ MultiThreadedDLL makes smaller exe,
+ maybe more compatibility issues
+ */
+ }
+ WriteBgnDestFileLn();
+ WriteXMLtagBegin("AdditionalIncludeDirectories");
+ Write_cfg_d_ToDestFile();
+ WriteCStrToDestFile(";%(AdditionalIncludeDirectories)");
+ WriteXMLtagEnd("AdditionalIncludeDirectories");
+ WriteEndDestFileLn();
+
+ WriteXMLtagBeginValEndLine("FunctionLevelLinking",
+ "true");
+ WriteXMLtagBeginValEndLine("ExceptionHandling",
+ "false");
+ WriteEndXMLtagLine("ClCompile");
+
+ WriteBeginXMLtagLine("ResourceCompile");
+ WriteBgnDestFileLn();
+ WriteXMLtagBegin("AdditionalIncludeDirectories");
+ Write_src_d_ToDestFile();
+ WriteCStrToDestFile(";%(AdditionalIncludeDirectories)");
+ WriteXMLtagEnd("AdditionalIncludeDirectories");
+ WriteEndDestFileLn();
+ WriteEndXMLtagLine("ResourceCompile");
+
+ WriteBeginXMLtagLine("Link");
+ WriteXMLtagBeginValEndLine("SubSystem", "Windows");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagBeginValEndLine(
+ "GenerateDebugInformation", "true");
+ } else {
+ WriteXMLtagBeginValEndLine(
+ "GenerateDebugInformation", "false");
+ }
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteXMLtagBeginValEndLine("EnableCOMDATFolding",
+ "true");
+ WriteXMLtagBeginValEndLine("OptimizeReferences",
+ "true");
+ }
+ WriteDestFileLn("<AdditionalDependencies>"
+ "winmm.lib;%(AdditionalDependencies)"
+ "</AdditionalDependencies>");
+ WriteXMLtagBeginProcValEndLine("OutputFile",
+ WriteAppNamePath);
+ WriteXMLtagBeginValEndLine("RandomizedBaseAddress",
+ "false");
+ WriteEndXMLtagLine("Link");
+ --DestFileIndent;
+ WriteDestFileLn("</ItemDefinitionGroup>");
+
+ WriteBeginXMLtagLine("ItemGroup");
+ DoAllDocTypesWithSetup(DoMSVC10XMLAddDocType);
+ WriteEndXMLtagLine("ItemGroup");
+
+ WriteBeginXMLtagLine("ItemGroup");
+ DoAllSrcFilesWithSetup(
+ DoSrcFileMSVC10XMLAddHeaderFile);
+ DoAllExtraHeaders2WithSetup(
+ DoMSVC10XMLAddAddExtraHeader);
+ WriteEndXMLtagLine("ItemGroup");
+
+ WriteBeginXMLtagLine("ItemGroup");
+ DoAllSrcFilesWithSetup(
+ DoSrcFileMSVC10XMLAddFile);
+ WriteEndXMLtagLine("ItemGroup");
+
+ WriteBeginXMLtagLine("ItemGroup");
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<ResourceCompile Include=\"");
+ WriteMainRsrcSrcPath();
+ WriteCStrToDestFile("\" />");
+ WriteEndDestFileLn();
+ WriteEndXMLtagLine("ItemGroup");
+
+ WriteDestFileLn("<Import Project=\""
+ "$(VCTargetsPath)\\Microsoft.Cpp.targets\" />");
+ WriteDestFileLn("<ImportGroup Label=\"ExtensionTargets\">");
+ WriteDestFileLn("</ImportGroup>");
+ --DestFileIndent;
+ WriteDestFileLn("</Project>");
+}
+
+LOCALPROC DoSrcFileMSVC10XMLAddClCompile(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<ClCompile Include=\"");
+ WriteSrcFileFilePath();
+ WriteCStrToDestFile("\">");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+
+ WriteDestFileLn("<Filter>Source Files</Filter>");
+
+ --DestFileIndent;
+ WriteDestFileLn("</ClCompile>");
+}
+
+LOCALPROC DoSrcFileMSVC10XMLAddClInclude(void)
+{
+ if ((DoSrcFile_gd()->Flgm & kCSrcFlgmNoHeader) == 0) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<ClInclude Include=\"");
+ WriteSrcFileHeaderPath();
+ WriteCStrToDestFile("\">");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+
+ WriteDestFileLn("<Filter>Header Files</Filter>");
+
+ --DestFileIndent;
+ WriteDestFileLn("</ClInclude>");
+ }
+}
+
+LOCALPROC DoExtraHeaderMSVC10XMLAddClInclude(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<ClInclude Include=\"");
+ WriteExtraHeaderFilePath();
+ WriteCStrToDestFile("\">");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+
+ WriteDestFileLn("<Filter>Include Files</Filter>");
+
+ --DestFileIndent;
+ WriteDestFileLn("</ClInclude>");
+}
+
+LOCALPROC WriteDocTypeMSVC10resource(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<None Include=\"");
+ WriteDocTypeIconFilePath();
+ WriteCStrToDestFile("\">");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteDestFileLn("<Filter>Resource Files</Filter>");
+ --DestFileIndent;
+ WriteDestFileLn("</None>");
+}
+
+LOCALPROC WriteMSVC10XMLProjectFiltersProps(void)
+{
+ WriteCStrToDestFile(" ToolsVersion=\"4.0\" xmlns="
+ "\"http://schemas.microsoft.com/developer/msbuild/2003\"");
+}
+
+LOCALPROC WriteMSVC10XMLProjectFiltersBodyFilters(void)
+{
+ WriteDestFileLn("<Filter Include=\"Header Files\">");
+ ++DestFileIndent;
+ WriteDestFileLn("<UniqueIdentifier>"
+ "{00030000-0000-0000-0000-000000000000}"
+ "</UniqueIdentifier>");
+ WriteDestFileLn("<Extensions>"
+ "h;hpp;hxx;hm;inl;inc;xsd"
+ "</Extensions>");
+ --DestFileIndent;
+ WriteDestFileLn("</Filter>");
+
+ WriteDestFileLn("<Filter Include=\"Resource Files\">");
+ ++DestFileIndent;
+ WriteDestFileLn("<UniqueIdentifier>"
+ "{00040000-0000-0000-0000-000000000000}"
+ "</UniqueIdentifier>");
+ WriteDestFileLn("<Extensions>"
+ "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;"
+ "resx;tiff;tif;png;wav"
+ "</Extensions>");
+ --DestFileIndent;
+ WriteDestFileLn("</Filter>");
+
+ WriteDestFileLn("<Filter Include=\"Include Files\">");
+ ++DestFileIndent;
+ WriteDestFileLn("<UniqueIdentifier>"
+ "{00050000-0000-0000-0000-000000000000}"
+ "</UniqueIdentifier>");
+ WriteDestFileLn("<Extensions>"
+ "h;hpp;hxx;hm;inl;inc;xsd"
+ "</Extensions>");
+ --DestFileIndent;
+ WriteDestFileLn("</Filter>");
+
+ WriteDestFileLn("<Filter Include=\"Source Files\">");
+ ++DestFileIndent;
+ WriteDestFileLn("<UniqueIdentifier>"
+ "{00020000-0000-0000-0000-000000000000}"
+ "</UniqueIdentifier>");
+ WriteDestFileLn("<Extensions>"
+ "cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ "</Extensions>");
+ --DestFileIndent;
+ WriteDestFileLn("</Filter>");
+}
+
+LOCALPROC WriteMSVC10XMLProjectFiltersBodyClCompiles(void)
+{
+ DoAllSrcFilesWithSetup(
+ DoSrcFileMSVC10XMLAddClCompile);
+}
+
+LOCALPROC WriteMSVC10XMLProjectFiltersBodyClIncludes(void)
+{
+ DoAllSrcFilesWithSetup(
+ DoSrcFileMSVC10XMLAddClInclude);
+ DoAllExtraHeaders2WithSetup(
+ DoExtraHeaderMSVC10XMLAddClInclude);
+}
+
+LOCALPROC WriteMSVC10XMLProjectFiltersBodyResourceCompileProp(void)
+{
+ WriteCStrToDestFile(" Include=\"");
+ WriteMainRsrcSrcPath();
+ WriteCStrToDestFile("\"");
+}
+
+LOCALPROC WriteMSVC10XMLProjectFiltersBodyResourceCompileBody(void)
+{
+ WriteXMLtagBeginValEndLine("Filter", "Resource Files");
+}
+
+LOCALPROC WriteMSVC10XMLProjectFiltersBodyResourceCompiles(void)
+{
+ WriteXMLtaggedLinesWith1LnProps("ResourceCompile",
+ WriteMSVC10XMLProjectFiltersBodyResourceCompileProp,
+ WriteMSVC10XMLProjectFiltersBodyResourceCompileBody);
+}
+
+LOCALPROC WriteMSVC10XMLProjectFiltersBodyResourceFiles(void)
+{
+ DoAllDocTypesWithSetup(WriteDocTypeMSVC10resource);
+}
+
+LOCALPROC WriteMSVC10XMLProjectFiltersItemGroup(MyProc p)
+{
+ WriteXMLtaggedLines("ItemGroup", p);
+}
+
+LOCALPROC WriteMSVC10XMLProjectFiltersBody(void)
+{
+ WriteMSVC10XMLProjectFiltersItemGroup(
+ WriteMSVC10XMLProjectFiltersBodyFilters);
+ WriteMSVC10XMLProjectFiltersItemGroup(
+ WriteMSVC10XMLProjectFiltersBodyClCompiles);
+ WriteMSVC10XMLProjectFiltersItemGroup(
+ WriteMSVC10XMLProjectFiltersBodyClIncludes);
+ WriteMSVC10XMLProjectFiltersItemGroup(
+ WriteMSVC10XMLProjectFiltersBodyResourceCompiles);
+ WriteMSVC10XMLProjectFiltersItemGroup(
+ WriteMSVC10XMLProjectFiltersBodyResourceFiles);
+}
+
+LOCALPROC WriteMSVCXML10ProjectFiltersFile(void)
+{
+ WriteCStrToDestFile("\357\273\277"); /* UTF-8 byte-order mark */
+ WriteDestFileLn("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+ WriteXMLtaggedLinesWith1LnProps("Project",
+ WriteMSVC10XMLProjectFiltersProps,
+ WriteMSVC10XMLProjectFiltersBody);
+}
+
+LOCALPROC WriteMSVCXML10SpecificFiles(void)
+{
+ WriteADstFile1("my_project_d",
+ vStrAppAbbrev, ".sln", "Solutions file",
+ WriteMSVCXMLSolutionFile);
+ WriteADstFile1("my_project_d",
+ vStrAppAbbrev, ".vcxproj", "Project file",
+ WriteMSVCXML10ProjectFile);
+ WriteADstFile1("my_project_d",
+ vStrAppAbbrev, ".vcxproj.filters", "Project Filters file",
+ WriteMSVCXML10ProjectFiltersFile);
+}
+
+LOCALPROC WriteMsvSpecificFiles(void)
+{
+ if (UseCmndLine) {
+ WriteNMakeSpecificFiles();
+ } else {
+ if (ide_vers >= 10000) {
+ WriteMSVCXML10SpecificFiles();
+ } else if (ide_vers >= 7000) {
+ WriteMSVCXMLSpecificFiles();
+ } else {
+ WriteMSVCSpecificFiles();
+ }
+ }
+}
--- /dev/null
+++ b/setup/WRMVCFLS.i
@@ -1,0 +1,595 @@
+/*
+ WRMVCFLS.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite Mini vMac C specific FiLeS
+*/
+
+
+LOCALPROC WriteMVCCompileAsmLinkCommonOptions(void)
+{
+ {
+ switch (cur_targ) {
+ case gbk_targ_mach:
+ case gbk_targ_imch:
+ case gbk_targ_mc64:
+ case gbk_targ_mx11:
+ case gbk_targ_mi11:
+ case gbk_targ_mx64:
+ if (gbk_cpufam_x86 == gbo_cpufam) {
+ WriteCStrToDestFile(" -arch i386");
+ } else if (gbk_cpufam_x64 == gbo_cpufam) {
+ WriteCStrToDestFile(" -arch x86_64");
+ } else {
+ WriteCStrToDestFile(" -arch ppc");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ((gbk_apifam_osx == gbo_apifam)
+ || (gbk_apifam_cco == gbo_apifam))
+ {
+ if (gbk_cpufam_ppc == gbo_cpufam) {
+ WriteCStrToDestFile(" -mmacosx-version-min=10.1");
+ } else
+ if (gbk_cpufam_x64 == gbo_cpufam) {
+ WriteCStrToDestFile(" -mmacosx-version-min=10.5");
+ } else
+ {
+ WriteCStrToDestFile(" -mmacosx-version-min=10.4");
+ }
+ }
+}
+
+LOCALPROC WriteMVCLinkOSGlucompileCommonOptions(void)
+{
+ if ((gbk_apifam_osx == gbo_apifam)
+ || (gbk_apifam_cco == gbo_apifam))
+ {
+ WriteCStrToDestFile(" -isysroot");
+ if (ide_vers >= 3200) {
+ WriteCStrToDestFile(" /Developer/SDKs/MacOSX10.6.sdk");
+ } else if ((ide_vers >= 3100)
+ || (gbk_cpufam_x64 == gbo_cpufam))
+ {
+ WriteCStrToDestFile(" /Developer/SDKs/MacOSX10.5.sdk");
+ } else {
+ WriteCStrToDestFile(" /Developer/SDKs/MacOSX10.4u.sdk");
+ }
+ }
+}
+
+LOCALPROC WriteMVCCompileLinkCommonOptions(void)
+{
+#if 0
+ WriteCStrToDestFile(" -Werror");
+#endif
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteCStrToDestFile(" -g");
+ }
+}
+
+LOCALPROC WriteMVCCOptions(void)
+{
+ WriteCStrToDestFile(
+ " -Wall -Wmissing-prototypes -Wno-uninitialized");
+
+ WriteCStrToDestFile(" -Wundef -Wstrict-prototypes");
+
+ if (gbk_apifam_osx == gbo_apifam) {
+ WriteCStrToDestFile(" -Wno-deprecated-declarations");
+ }
+ WriteCStrToDestFile(" -fomit-frame-pointer");
+ WriteCStrToDestFile(" -fno-strict-aliasing");
+ WriteCStrToDestFile(" -fno-asynchronous-unwind-tables");
+ WriteCStrToDestFile(
+ " -Winline --param large-function-growth=1000");
+ if (gbk_targ_wcar == cur_targ) {
+ WriteCStrToDestFile(" -fno-leading-underscore");
+ }
+ switch (cur_targ) {
+ case gbk_targ_mach:
+ case gbk_targ_imch:
+ case gbk_targ_mc64:
+ case gbk_targ_mx11:
+ case gbk_targ_mi11:
+ case gbk_targ_mx64:
+ WriteCStrToDestFile(" -mdynamic-no-pic");
+ break;
+ }
+ WriteMVCCompileAsmLinkCommonOptions();
+ WriteMVCCompileLinkCommonOptions();
+
+ if (1 /* WantConfigDir */) {
+ WriteCStrToDestFile(" -I./");
+ Write_cfg_d_Name();
+ WriteCStrToDestFile(" -I./");
+ Write_src_d_Name();
+ }
+}
+
+LOCALPROC WriteMVCCOptOptions(void)
+{
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteCStrToDestFile(" -Os");
+ } else {
+ WriteCStrToDestFile(" -O0");
+ }
+}
+
+LOCALPROC DoFrameWorkMVCaddFile(void)
+{
+ WriteCStrToDestFile(" -framework ");
+ WriteCStrToDestFile(DoFrameWork_gd()->s);
+}
+
+LOCALPROC Write_machoRsrcMVCDeps(void)
+{
+ WriteMakeDependFile(WriteMainRsrcSrcPath);
+ WriteMakeDependFile(Write_machoAppIconPath);
+}
+
+LOCALPROC Write_machoRsrcMVCBuild(void)
+{
+ WriteDestFileLn("/Developer/Tools/Rez \\");
+ ++DestFileIndent;
+ WriteDestFileLn("-i /Developer/Headers/FlatCarbon \\");
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("\"");
+ WriteMainRsrcSrcPath();
+ WriteCStrToDestFile("\" \\");
+ WriteEndDestFileLn();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("-o \"");
+ Write_machoRsrcPath();
+ WriteCStrToDestFile("\" \\");
+ WriteEndDestFileLn();
+ WriteDestFileLn("-useDF");
+ --DestFileIndent;
+}
+
+LOCALPROC WriteMVCSrcFileAsmName(void)
+{
+ WriteCStrToDestFile(DoSrcFile_gd()->s);
+ WriteCStrToDestFile(".s");
+}
+
+LOCALPROC WriteMVCSrcFileAsmPath(void)
+{
+ WriteFileInDirToDestFile0(Write_obj_d_ToDestFile,
+ WriteMVCSrcFileAsmName);
+}
+
+LOCALPROC DoMVCSrcFileMakeCompileBody(void)
+{
+ blnr UseAPI = (DoSrcFile_gd()->Flgm & kCSrcFlgmUseAPI) != 0;
+ blnr Fast = (DoSrcFile_gd()->Flgm & kCSrcFlgmSortFirst) != 0;
+
+ WriteBgnDestFileLn();
+
+ WriteCStrToDestFile("$(my_prefix)gcc -S");
+ WritePathArgInMakeCmnd(WriteSrcFileFilePath);
+ WriteCStrToDestFile(" -o");
+ WritePathArgInMakeCmnd(WriteMVCSrcFileAsmPath);
+ WriteSpaceToDestFile();
+ if (! UseAPI) {
+ if (Fast) {
+ WriteMakeVar("mk_COptionsFast");
+ } else {
+ WriteMakeVar("mk_COptions");
+ }
+ } else {
+ WriteMakeVar("mk_COptionsOSGLU");
+ }
+
+ WriteEndDestFileLn();
+}
+
+LOCALPROC DoMVCSrcFileMakeAsmBody(void)
+{
+ WriteBgnDestFileLn();
+
+ WriteCStrToDestFile("$(my_prefix)gcc -c");
+ WritePathArgInMakeCmnd(WriteMVCSrcFileAsmPath);
+ WriteCStrToDestFile(" -o");
+ WritePathArgInMakeCmnd(WriteSrcFileObjPath);
+
+ WriteEndDestFileLn();
+}
+
+LOCALPROC DoMVCSrcFileMakeAsmDeps(void)
+{
+ WriteMakeDependFile(WriteMVCSrcFileAsmPath);
+}
+
+LOCALPROC DoMVCSrcFileMakeCompile(void)
+{
+ WriteMakeRule(WriteMVCSrcFileAsmPath,
+ DoSrcFileMakeCompileDeps,
+ DoMVCSrcFileMakeCompileBody);
+}
+
+LOCALPROC DoMVCSrcFileMakeAsm(void)
+{
+ WriteMakeRule(WriteSrcFileObjPath,
+ DoMVCSrcFileMakeAsmDeps,
+ DoMVCSrcFileMakeAsmBody);
+}
+
+LOCALPROC DoMVCSrcFileStandardMakeAsms(void)
+{
+ WriteBgnDestFileLn();
+ WriteMVCSrcFileAsmPath();
+ WriteSpaceToDestFile();
+ WriteBackSlashToDestFile();
+ WriteEndDestFileLn();
+}
+
+LOCALPROC DoMVCAllSrcFilesStandardMakeAsms(void)
+{
+ DoAllSrcFilesSortWithSetup(DoMVCSrcFileStandardMakeAsms);
+}
+
+LOCALPROC WriteMVCMakeFile(void)
+{
+ WriteDestFileLn("# make file generated by gryphel build system");
+
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptionsCommon =");
+ WriteMVCCOptions();
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptionsOSGLU = $(mk_COptionsCommon)");
+ if (gbk_apifam_osx == gbo_apifam) {
+ WriteCStrToDestFile(" -Wno-multichar");
+ }
+ WriteMVCLinkOSGlucompileCommonOptions();
+ WriteMVCCOptOptions();
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptionsNotOS = $(mk_COptionsCommon)");
+ if (gbk_cpufam_x86 == gbo_cpufam) {
+ WriteCStrToDestFile(" -mpreferred-stack-boundary=2");
+ }
+ WriteCStrToDestFile(" -fno-toplevel-reorder");
+ if (gbk_cpufam_x86 == gbo_cpufam) {
+ WriteCStrToDestFile(" -mtune=generic -march=i386");
+ }
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptions = $(mk_COptionsNotOS)");
+ WriteMVCCOptOptions();
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptionsFast = $(mk_COptionsNotOS)");
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteCStrToDestFile(
+ " -O2 -fno-align-functions -fno-align-labels");
+ } else {
+ WriteMVCCOptOptions();
+ }
+ WriteEndDestFileLn();
+
+ switch (cur_targ) {
+ case gbk_targ_mach:
+ WriteDestFileLn("my_prefix = powerpc-apple-darwin9-");
+ break;
+ case gbk_targ_imch:
+ WriteDestFileLn("my_prefix = i686-apple-darwin11-");
+ break;
+ case gbk_targ_mc64:
+ WriteDestFileLn("my_prefix = x86_64-apple-darwin11-");
+ break;
+ case gbk_targ_wx86:
+ WriteDestFileLn("my_prefix = i686-w64-mingw32-");
+ break;
+ case gbk_targ_wx64:
+ WriteDestFileLn("my_prefix = x86_64-w64-mingw32-");
+ break;
+ case gbk_targ_lx86:
+ WriteDestFileLn("my_prefix = i386-pc-linux-");
+ break;
+ case gbk_targ_lx64:
+ WriteDestFileLn("my_prefix = x86_64-linux-gnu-");
+ break;
+ case gbk_targ_larm:
+ WriteDestFileLn("my_prefix = arm-linux-gnueabi-");
+ break;
+ case gbk_targ_lppc:
+ WriteDestFileLn("my_prefix = powerpc-linux-gnu-");
+ break;
+ case gbk_targ_lspr:
+ WriteDestFileLn("my_prefix = sparc-linux-gnu-");
+ break;
+ case gbk_targ_fbsd:
+ WriteDestFileLn("my_prefix = i386-pc-freebsd9-");
+ break;
+ case gbk_targ_fb64:
+ WriteDestFileLn("my_prefix = x86_64-pc-freebsd9-");
+ break;
+ case gbk_targ_nbsd:
+ WriteDestFileLn("my_prefix = i386-pc-netbsdelf-");
+ break;
+ case gbk_targ_nb64:
+ WriteDestFileLn("my_prefix = x86_64-pc-netbsdelf-");
+ break;
+ case gbk_targ_oind:
+ WriteDestFileLn("my_prefix = i386-pc-solaris2.11-");
+ break;
+ case gbk_targ_oi64:
+ WriteDestFileLn("my_prefix = x86_64-pc-solaris2.11-");
+ break;
+ case gbk_targ_wcar:
+ WriteDestFileLn("my_prefix = arm-wince-pe-");
+ break;
+ }
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(".PHONY: TheDefaultOutput clean");
+
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("TheDefaultOutput :");
+ WriteMakeDependFile(Write_machobinpath_ToDestFile);
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ DoAllSrcFilesWithSetup(DoMVCSrcFileMakeCompile);
+
+ WriteBlankLineToDestFile();
+ DoAllSrcFilesWithSetup(DoMVCSrcFileMakeAsm);
+
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("AsmFiles = ");
+ WriteBackSlashToDestFile();
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ DoMVCAllSrcFilesStandardMakeAsms();
+ WriteBlankLineToDestFile();
+ --DestFileIndent;
+
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("ObjFiles = ");
+ WriteBackSlashToDestFile();
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ DoAllSrcFilesStandardMakeObjects();
+ WriteBlankLineToDestFile();
+ --DestFileIndent;
+
+ if (HaveMacBundleApp) {
+ WriteBlankLineToDestFile();
+ WriteMakeRule(Write_machoAppIconPath,
+ Write_tmachoShellDeps,
+ Write_tmachoShell);
+ }
+ if (gbk_apifam_win == gbo_apifam) {
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteMainRsrcObjPath();
+ WriteCStrToDestFile(": ");
+ WriteMainRsrcSrcPath();
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("$(my_prefix)windres");
+ WriteCStrToDestFile(" -i");
+ WritePathArgInMakeCmnd(WriteMainRsrcSrcPath);
+ WriteCStrToDestFile(" --input-format=rc -o");
+ WritePathArgInMakeCmnd(WriteMainRsrcObjPath);
+ WriteCStrToDestFile(" -O coff --include-dir SRC");
+ WriteEndDestFileLn();
+ --DestFileIndent;
+ WriteBlankLineToDestFile();
+ }
+
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ Write_machobinpath_ToDestFile();
+ WriteCStrToDestFile(" : $(AsmFiles) $(ObjFiles)");
+ if (HaveMacBundleApp) {
+ WriteMakeDependFile(Write_machoAppIconPath);
+ }
+ if (HaveMacRrscs) {
+ WriteMakeDependFile(Write_machoRsrcPath);
+ }
+ if (gbk_apifam_win == gbo_apifam) {
+ WriteMakeDependFile(WriteMainRsrcObjPath);
+ }
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ switch (cur_targ) {
+ case gbk_targ_mach:
+ case gbk_targ_imch:
+ case gbk_targ_mc64:
+ case gbk_targ_mx11:
+ case gbk_targ_mi11:
+ case gbk_targ_mx64:
+ WriteCStrToDestFile("gcc");
+ break;
+ default:
+ WriteCStrToDestFile("$(my_prefix)gcc");
+ break;
+ }
+ WriteCStrToDestFile(" \\");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("-o");
+ WritePathArgInMakeCmnd(Write_machobinpath_ToDestFile);
+ WriteCStrToDestFile(" \\");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("$(ObjFiles)");
+ if ((gbk_apifam_osx == gbo_apifam)
+ || (gbk_apifam_cco == gbo_apifam))
+ {
+ DoAllFrameWorksWithSetup(DoFrameWorkMVCaddFile);
+ if (gbk_targ_mach == cur_targ) {
+ WriteCStrToDestFile(
+ " /usr/local/mvmc/mach"
+ "/lib/darwin-gpsave.o");
+ }
+ if (ide_vers >= 4000) {
+ WriteCStrToDestFile(" -Wl,-no_pie");
+ }
+ WriteCStrToDestFile(" -nodefaultlibs -lSystem");
+ if ((gbk_targ_mach == cur_targ) && WantLocalTalk) {
+ WriteCStrToDestFile(" -lSystemStubs");
+ }
+ } else if (gbk_apifam_win == gbo_apifam) {
+ WritePathArgInMakeCmnd(WriteMainRsrcObjPath);
+ if (gbk_targ_wcar == cur_targ) {
+ WriteCStrToDestFile(
+ " /usr/local/mvmc/wcar/lib/divlib.o"
+ " -lmingw32");
+ WriteCStrToDestFile(
+ " -lcommctrl -lcoredll -laygshell -lmmtimer");
+ WriteCStrToDestFile(" -static-libgcc");
+ } else {
+ WriteCStrToDestFile(
+ " -mwindows -lwinmm -lole32 -luuid");
+ }
+ } else {
+ if (gbk_targfam_slrs == gbo_targfam) {
+ WriteCStrToDestFile(" -lposix4");
+ }
+#if MayUseSound
+ if (gbk_sndapi_alsa == gbo_sndapi) {
+ WriteCStrToDestFile(" -ldl");
+#if 0
+ WriteCStrToDestFile(" -lasound");
+#endif
+ } else if (gbk_sndapi_ddsp == gbo_sndapi) {
+ if ((gbk_targfam_nbsd == gbo_targfam)
+ || (gbk_targfam_obsd == gbo_targfam))
+ {
+ WriteCStrToDestFile(" -lossaudio");
+ }
+ }
+#endif
+#if 0
+ WriteCStrToDestFile(" -lXext");
+#endif
+ if (gbk_targfam_nbsd == gbo_targfam) {
+ WriteCStrToDestFile(" -R/usr/X11R7/lib");
+ }
+ WriteCStrToDestFile(" -lX11");
+ switch (cur_targ) {
+ case gbk_targ_lx86:
+ case gbk_targ_lx64:
+ case gbk_targ_larm:
+ case gbk_targ_lppc:
+ case gbk_targ_lspr:
+ case gbk_targ_fbsd:
+ case gbk_targ_fb64:
+ case gbk_targ_nbsd:
+ case gbk_targ_nb64:
+ case gbk_targ_oind:
+ case gbk_targ_oi64:
+ case gbk_targ_wcar:
+ WriteCStrToDestFile(" -static-libgcc");
+ break;
+ }
+ }
+ WriteMVCCompileAsmLinkCommonOptions();
+ WriteMVCLinkOSGlucompileCommonOptions();
+ WriteMVCCompileLinkCommonOptions();
+ WriteEndDestFileLn();
+ --DestFileIndent;
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteBgnDestFileLn();
+ switch (cur_targ) {
+ case gbk_targ_mach:
+ case gbk_targ_imch:
+ case gbk_targ_mc64:
+ case gbk_targ_mx11:
+ case gbk_targ_mi11:
+ case gbk_targ_mx64:
+ WriteCStrToDestFile("strip -u -r");
+ break;
+ default:
+ WriteCStrToDestFile("$(my_prefix)strip");
+ break;
+ }
+ WritePathArgInMakeCmnd(
+ Write_machobinpath_ToDestFile);
+ WriteEndDestFileLn();
+ }
+ --DestFileIndent;
+
+ if (HaveMacRrscs) {
+ WriteBlankLineToDestFile();
+ WriteMakeRule(Write_machoRsrcPath,
+ Write_machoRsrcMVCDeps,
+ Write_machoRsrcMVCBuild);
+ }
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("clean :");
+ ++DestFileIndent;
+ WriteDestFileLn("rm -f $(AsmFiles) $(ObjFiles)");
+ if (HaveMacBundleApp) {
+ WriteRmDir(WriteAppNamePath);
+ } else {
+ if (gbk_apifam_win == gbo_apifam) {
+ WriteRmFile(WriteMainRsrcObjPath);
+ }
+ WriteRmFile(WriteAppNamePath);
+ }
+ --DestFileIndent;
+}
+
+LOCALPROC WriteWantSigningFlag(void)
+{
+ WriteOpenDestFile("my_config_d",
+ "codesign", ".txt", "code signing flag");
+
+ WriteDestFileLn("1");
+
+ WriteCloseDestFile();
+}
+
+LOCALPROC WriteMVCSpecificFiles(void)
+{
+ if (HaveMacBundleApp) {
+ WritePListData();
+ }
+
+ if (WantSigning) {
+ WriteWantSigningFlag();
+ }
+
+ if (WantSandbox) {
+ WriteEntitlementsData();
+ }
+
+ WriteADstFile1("my_project_d",
+ "Makefile", "", "Make file",
+ WriteMVCMakeFile);
+}
--- /dev/null
+++ b/setup/WRMW8FLS.i
@@ -1,0 +1,870 @@
+/*
+ WRMW8FLS.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite MetroWerks 8 specific FiLeS
+*/
+
+
+
+static void WriteXMLtagSettingNameProcVal(char *n, MyProc v)
+{
+ WriteBgnDestFileLn();
+ WriteXMLtagBegin("SETTING");
+ WriteXMLtagBegin("NAME");
+ WriteCStrToDestFile(n);
+ WriteXMLtagEnd("NAME");
+ WriteXMLtagBegin("VALUE");
+ v();
+ WriteXMLtagEnd("VALUE");
+ WriteXMLtagEnd("SETTING");
+ WriteEndDestFileLn();
+}
+
+static void WriteXMLtagSettingNameVal(char *n, char *v)
+{
+ MyPtr SavepDt = pDt;
+
+ pDt = (MyPtr)v;
+ WriteXMLtagSettingNameProcVal(n, WritepDtString);
+ pDt = SavepDt;
+}
+
+static void WriteBeginNamedSettingXMLtagLine(char *s)
+{
+ WriteBgnDestFileLn();
+ WriteXMLtagBegin("SETTING");
+ WriteXMLtagBegin("NAME");
+ WriteCStrToDestFile(s);
+ WriteXMLtagEnd("NAME");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+}
+
+static void WriteAllMWTargetName(void)
+{
+ WriteXMLtagBeginProcValEndLine("TARGETNAME", WriteAppVariationStr);
+}
+
+typedef void (*tWriteMWLib)(char *s);
+
+static void WriteMWLibs(tWriteMWLib p)
+{
+ if (gbk_targfam_mswn == gbo_targfam) {
+ p("kernel32.lib");
+ p("user32.lib");
+ p("gdi32.lib");
+ p("comdlg32.lib");
+ p("shell32.lib");
+ p("ole32.lib");
+ p("uuid.lib");
+ p("winmm.lib");
+ if (WantIconMaster) {
+ p("advapi32.lib");
+ }
+ p("MSL_All_x86.lib");
+ } else if (gbk_targfam_mach == gbo_targfam) {
+ p("crt1.o");
+ p("MSL_All_Mach-O_D.lib");
+ } else {
+ if (gbk_targfam_carb == gbo_targfam) {
+ p("CarbonLib");
+#if UseOpenGLinOSX
+ p("OpenGLLibraryStub");
+#endif
+ } else {
+ p("InterfaceLib");
+ p("MathLib");
+ p("AppearanceLib");
+ p("MenusLib");
+ p("NavigationLib");
+ p("DragLib");
+ p("WindowsLib");
+ }
+ p("MSL_Runtime_PPC.Lib");
+ }
+}
+
+static void WriteMWLibAddFile(char *s)
+{
+ WriteBeginXMLtagLine("FILE");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginValEndLine("PATH", s);
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ if (gbk_targfam_mswn == gbo_targfam) {
+ WriteXMLtagBeginValEndLine("FILEKIND", "Unknown");
+ } else {
+ WriteXMLtagBeginValEndLine("FILEKIND", "Library");
+ }
+ WriteXMLtagBeginValEndLine("FILEFLAGS", "");
+ WriteEndXMLtagLine("FILE");
+}
+
+static void WriteMWLibMakeObjects(char *s)
+{
+ WriteBeginXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginValEndLine("PATH", s);
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+}
+
+static void WriteMWLibGroupList(char *s)
+{
+ WriteBeginXMLtagLine("FILEREF");
+ WriteAllMWTargetName();
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginValEndLine("PATH", s);
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+}
+
+static void WriteMWProjRelSearchPath(MyProc p)
+{
+ WriteBeginXMLtagLine("SETTING");
+ WriteBeginNamedSettingXMLtagLine("SearchPath");
+ WriteBgnDestFileLn();
+ WriteXMLtagBegin("SETTING");
+ WriteXMLtagBegin("NAME");
+ WriteCStrToDestFile("Path");
+ WriteXMLtagEnd("NAME");
+ WriteXMLtagBegin("VALUE");
+ p();
+ WriteXMLtagEnd("VALUE");
+ WriteXMLtagEnd("SETTING");
+ WriteEndDestFileLn();
+
+ WriteXMLtagSettingNameVal("PathFormat", "MacOS");
+ WriteXMLtagSettingNameVal("PathRoot", "Project");
+ WriteEndXMLtagLine("SETTING");
+ WriteXMLtagSettingNameVal("Recursive", "true");
+ WriteXMLtagSettingNameVal("FrameworkPath", "false");
+ WriteXMLtagSettingNameVal("HostFlags", "All");
+ WriteEndXMLtagLine("SETTING");
+}
+
+static void WriteMWDrvRelSearchPath(char *s)
+{
+ WriteBeginXMLtagLine("SETTING");
+ WriteBeginNamedSettingXMLtagLine("SearchPath");
+ WriteXMLtagSettingNameVal("Path", s);
+ WriteXMLtagSettingNameVal("PathFormat", "MacOS");
+ WriteXMLtagSettingNameVal("PathRoot", "Project");
+ WriteEndXMLtagLine("SETTING");
+ WriteXMLtagSettingNameVal("Recursive", "true");
+ WriteXMLtagSettingNameVal("FrameworkPath", "false");
+ WriteXMLtagSettingNameVal("HostFlags", "All");
+ WriteEndXMLtagLine("SETTING");
+}
+
+static void WriteBeginXMLMWGroup(char *s)
+{
+ WriteBgnDestFileLn();
+ WriteXMLtagBegin("GROUP");
+ WriteXMLtagBegin("NAME");
+ WriteCStrToDestFile(s);
+ WriteXMLtagEnd("NAME");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+}
+
+static void WriteMWSettingsPanelComment(char *s)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<!-- Settings for ");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(s);
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" panel -->");
+ WriteEndDestFileLn();
+}
+
+static void WriteDocTypeMWAddFile(void)
+{
+ WriteBeginXMLtagLine("FILE");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginProcValEndLine("PATH",
+ WriteDocTypeIconFileName);
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteXMLtagBeginValEndLine("FILEKIND", "Unknown");
+ WriteXMLtagBeginValEndLine("FILEFLAGS", "");
+ WriteEndXMLtagLine("FILE");
+}
+
+static void WriteDocTypeMWMakeObjects(void)
+{
+ WriteBeginXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginProcValEndLine("PATH",
+ WriteDocTypeIconFileName);
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+}
+
+static void WriteDocTypeMWGroupList(void)
+{
+ WriteBeginXMLtagLine("FILEREF");
+ WriteAllMWTargetName();
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginProcValEndLine("PATH",
+ WriteDocTypeIconFileName);
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+}
+
+static void DoSrcFileMW8AddFile(void)
+{
+ WriteBeginXMLtagLine("FILE");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginProcValEndLine("PATH", WriteSrcFileFileName);
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteXMLtagBeginValEndLine("FILEKIND", "Text");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagBeginValEndLine("FILEFLAGS", "Debug");
+ } else {
+ WriteXMLtagBeginValEndLine("FILEFLAGS", "");
+ }
+ WriteEndXMLtagLine("FILE");
+}
+
+static void DoSrcFileMW8sMakeObjects(void)
+{
+ WriteBeginXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginProcValEndLine("PATH", WriteSrcFileFileName);
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+}
+
+LOCALPROC DoSrcFileMW8GroupList(void)
+{
+ WriteBeginXMLtagLine("FILEREF");
+ WriteAllMWTargetName();
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginProcValEndLine("PATH", WriteSrcFileFileName);
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+}
+
+LOCALPROC WriteMetrowerksProjectFile(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<?xml version=");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("1.0");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" encoding=");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("UTF-8");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" standalone=");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("yes");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" ?>");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<?codewarrior exportversion=");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("1.0.1");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" ideversion=");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("5.0");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" ?>");
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ WriteBeginXMLtagLine("PROJECT");
+ WriteBeginXMLtagLine("TARGETLIST");
+ WriteBeginXMLtagLine("TARGET");
+ WriteXMLtagBeginProcValEndLine("NAME", WriteAppVariationStr);
+ WriteBeginXMLtagLine("SETTINGLIST");
+ WriteMWSettingsPanelComment("Access Paths");
+ if (gbk_targfam_mach == gbo_targfam) {
+ WriteXMLtagSettingNameVal(
+ "InterpretDOSAndUnixPaths", "true");
+ WriteXMLtagSettingNameVal(
+ "RequireFrameworkStyleIncludes", "true");
+ }
+ WriteBeginNamedSettingXMLtagLine("UserSearchPaths");
+ WriteMWProjRelSearchPath(Write_src_d_ToDestFile);
+ WriteMWProjRelSearchPath(Write_cfg_d_ToDestFile);
+ if (gbk_targfam_mach == gbo_targfam) {
+ /* seems to be wanted by property list compiler */
+ WriteMWDrvRelSearchPath(":");
+ }
+ WriteEndXMLtagLine("SETTING");
+ WriteBeginNamedSettingXMLtagLine("SystemSearchPaths");
+ if (gbk_targfam_mswn == gbo_targfam) {
+ WriteBeginXMLtagLine("SETTING");
+ WriteBeginNamedSettingXMLtagLine("SearchPath");
+ WriteXMLtagSettingNameVal("Path", ":MSL:");
+ WriteXMLtagSettingNameVal("PathFormat",
+ "MacOS");
+ WriteXMLtagSettingNameVal("PathRoot",
+ "CodeWarrior");
+ WriteEndXMLtagLine("SETTING");
+ WriteXMLtagSettingNameVal("Recursive", "true");
+ WriteXMLtagSettingNameVal("FrameworkPath",
+ "false");
+ WriteXMLtagSettingNameVal("HostFlags", "All");
+ WriteEndXMLtagLine("SETTING");
+
+ WriteBeginXMLtagLine("SETTING");
+ WriteBeginNamedSettingXMLtagLine("SearchPath");
+ WriteXMLtagSettingNameVal("Path",
+ ":Win32-x86 Support:");
+ WriteXMLtagSettingNameVal("PathFormat",
+ "MacOS");
+ WriteXMLtagSettingNameVal("PathRoot",
+ "CodeWarrior");
+ WriteEndXMLtagLine("SETTING");
+ WriteXMLtagSettingNameVal("Recursive", "true");
+ WriteXMLtagSettingNameVal("FrameworkPath",
+ "false");
+ WriteXMLtagSettingNameVal("HostFlags", "All");
+ WriteEndXMLtagLine("SETTING");
+ } else {
+ WriteBeginXMLtagLine("SETTING");
+ WriteBeginNamedSettingXMLtagLine("SearchPath");
+ WriteXMLtagSettingNameVal("Path",
+ ":MSL:MSL_C:");
+ WriteXMLtagSettingNameVal("PathFormat",
+ "MacOS");
+ WriteXMLtagSettingNameVal("PathRoot",
+ "CodeWarrior");
+ WriteEndXMLtagLine("SETTING");
+ WriteXMLtagSettingNameVal("Recursive", "true");
+ WriteXMLtagSettingNameVal("FrameworkPath",
+ "false");
+ WriteXMLtagSettingNameVal("HostFlags", "All");
+ WriteEndXMLtagLine("SETTING");
+
+ if (gbk_targfam_mach == gbo_targfam) {
+ WriteBeginXMLtagLine("SETTING");
+ WriteBeginNamedSettingXMLtagLine(
+ "SearchPath");
+ WriteXMLtagSettingNameVal("Path",
+ ":MacOS X Support:");
+ WriteXMLtagSettingNameVal("PathFormat",
+ "MacOS");
+ WriteXMLtagSettingNameVal("PathRoot",
+ "CodeWarrior");
+ WriteEndXMLtagLine("SETTING");
+ WriteXMLtagSettingNameVal("Recursive",
+ "true");
+ WriteXMLtagSettingNameVal("FrameworkPath",
+ "false");
+ WriteXMLtagSettingNameVal("HostFlags",
+ "All");
+ WriteEndXMLtagLine("SETTING");
+
+ WriteBeginXMLtagLine("SETTING");
+ WriteBeginNamedSettingXMLtagLine(
+ "SearchPath");
+ WriteXMLtagSettingNameVal("Path",
+ "/usr/include");
+ WriteXMLtagSettingNameVal("PathFormat",
+ "Unix");
+ WriteXMLtagSettingNameVal("PathRoot",
+ "Absolute");
+ WriteEndXMLtagLine("SETTING");
+ WriteXMLtagSettingNameVal("Recursive",
+ "false");
+ WriteXMLtagSettingNameVal("FrameworkPath",
+ "false");
+ WriteXMLtagSettingNameVal("HostFlags",
+ "All");
+ WriteEndXMLtagLine("SETTING");
+
+ WriteBeginXMLtagLine("SETTING");
+ WriteBeginNamedSettingXMLtagLine(
+ "SearchPath");
+ WriteXMLtagSettingNameVal("Path",
+ "/usr/lib");
+ WriteXMLtagSettingNameVal("PathFormat",
+ "Unix");
+ WriteXMLtagSettingNameVal("PathRoot",
+ "Absolute");
+ WriteEndXMLtagLine("SETTING");
+ WriteXMLtagSettingNameVal("Recursive",
+ "false");
+ WriteXMLtagSettingNameVal("FrameworkPath",
+ "false");
+ WriteXMLtagSettingNameVal("HostFlags",
+ "All");
+ WriteEndXMLtagLine("SETTING");
+
+ WriteBeginXMLtagLine("SETTING");
+ WriteBeginNamedSettingXMLtagLine(
+ "SearchPath");
+ WriteXMLtagSettingNameVal("Path",
+ "System/Library/Frameworks");
+ WriteXMLtagSettingNameVal("PathFormat",
+ "Unix");
+ WriteXMLtagSettingNameVal("PathRoot",
+ "OS X Volume");
+ WriteEndXMLtagLine("SETTING");
+ WriteXMLtagSettingNameVal("Recursive",
+ "false");
+ WriteXMLtagSettingNameVal("FrameworkPath",
+ "true");
+ WriteXMLtagSettingNameVal("HostFlags",
+ "All");
+ WriteEndXMLtagLine("SETTING");
+ } else {
+ WriteBeginXMLtagLine("SETTING");
+ WriteBeginNamedSettingXMLtagLine(
+ "SearchPath");
+ WriteXMLtagSettingNameVal("Path",
+ ":MacOS Support:");
+ WriteXMLtagSettingNameVal("PathFormat",
+ "MacOS");
+ WriteXMLtagSettingNameVal("PathRoot",
+ "CodeWarrior");
+ WriteEndXMLtagLine("SETTING");
+ WriteXMLtagSettingNameVal("Recursive",
+ "true");
+ WriteXMLtagSettingNameVal("FrameworkPath",
+ "false");
+ WriteXMLtagSettingNameVal("HostFlags",
+ "All");
+ WriteEndXMLtagLine("SETTING");
+ }
+ }
+
+ WriteEndXMLtagLine("SETTING");
+ WriteBlankLineToDestFile();
+ WriteMWSettingsPanelComment("Target Settings");
+ if (gbk_targ_wx86 == cur_targ) {
+ WriteXMLtagSettingNameVal("Linker",
+ "Win32 x86 Linker");
+ } else if (gbk_targ_mach == cur_targ) {
+ WriteXMLtagSettingNameVal("Linker",
+ "MacOS X PPC Linker");
+ } else {
+ WriteXMLtagSettingNameVal("Linker",
+ "MacOS PPC Linker");
+ }
+ WriteXMLtagSettingNameProcVal("Targetname",
+ WriteAppVariationStr);
+
+ WriteBeginNamedSettingXMLtagLine("OutputDirectory");
+ WriteXMLtagSettingNameVal("Path", ":");
+ WriteXMLtagSettingNameVal("PathFormat", "MacOS");
+ WriteXMLtagSettingNameVal("PathRoot", "Project");
+ WriteEndXMLtagLine("SETTING");
+
+ WriteBlankLineToDestFile();
+ WriteMWSettingsPanelComment("Build Extras");
+ WriteXMLtagSettingNameVal("BrowserGenerator", "0");
+
+ WriteBlankLineToDestFile();
+ WriteMWSettingsPanelComment("Debugger Target");
+ WriteXMLtagSettingNameVal("StopAtTempBPOnLaunch", "false");
+
+ WriteBlankLineToDestFile();
+ WriteMWSettingsPanelComment("C/C++ Compiler");
+ WriteXMLtagSettingNameVal("MWFrontEnd_C_checkprotos", "1");
+ WriteXMLtagSettingNameVal("MWFrontEnd_C_enableexceptions",
+ "0");
+ if ((gbk_dbg_on == gbo_dbg)
+ || (gbk_targfam_mswn == gbo_targfam))
+ {
+ /* inlining seems to give bad code for x86 version */
+ WriteXMLtagSettingNameVal("MWFrontEnd_C_dontinline",
+ "1");
+ } else {
+ WriteXMLtagSettingNameVal("MWFrontEnd_C_dontinline",
+ "0");
+ }
+ WriteXMLtagSettingNameVal("MWFrontEnd_C_useRTTI", "0");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagSettingNameVal("MWFrontEnd_C_autoinline",
+ "0");
+ } else {
+ WriteXMLtagSettingNameVal("MWFrontEnd_C_autoinline",
+ "1");
+ }
+
+ WriteBlankLineToDestFile();
+ WriteMWSettingsPanelComment("C/C++ Warnings");
+ WriteXMLtagSettingNameVal(
+ "MWWarning_C_warn_illpragma", "1");
+ WriteXMLtagSettingNameVal(
+ "MWWarning_C_warn_emptydecl", "1");
+ WriteXMLtagSettingNameVal(
+ "MWWarning_C_warn_possunwant", "1");
+ WriteXMLtagSettingNameVal(
+ "MWWarning_C_warn_unusedvar", "1");
+ WriteXMLtagSettingNameVal(
+ "MWWarning_C_warn_unusedarg", "1");
+ WriteXMLtagSettingNameVal(
+ "MWWarning_C_warn_extracomma", "1");
+ WriteXMLtagSettingNameVal(
+ "MWWarning_C_pedantic", "1");
+
+ WriteBlankLineToDestFile();
+ if (gbk_targfam_mswn == gbo_targfam) {
+ WriteMWSettingsPanelComment("x86 CodeGen");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_X86_intrinsics", "0");
+ } else {
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_X86_intrinsics", "1");
+ }
+ } else if (gbk_targ_mach == cur_targ) {
+ WriteMWSettingsPanelComment("PPC CodeGen Mach-O");
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_MachO_structalignment", "PPC");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_MachO_peephole", "0");
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_MachO_schedule", "0");
+ } else {
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_MachO_peephole", "1");
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_MachO_schedule", "1");
+ }
+ } else {
+ WriteMWSettingsPanelComment("PPC CodeGen");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_PPC_tracebacktables", "Inline");
+ } else {
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_PPC_tracebacktables", "None");
+ }
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_PPC_vectortocdata", "0");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_PPC_peephole", "0");
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_PPC_schedule", "0");
+ } else {
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_PPC_peephole", "1");
+ WriteXMLtagSettingNameVal(
+ "MWCodeGen_PPC_schedule", "1");
+ }
+ }
+
+ WriteBlankLineToDestFile();
+ if (gbk_targfam_mswn == gbo_targfam) {
+ WriteMWSettingsPanelComment("x86 Global Optimizer");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagSettingNameVal(
+ "GlobalOptimizer_X86_optimizationlevel",
+ "Level0");
+ } else {
+ WriteXMLtagSettingNameVal(
+ "GlobalOptimizer_X86_optimizationlevel",
+ "Level1");
+ /*
+ Level4 (and Level3 and Level2)
+ generates bade code.
+ */
+ }
+ WriteXMLtagSettingNameVal(
+ "GlobalOptimizer_X86_optfor", "Size");
+
+ /*
+ work around what is probably bug
+ in windows version of mw8
+ */
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagSettingNameVal(
+ "GlobalOptimizer_X86__optimizationlevel",
+ "Level0");
+ } else {
+ WriteXMLtagSettingNameVal(
+ "GlobalOptimizer_X86__optimizationlevel",
+ "Level1");
+ }
+ WriteXMLtagSettingNameVal(
+ "GlobalOptimizer_X86__optfor", "Size");
+ } else {
+ WriteMWSettingsPanelComment("PPC Global Optimizer");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagSettingNameVal(
+ "GlobalOptimizer_PPC_optimizationlevel",
+ "Level0");
+ } else {
+ WriteXMLtagSettingNameVal(
+ "GlobalOptimizer_PPC_optimizationlevel",
+ "Level4");
+ }
+ WriteXMLtagSettingNameVal(
+ "GlobalOptimizer_PPC_optfor", "Size");
+ }
+
+ WriteBlankLineToDestFile();
+ if (gbk_targfam_mswn == gbo_targfam) {
+ WriteMWSettingsPanelComment("x86 Linker");
+ WriteXMLtagSettingNameVal(
+ "MWLinker_X86_subsystem", "WinGUI");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagSettingNameVal(
+ "MWLinker_X86_linkdebug", "true");
+ } else {
+ WriteXMLtagSettingNameVal(
+ "MWLinker_X86_linkdebug", "false");
+ }
+ WriteXMLtagSettingNameVal(
+ "MWLinker_X86_usedefaultlibs", "false");
+ } else if (gbk_targ_mach == cur_targ) {
+ WriteMWSettingsPanelComment("PPC Mac OS X Linker");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagSettingNameVal(
+ "MWLinker_MacOSX_linksym", "1");
+ } else {
+ WriteXMLtagSettingNameVal(
+ "MWLinker_MacOSX_linksym", "0");
+ }
+ WriteXMLtagSettingNameVal(
+ "MWLinker_MacOSX_symfullpath", "1");
+ WriteXMLtagSettingNameVal(
+ "MWLinker_MacOSX_permitmultdefs", "0");
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteXMLtagSettingNameVal(
+ "MWLinker_MacOSX_strip_debug_symbols", "1");
+ }
+ } else {
+ WriteMWSettingsPanelComment("PPC Linker");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteXMLtagSettingNameVal(
+ "MWLinker_PPC_linksym", "1");
+ } else {
+ WriteXMLtagSettingNameVal(
+ "MWLinker_PPC_linksym", "0");
+ }
+ WriteXMLtagSettingNameVal(
+ "MWLinker_PPC_linkmode", "Normal");
+ }
+
+ WriteBlankLineToDestFile();
+ if (gbk_targfam_mswn == gbo_targfam) {
+ WriteMWSettingsPanelComment("x86 Project");
+ WriteXMLtagSettingNameProcVal(
+ "MWProject_X86_outfile", WriteAppNameStr);
+ } else if (gbk_targ_mach == cur_targ) {
+ WriteMWSettingsPanelComment("PPC Mac OS X Project");
+ WriteXMLtagSettingNameVal(
+ "MWProject_MacOSX_type", "ApplicationPackage");
+ WriteXMLtagSettingNameProcVal(
+ "MWProject_MacOSX_outfile", WriteAppNameStr);
+ WriteXMLtagSettingNameVal(
+ "MWProject_MacOSX_filecreator", kMacCreatorSig);
+ WriteXMLtagSettingNameVal(
+ "MWProject_MacOSX_filetype", "APPL");
+ WriteXMLtagSettingNameVal(
+ "MWProject_MacOSX_vmaddress", "0");
+ WriteXMLtagSettingNameVal(
+ "MWProject_MacOSX_flatrsrc", "1");
+ WriteXMLtagSettingNameVal(
+ "MWProject_MacOSX_flatrsrcfilename", "");
+ WriteBeginNamedSettingXMLtagLine(
+ "MWProject_MacOSX_flatrsrcoutputdir");
+ WriteXMLtagSettingNameVal("Path", ":");
+ WriteXMLtagSettingNameVal("PathFormat", "MacOS");
+ WriteXMLtagSettingNameVal("PathRoot", "Project");
+ WriteEndXMLtagLine("SETTING");
+ } else {
+ WriteMWSettingsPanelComment("PPC Project");
+ WriteXMLtagSettingNameVal(
+ "MWProject_PPC_outfile", vStrAppAbbrev);
+ WriteXMLtagSettingNameVal(
+ "MWProject_PPC_filecreator", kMacCreatorSig);
+ WriteXMLtagSettingNameVal(
+ "MWProject_PPC_size", "6000");
+ WriteXMLtagSettingNameVal(
+ "MWProject_PPC_minsize", "3000");
+ WriteXMLtagSettingNameVal(
+ "MWProject_PPC_flags", "22768");
+ }
+ WriteEndXMLtagLine("SETTINGLIST");
+
+ WriteBeginXMLtagLine("FILELIST");
+ WriteMWLibs(WriteMWLibAddFile);
+
+ if (gbk_targfam_mswn == gbo_targfam) {
+ WriteBeginXMLtagLine("FILE");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginValEndLine("PATH", "main.RC");
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteXMLtagBeginValEndLine("FILEKIND", "Text");
+ WriteXMLtagBeginValEndLine("FILEFLAGS", "");
+ WriteEndXMLtagLine("FILE");
+ } else if (gbk_targfam_mach == gbo_targfam) {
+ WriteBeginXMLtagLine("FILE");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginValEndLine("PATH", "main.plc");
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteXMLtagBeginValEndLine("FILEKIND", "Text");
+ WriteXMLtagBeginValEndLine("FILEFLAGS", "Debug");
+ WriteEndXMLtagLine("FILE");
+ DoAllDocTypesWithSetup(WriteDocTypeMWAddFile);
+ } else {
+ WriteBeginXMLtagLine("FILE");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginValEndLine("PATH", "main.r");
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteXMLtagBeginValEndLine("FILEKIND", "Text");
+ WriteXMLtagBeginValEndLine("FILEFLAGS", "");
+ WriteEndXMLtagLine("FILE");
+ }
+
+ DoAllSrcFilesWithSetup(DoSrcFileMW8AddFile);
+ WriteEndXMLtagLine("FILELIST");
+
+ WriteBeginXMLtagLine("LINKORDER");
+ WriteMWLibs(WriteMWLibMakeObjects);
+ if (gbk_targfam_mswn == gbo_targfam) {
+ WriteBeginXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginValEndLine("PATH", "main.RC");
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+ } else if (gbk_targfam_mach == gbo_targfam) {
+ WriteBeginXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginValEndLine("PATH", "main.plc");
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+ DoAllDocTypesWithSetup(WriteDocTypeMWMakeObjects);
+ } else {
+ WriteBeginXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginValEndLine("PATH", "main.r");
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+ }
+ DoAllSrcFilesSortWithSetup(DoSrcFileMW8sMakeObjects);
+ WriteEndXMLtagLine("LINKORDER");
+
+ if (gbk_targfam_mach == gbo_targfam) {
+ WriteBeginXMLtagLine("FRAMEWORKLIST");
+ WriteBeginXMLtagLine("FRAMEWORK");
+ WriteBeginXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginValEndLine(
+ "PATH", "Carbon.framework");
+ WriteXMLtagBeginValEndLine(
+ "PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine(
+ "DYNAMICLIBRARY", "Carbon");
+ WriteEndXMLtagLine("FRAMEWORK");
+
+#if UseOpenGLinOSX
+ WriteBeginXMLtagLine("FRAMEWORK");
+ WriteBeginXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginValEndLine("PATH",
+ "OpenGL.framework");
+ WriteXMLtagBeginValEndLine(
+ "PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine(
+ "DYNAMICLIBRARY", "OpenGL");
+ WriteEndXMLtagLine("FRAMEWORK");
+
+ WriteBeginXMLtagLine("FRAMEWORK");
+ WriteBeginXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginValEndLine(
+ "PATH", "AGL.framework");
+ WriteXMLtagBeginValEndLine(
+ "PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine("DYNAMICLIBRARY", "AGL");
+ WriteEndXMLtagLine("FRAMEWORK");
+#endif
+
+ WriteBeginXMLtagLine("FRAMEWORK");
+ WriteBeginXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ WriteXMLtagBeginValEndLine(
+ "PATH", "System.framework");
+ WriteXMLtagBeginValEndLine(
+ "PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+ WriteXMLtagBeginValEndLine(
+ "DYNAMICLIBRARY", "System");
+ WriteEndXMLtagLine("FRAMEWORK");
+ WriteEndXMLtagLine("FRAMEWORKLIST");
+ } /* (gbk_targfam_mach == gbo_targfam) */
+ WriteEndXMLtagLine("TARGET");
+ WriteEndXMLtagLine("TARGETLIST");
+
+ WriteBlankLineToDestFile();
+ WriteBeginXMLtagLine("TARGETORDER");
+ WriteBgnDestFileLn();
+ WriteXMLtagBegin("ORDEREDTARGET");
+ WriteXMLtagBegin("NAME");
+ WriteAppVariationStr();
+ WriteXMLtagEnd("NAME");
+ WriteXMLtagEnd("ORDEREDTARGET");
+ WriteEndDestFileLn();
+ WriteEndXMLtagLine("TARGETORDER");
+
+ WriteBlankLineToDestFile();
+ WriteBeginXMLtagLine("GROUPLIST");
+ WriteBeginXMLMWGroup("Libraries");
+ WriteMWLibs(WriteMWLibGroupList);
+ WriteEndXMLtagLine("GROUP");
+ WriteBeginXMLMWGroup("Resources");
+ WriteBeginXMLtagLine("FILEREF");
+ WriteAllMWTargetName();
+ WriteXMLtagBeginValEndLine("PATHTYPE", "Name");
+ if (gbk_targfam_mswn == gbo_targfam) {
+ WriteXMLtagBeginValEndLine("PATH", "main.RC");
+ } else {
+ if (HaveMacBundleApp) {
+ WriteXMLtagBeginValEndLine("PATH", "main.plc");
+ } else {
+ WriteXMLtagBeginValEndLine("PATH", "main.r");
+ }
+ }
+ WriteXMLtagBeginValEndLine("PATHFORMAT", "MacOS");
+ WriteEndXMLtagLine("FILEREF");
+ if (HaveMacBundleApp) {
+ DoAllDocTypesWithSetup(WriteDocTypeMWGroupList);
+ }
+ WriteEndXMLtagLine("GROUP");
+ DoAllSrcFilesWithSetup(DoSrcFileMW8GroupList);
+ WriteEndXMLtagLine("GROUPLIST");
+
+ WriteBlankLineToDestFile();
+ WriteEndXMLtagLine("PROJECT");
+}
+
+LOCALPROC WriteMetrowerksSpecificFiles(void)
+{
+ if (HaveMacBundleApp) {
+ WritePListData();
+ }
+
+ WriteADstFile1("my_project_d",
+ vStrAppAbbrev, ".mcp.xml", ".mcp.xml",
+ WriteMetrowerksProjectFile);
+}
--- /dev/null
+++ b/setup/WRPLCFLS.i
@@ -1,0 +1,289 @@
+/*
+ WRPLCFLS.i
+ Copyright (C) 2010 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite Pelles C Compiler specific FiLeS
+*/
+
+
+LOCALPROC DoSrcFilePLCAddFile(void)
+{
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("# ");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("# Build ");
+ WriteSrcFileObjName();
+ WriteCStrToDestFile(".");
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("# ");
+
+ WriteBgnDestFileLn();
+ WriteSrcFileObjPath();
+ WriteCStrToDestFile(": \\");
+ WriteEndDestFileLn();
+
+ ++DestFileIndent;
+
+ WriteBgnDestFileLn();
+ WriteSrcFileFilePath();
+ if ((DoSrcFile_gd()->Flgm & kCSrcFlgmNoHeader) == 0) {
+ WriteCStrToDestFile(" \\");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteSrcFileHeaderPath();
+ }
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("$(CC) $(CCFLAGS) \"$!\" -Fo\"$@\"");
+
+ --DestFileIndent;
+}
+
+
+LOCALPROC WritePLC_CCFLAGS(void)
+{
+ WriteCStrToDestFile(" -Tx86-coff");
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteCStrToDestFile(" -Zi");
+ }
+ WriteCStrToDestFile(" -Ob1 -fp:precise -W1 -Gd -Ze");
+}
+
+LOCALPROC WritePLC_LINKFLAGS(void)
+{
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteCStrToDestFile(" -debug -debugtype:cv");
+ }
+ WriteCStrToDestFile(" -subsystem:windows -machine:x86");
+}
+
+LOCALPROC WritePLCProjectFile(void)
+{
+ WriteDestFileLn("# ");
+ WriteDestFileLn(
+ "# PROJECT FILE generated by \"Pelles C for Windows,"
+ " version 6.00\".");
+ WriteDestFileLn("# WARNING! DO NOT EDIT THIS FILE.");
+ WriteDestFileLn("# ");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("POC_PROJECT_VERSION = 6.00#");
+ WriteDestFileLn("POC_PROJECT_TYPE = 0#");
+ WriteDestFileLn("POC_PROJECT_OUTPUTDIR = bld#");
+ WriteDestFileLn("POC_PROJECT_RESULTDIR = .#");
+ WriteDestFileLn("POC_PROJECT_ARGUMENTS = #");
+ WriteDestFileLn("POC_PROJECT_WORKPATH = #");
+ WriteDestFileLn("POC_PROJECT_EXECUTOR = #");
+ WriteDestFileLn("CC = pocc.exe#");
+ WriteDestFileLn("AS = poasm.exe#");
+ WriteDestFileLn("RC = porc.exe#");
+ WriteDestFileLn("LINK = polink.exe#");
+ WriteDestFileLn("SIGN = posign.exe#");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("CCFLAGS =");
+ WritePLC_CCFLAGS();
+ WriteCStrToDestFile(" #");
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("ASFLAGS = -AIA32 -Gz #");
+ WriteDestFileLn("RCFLAGS = #");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("LINKFLAGS = ");
+ WritePLC_LINKFLAGS();
+ WriteCStrToDestFile(
+ " shell32.lib winmm.lib ole32.lib uuid.lib kernel32.lib"
+ " user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib"
+ " delayimp.lib#");
+ WriteEndDestFileLn();
+
+ WriteDestFileLn(
+ "SIGNFLAGS = -timeurl:http://"
+ "timestamp.verisign.com/scripts/timstamp.dll"
+ " -location:CU -store:MY -errkill#");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("INCLUDE = ");
+ WriteCStrToDestFile("$(PellesCDir)\\Include\\Win");
+ WriteCStrToDestFile(";");
+ WriteCStrToDestFile("$(PellesCDir)\\Include");
+ WriteCStrToDestFile(";");
+ Write_src_d_ToDestFile();
+ WriteCStrToDestFile(";");
+ Write_cfg_d_ToDestFile();
+ WriteCStrToDestFile("#");
+ WriteEndDestFileLn();
+
+ WriteDestFileLn(
+ "LIB = $(PellesCDir)\\Lib\\Win;$(PellesCDir)\\Lib#");
+ WriteDestFileLn("WizCreator = Pelle Orinius#");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("# ");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("# Build ");
+ WriteAppNamePath();
+ WriteCStrToDestFile(".");
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("# ");
+
+ WriteBgnDestFileLn();
+ WriteAppNamePath();
+ WriteCStrToDestFile(": \\");
+ WriteEndDestFileLn();
+
+ ++DestFileIndent;
+ DoAllSrcFilesStandardMakeObjects();
+
+ WriteBgnDestFileLn();
+ WriteMainRsrcObjPath();
+ WriteEndDestFileLn();
+ --DestFileIndent;
+
+ WriteDestFileLn("\t$(LINK) $(LINKFLAGS) -out:\"$@\" $**");
+
+ DoAllSrcFilesWithSetup(DoSrcFilePLCAddFile);
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("# ");
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("# Build ");
+ WriteMainRsrcObjName();
+ WriteCStrToDestFile(".");
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("# ");
+
+ WriteBgnDestFileLn();
+ WriteMainRsrcObjPath();
+ WriteCStrToDestFile(": \\");
+ WriteEndDestFileLn();
+
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteMainRsrcSrcPath();
+ WriteEndDestFileLn();
+
+ WriteDestFileLn("$(RC) $(RCFLAGS) \"$!\" -Fo\"$@\"");
+ --DestFileIndent;
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(".SILENT:");
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(".EXCLUDEDFILES:");
+}
+
+LOCALPROC WritePLCSpecificFiles(void)
+{
+ WriteADstFile1("my_project_d",
+ vStrAppAbbrev, ".ppj", "Project file",
+ WritePLCProjectFile);
+}
+
+LOCALPROC WriteMainRsrcObjPLCbuild(void)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("porc.exe ");
+ WriteMainRsrcSrcPath();
+ WriteCStrToDestFile(" -Fo\"");
+ WriteMainRsrcObjPath();
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WritePLCclMakeFile(void)
+{
+ WriteDestFileLn("# make file generated by gryphel build system");
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptions =");
+ WritePLC_CCFLAGS();
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn(".phony: TheDefaultOutput clean");
+
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("TheDefaultOutput:");
+ WriteMakeDependFile(WriteAppNamePath);
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ WriteBlankLineToDestFile();
+ DoAllSrcFilesWithSetup(DoSrcFileMakeCompile);
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("OBJFILES = \\");
+ ++DestFileIndent;
+ DoAllSrcFilesStandardMakeObjects();
+ WriteBlankLineToDestFile();
+ --DestFileIndent;
+ WriteBlankLineToDestFile();
+
+ WriteBlankLineToDestFile();
+ WriteMakeRule(WriteMainRsrcObjPath,
+ WriteMainRsrcObjMSCdeps, WriteMainRsrcObjPLCbuild);
+
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteAppNamePath();
+ WriteCStrToDestFile(": $(OBJFILES) ");
+ WriteMainRsrcObjPath();
+ WriteEndDestFileLn();
+
+ ++DestFileIndent;
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("polink.exe -out:\"");
+ WriteAppNamePath();
+ WriteCStrToDestFile("\"");
+ WritePLC_LINKFLAGS();
+ WriteCStrToDestFile(" \\");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("$(OBJFILES) ");
+ WriteMainRsrcObjPath();
+ WriteCStrToDestFile(" \\");
+ WriteEndDestFileLn();
+
+ WriteDestFileLn(
+ "user32.lib winmm.lib ole32.lib uuid.lib comdlg32.lib"
+ " shell32.lib gdi32.lib");
+
+ --DestFileIndent;
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("clean:");
+ ++DestFileIndent;
+ DoAllSrcFilesStandardErase();
+ WriteRmFile(WriteMainRsrcObjPath);
+ WriteRmFile(WriteAppNamePath);
+ --DestFileIndent;
+}
+
+LOCALPROC WritePLCclSpecificFiles(void)
+{
+ WriteADstFile1("my_project_d",
+ "Makefile", "", "Make file",
+ WritePLCclMakeFile);
+}
--- /dev/null
+++ b/setup/WRSNCFLS.i
@@ -1,0 +1,115 @@
+/*
+ WRSNCFLS.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite SuN C specific FiLeS
+*/
+
+LOCALPROC WriteSncCOptions(void)
+{
+ WriteCStrToDestFile(" -c -v -fd -xstrconst");
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteCStrToDestFile(" -xO4 -xspace -Qn");
+ } else {
+ WriteCStrToDestFile(" -g");
+ }
+}
+
+LOCALPROC WriteSncMakeFile(void)
+{
+ WriteDestFileLn("# make file generated by gryphel build system");
+
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("mk_COptions =");
+ WriteSncCOptions();
+ WriteEndDestFileLn();
+ WriteBlankLineToDestFile();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("TheDefaultOutput : ");
+ Write_machobinpath_ToDestFile();
+ WriteEndDestFileLn();
+
+ WriteBlankLineToDestFile();
+ DoAllSrcFilesWithSetup(DoSrcFileMakeCompile);
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("ObjFiles = ");
+ WriteBackSlashToDestFile();
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ DoAllSrcFilesStandardMakeObjects();
+ WriteBlankLineToDestFile();
+ --DestFileIndent;
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ Write_machobinpath_ToDestFile();
+ WriteCStrToDestFile(" : $(ObjFiles)");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("cc");
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteCStrToDestFile(" -s -Qn -mr");
+ }
+ WriteCStrToDestFile(" \\");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("-o ");
+ WriteQuoteToDestFile();
+ Write_machobinpath_ToDestFile();
+ WriteQuoteToDestFile();
+
+ WriteCStrToDestFile(" -L/usr/X11R6/lib -lX11");
+#if 0
+ if (gbk_targfam_slrs == gbo_targfam) {
+ WriteCStrToDestFile(" -lposix4");
+ }
+ if (MySoundEnabled) {
+ WriteCStrToDestFile(" -lasound");
+ }
+#endif
+ WriteCStrToDestFile(" \\");
+ WriteEndDestFileLn();
+ WriteDestFileLn("$(ObjFiles)");
+ --DestFileIndent;
+ if (gbk_dbg_on != gbo_dbg) {
+ if (gbk_ide_xcd == cur_ide) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("strip -u -r \"");
+ Write_machobinpath_ToDestFile();
+ WriteCStrToDestFile("\"");
+ WriteEndDestFileLn();
+ }
+ }
+ --DestFileIndent;
+
+ WriteBlankLineToDestFile();
+ WriteDestFileLn("clean :");
+ ++DestFileIndent;
+ WriteDestFileLn("rm -f $(ObjFiles)");
+ WriteRmFile(WriteAppNamePath);
+ --DestFileIndent;
+}
+
+LOCALPROC WriteSncSpecificFiles(void)
+{
+ WriteADstFile1("my_project_d",
+ "Makefile", "", "Make file",
+ WriteSncMakeFile);
+}
--- /dev/null
+++ b/setup/WRTEXTFL.i
@@ -1,0 +1,834 @@
+/*
+ WRTEXTFL.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite TEXT FiLe
+*/
+
+
+
+/* --- routines for writing text files --- */
+
+
+#define WriteCharToOutput putchar
+
+LOCALPROC WriteCStrToOutput(char *s)
+{
+ printf("%s", s);
+}
+
+LOCALPROC WriteSignedLongToOutput(long int v)
+{
+ printf("%ld", v);
+}
+
+LOCALPROC WriteUnsignedToOutput(unsigned int v)
+{
+ printf("%u", v);
+}
+
+LOCALPROC WriteDec2CharToOutput(int v)
+{
+ printf("%02u", v);
+}
+
+LOCALPROC WriteHexByteToOutput(unsigned int v)
+{
+ printf("%02X", v);
+}
+
+LOCALPROC WriteHexWordToOutput(unsigned int v)
+{
+ printf("%04X", v);
+}
+
+LOCALPROC WriteHexLongToOutput(ui5r v)
+{
+ printf("%08lX", v);
+}
+
+LOCALPROC WriteEolToOutput(void)
+{
+ printf("\n");
+}
+
+LOCALPROC WriteLnCStrToOutput(char *s)
+{
+ WriteCStrToOutput(s);
+ WriteEolToOutput();
+}
+
+
+/* --- code specific to Scripting Language --- */
+
+GLOBALPROC WriteScriptLangExtension(void)
+{
+#if (gbo_script == gbk_script_mpw)
+ WriteCStrToOutput(".mpw");
+#endif
+#if (gbo_script == gbk_script_applescript)
+ WriteCStrToOutput(".scpt");
+#endif
+#if (gbo_script == gbk_script_bash)
+ WriteCStrToOutput(".sh");
+#endif
+#if (gbo_script == gbk_script_rc)
+ WriteCStrToOutput(".rc");
+#endif
+#if (gbo_script == gbk_script_vbscript)
+ WriteCStrToOutput(".vbs");
+#endif
+#if (gbo_script == gbk_script_xp)
+ WriteCStrToOutput(".bat");
+#endif
+}
+
+GLOBALPROC WriteScriptLangHeader(void)
+{
+#if (gbo_script == gbk_script_bash)
+ WriteLnCStrToOutput("#! /bin/bash");
+ WriteEolToOutput();
+#endif
+#if (gbo_script == gbk_script_xp)
+ WriteLnCStrToOutput("@echo off");
+ WriteEolToOutput();
+#endif
+#if (gbo_script == gbk_script_rc)
+ WriteLnCStrToOutput("#!/bin/rc");
+ WriteEolToOutput();
+#endif
+}
+
+#if (gbo_script == gbk_script_bash)
+#ifndef BashUsePrintf
+#define BashUsePrintf 1
+#endif
+#endif
+
+GLOBALPROC WriteSectionCommentDestFile(char * Description)
+{
+ WriteEolToOutput();
+ WriteEolToOutput();
+#if (gbo_script == gbk_script_mpw) || (gbo_script == gbk_script_bash) || (gbo_script == gbk_script_rc)
+ {
+ WriteCStrToOutput("# ----- ");
+ WriteCStrToOutput(Description);
+ WriteCStrToOutput(" -----");
+ }
+#endif
+#if (gbo_script == gbk_script_applescript)
+ {
+ WriteCStrToOutput("\t--- ");
+ WriteCStrToOutput(Description);
+ WriteCStrToOutput(" -----");
+ }
+#endif
+#if (gbo_script == gbk_script_vbscript)
+ {
+ WriteCStrToOutput("' ----- ");
+ WriteCStrToOutput(Description);
+ WriteCStrToOutput(" -----");
+ }
+#endif
+#if (gbo_script == gbk_script_xp)
+ {
+ WriteCStrToOutput("rem ----- ");
+ WriteCStrToOutput(Description);
+ WriteCStrToOutput(" -----");
+ }
+#endif
+
+ WriteEolToOutput();
+}
+
+LOCALPROC WriteOpenDestFile(char *DirVar, char *FileName, char *FileExt,
+ char * Description)
+{
+ WriteSectionCommentDestFile(Description);
+
+ WriteEolToOutput();
+
+#if (gbo_script == gbk_script_mpw)
+ {
+#if MPWOneEchoPerFile
+ WriteCStrToOutput("Echo -n > \"{");
+ WriteCStrToOutput(DirVar);
+ WriteCStrToOutput("}");
+ WriteCStrToOutput(FileName);
+ WriteCStrToOutput(FileExt);
+ WriteCStrToOutput("\" \266");
+ WriteEolToOutput();
+#else
+ WriteCStrToOutput("Set DestFile \"{");
+ WriteCStrToOutput(DirVar);
+ WriteCStrToOutput("}");
+ WriteCStrToOutput(FileName);
+ WriteCStrToOutput(FileExt);
+ WriteCStrToOutput("\"");
+ WriteEolToOutput();
+ WriteLnCStrToOutput("Echo -n > \"{DestFile}\"");
+ WriteEolToOutput();
+#endif
+ }
+#endif
+#if (gbo_script == gbk_script_applescript)
+ {
+ WriteCStrToOutput("\tset DestFile to open for access file (");
+ WriteCStrToOutput(DirVar);
+ WriteCStrToOutput(" & \"");
+ WriteCStrToOutput(FileName);
+ WriteCStrToOutput(FileExt);
+ WriteCStrToOutput("\") with write permission");
+ WriteEolToOutput();
+ WriteEolToOutput();
+ WriteLnCStrToOutput("\tset eof DestFile to 0");
+ }
+#endif
+#if (gbo_script == gbk_script_bash)
+ {
+ WriteCStrToOutput("DestFile=\"${");
+ WriteCStrToOutput(DirVar);
+ WriteCStrToOutput("}");
+ WriteCStrToOutput(FileName);
+ WriteCStrToOutput(FileExt);
+ WriteCStrToOutput("\"");
+ WriteEolToOutput();
+#if BashUsePrintf
+ WriteLnCStrToOutput("printf \"\" > \"${DestFile}\"");
+#else
+ /* WriteLnCStrToOutput("echo -n > \"${DestFile}\""); */
+ WriteLnCStrToOutput("true > \"${DestFile}\"");
+#endif
+ WriteEolToOutput();
+ }
+#endif
+#if (gbo_script == gbk_script_rc)
+ {
+ WriteCStrToOutput("DestFile=$");
+ WriteCStrToOutput(DirVar);
+ WriteCStrToOutput("^");
+ WriteCStrToOutput(FileName);
+ WriteCStrToOutput(FileExt);
+ WriteEolToOutput();
+ WriteLnCStrToOutput("echo -n > $DestFile");
+ WriteEolToOutput();
+ }
+#endif
+#if (gbo_script == gbk_script_xp)
+ {
+ WriteCStrToOutput("set DestFile=%");
+ WriteCStrToOutput(DirVar);
+ WriteCStrToOutput("%");
+ WriteCStrToOutput("\\");
+ WriteCStrToOutput(FileName);
+ WriteCStrToOutput(FileExt);
+ WriteEolToOutput();
+ WriteLnCStrToOutput("echo.>\"%DestFile%\"");
+ WriteLnCStrToOutput("del \"%DestFile%\"");
+ }
+#endif
+#if (gbo_script == gbk_script_vbscript)
+ {
+ WriteCStrToOutput("Set f = fso.CreateTextFile(");
+ WriteCStrToOutput(DirVar);
+ WriteCStrToOutput(" & \"\\");
+ WriteCStrToOutput(FileName);
+ WriteCStrToOutput(FileExt);
+ WriteCStrToOutput("\", True)");
+ WriteEolToOutput();
+ WriteEolToOutput();
+ }
+#endif
+}
+
+LOCALPROC WriteCloseDestFile(void)
+{
+#if (gbo_script == gbk_script_mpw)
+#if MPWOneEchoPerFile
+ WriteLnCStrToOutput("''");
+#endif
+#endif /* (gbo_script == gbk_script_mpw) */
+#if (gbo_script == gbk_script_applescript)
+ WriteEolToOutput();
+ WriteLnCStrToOutput("\tclose access DestFile");
+#endif
+#if (gbo_script == gbk_script_bash)
+#endif
+#if (gbo_script == gbk_script_vbscript)
+ WriteEolToOutput();
+ WriteLnCStrToOutput("f.Close");
+#endif
+#if (gbo_script == gbk_script_xp)
+#endif
+}
+
+TYPEDEFPROC (*MyProc)(void);
+
+LOCALPROC WriteADstFile1(char *DirVar,
+ char *FileName, char *FileExt, char * Description, MyProc p)
+{
+ WriteOpenDestFile(DirVar, FileName, FileExt, Description);
+ p();
+ WriteCloseDestFile();
+}
+
+LOCALPROC WriteBlankLineToDestFile(void)
+{
+#if (gbo_script == gbk_script_mpw)
+#if MPWOneEchoPerFile
+ WriteLnCStrToOutput("''\266n\266");
+#else
+ WriteLnCStrToOutput("Echo '' >> \"{DestFile}\"");
+#endif
+#endif /* (gbo_script == gbk_script_mpw) */
+#if (gbo_script == gbk_script_applescript)
+ WriteLnCStrToOutput("\twrite \"\" & return to DestFile");
+#endif
+#if (gbo_script == gbk_script_bash)
+#if BashUsePrintf
+ WriteLnCStrToOutput("printf \"\\n\" >> \"${DestFile}\"");
+#else
+ WriteLnCStrToOutput("echo '' >> \"${DestFile}\"");
+#endif
+#endif
+#if (gbo_script == gbk_script_rc)
+ WriteLnCStrToOutput("echo >> $DestFile");
+#endif
+#if (gbo_script == gbk_script_vbscript)
+ WriteLnCStrToOutput("f.WriteLine(\"\")");
+#endif
+#if (gbo_script == gbk_script_xp)
+ WriteLnCStrToOutput("echo.>>\"%DestFile%\"");
+#endif
+}
+
+LOCALVAR int DestFileIndent = 0;
+
+LOCALPROC WriteBgnDestFileLn(void)
+{
+ int i;
+
+#if (gbo_script == gbk_script_mpw)
+#if MPWOneEchoPerFile
+ WriteCStrToOutput("'");
+#else
+ WriteCStrToOutput("Echo '");
+#endif
+#endif /* (gbo_script == gbk_script_mpw) */
+#if (gbo_script == gbk_script_applescript)
+ WriteCStrToOutput("\twrite \"");
+#endif
+#if (gbo_script == gbk_script_rc)
+ WriteCStrToOutput("echo '");
+#endif
+#if (gbo_script == gbk_script_bash)
+#if BashUsePrintf
+ WriteCStrToOutput("printf \"%s\\n\" '");
+#else
+ WriteCStrToOutput("echo '");
+#endif
+#endif
+#if (gbo_script == gbk_script_vbscript)
+ WriteCStrToOutput("f.WriteLine(\"");
+#endif
+#if (gbo_script == gbk_script_xp)
+ WriteCStrToOutput("echo ");
+#endif
+
+ for (i = 0; i < DestFileIndent; ++i) {
+ WriteCStrToOutput("\t");
+ }
+}
+
+LOCALPROC WriteEndDestFileLn(void)
+{
+#if (gbo_script == gbk_script_mpw)
+#if MPWOneEchoPerFile
+ WriteCStrToOutput("'\266n\266");
+#else
+ WriteCStrToOutput("' >> \"{DestFile}\"");
+#endif
+#endif /* (gbo_script == gbk_script_mpw) */
+#if (gbo_script == gbk_script_applescript)
+ WriteCStrToOutput("\" & return to DestFile");
+#endif
+#if (gbo_script == gbk_script_rc)
+ WriteCStrToOutput("' >> $DestFile");
+#endif
+#if (gbo_script == gbk_script_bash)
+ WriteCStrToOutput("' >> \"${DestFile}\"");
+#endif
+#if (gbo_script == gbk_script_vbscript)
+ WriteCStrToOutput("\")");
+#endif
+#if (gbo_script == gbk_script_xp)
+ WriteCStrToOutput(">>\"%DestFile%\"");
+#endif
+
+ WriteEolToOutput();
+}
+
+LOCALPROC WriteCharToDestFile(char c)
+{
+ switch (c) {
+#if (gbo_script == gbk_script_mpw)
+ case '\'':
+ WriteCStrToOutput("'\266''");
+ break;
+#endif
+#if (gbo_script == gbk_script_bash)
+ case '\'':
+ WriteCStrToOutput("'\\''");
+ break;
+#endif
+#if (gbo_script == gbk_script_rc)
+ case '\'':
+ WriteCStrToOutput("''''");
+ break;
+#endif
+#if (gbo_script == gbk_script_applescript)
+ case '"':
+ WriteCStrToOutput("\\\"");
+ break;
+#endif
+#if (gbo_script == gbk_script_vbscript)
+ case '"':
+ WriteCStrToOutput("\"\"");
+ break;
+#endif
+#if (gbo_script == gbk_script_xp)
+ case '%':
+ WriteCStrToOutput("%%");
+ break;
+ case '^':
+ case '<':
+ case '>':
+ case '|':
+ case '"':
+
+ /*
+ digit preceeding redirection
+ modifies the redirection
+ */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ WriteCStrToOutput("^");
+ WriteCharToOutput(c);
+ break;
+#endif
+ default:
+ WriteCharToOutput(c);
+ break;
+ }
+}
+
+LOCALPROC WriteCStrToDestFile(char *s)
+{
+ char c;
+
+ while ((c = *s++) != 0) {
+ WriteCharToDestFile(c);
+ }
+}
+
+LOCALPROC WriteScriptVarToDestFile(char *name)
+{
+#if (gbo_script == gbk_script_mpw)
+ WriteCStrToOutput("'\"{");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput("}\"'");
+#endif
+#if (gbo_script == gbk_script_applescript)
+ WriteCStrToOutput("* not implemented yet *");
+#endif
+#if (gbo_script == gbk_script_rc)
+ WriteCStrToOutput("$");
+ WriteCStrToOutput(name);
+#endif
+#if (gbo_script == gbk_script_bash)
+ WriteCStrToOutput("'\"${");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput("}\"'");
+#endif
+#if (gbo_script == gbk_script_vbscript)
+ WriteCStrToOutput("\" & ");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput(" & \"");
+#endif
+#if (gbo_script == gbk_script_xp)
+ WriteCStrToOutput("%");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput("%");
+#endif
+}
+
+LOCALPROC WriteBgnCommentBlock(void)
+{
+#if (gbo_script == gbk_script_applescript)
+ WriteLnCStrToOutput("(*");
+#endif
+}
+
+LOCALPROC WriteEndCommentBlock(void)
+{
+#if (gbo_script == gbk_script_applescript)
+ WriteLnCStrToOutput("*)");
+#endif
+}
+
+LOCALPROC WriteBgnCommentBlockLn(void)
+{
+#if (gbo_script == gbk_script_mpw) || (gbo_script == gbk_script_bash) || (gbo_script == gbk_script_rc)
+ WriteCStrToOutput("# ");
+#endif
+#if (gbo_script == gbk_script_applescript)
+ WriteCStrToOutput("\t");
+#endif
+#if (gbo_script == gbk_script_vbscript)
+ WriteCStrToOutput("' ");
+#endif
+#if (gbo_script == gbk_script_xp)
+ WriteCStrToOutput("rem ");
+#endif
+}
+
+LOCALPROC WriteEndCommentBlockLn(void)
+{
+#if (gbo_script == gbk_script_mpw) \
+ || (gbo_script == gbk_script_applescript) \
+ || (gbo_script == gbk_script_bash) \
+ || (gbo_script == gbk_script_rc) \
+ || (gbo_script == gbk_script_vbscript) \
+ || (gbo_script == gbk_script_xp)
+ WriteEolToOutput();
+#endif
+}
+
+LOCALPROC WriteCommentBlockLn(char *s)
+{
+ WriteBgnCommentBlockLn();
+ WriteCStrToOutput(s);
+ WriteEndCommentBlockLn();
+}
+
+LOCALPROC FindSubDirectory(char *new_d, char *parent_d, char *name)
+{
+ WriteEolToOutput();
+
+#if (gbo_script == gbk_script_mpw)
+ WriteCStrToOutput("Set ");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput(" \"{");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput("}");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput(":\"");
+ WriteEolToOutput();
+
+
+ WriteCStrToOutput("IF not \"`exists -d -q \"{");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("}\"`\"");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("\tEcho \"{");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("} is not an existing directory\"");
+ WriteEolToOutput();
+
+ WriteLnCStrToOutput("\tExit 1");
+
+ WriteLnCStrToOutput("END");
+#endif
+#if (gbo_script == gbk_script_applescript)
+ WriteCStrToOutput("\tset ");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput(" to ");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput(" & \"");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput(":\"");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("\tif not (exists alias ");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput(") then");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("\t\tdisplay dialog \"The folder '");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput("' is missing from '\" & ");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput(" & \"'.\" buttons {\"OK\"} default button 1");
+ WriteEolToOutput();
+
+ WriteLnCStrToOutput("\t\treturn");
+ WriteLnCStrToOutput("\tend if");
+#endif
+#if (gbo_script == gbk_script_bash)
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("=\"${");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput("}");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput("/\"");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("if test ! -d \"${");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("}\" ; then");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("\techo \"The folder '");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput("' is missing from ${");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput("}\"");
+ WriteEolToOutput();
+
+ WriteLnCStrToOutput("\texit 1");
+ WriteLnCStrToOutput("fi");
+#endif
+#if (gbo_script == gbk_script_rc)
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("=$");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput("^");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput("/");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("if(test ! -d $");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput(") {");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("\techo The folder '");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput("' is missing from $");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput("");
+ WriteEolToOutput();
+
+ WriteLnCStrToOutput("\texit fail");
+ WriteLnCStrToOutput("}");
+#endif
+#if (gbo_script == gbk_script_vbscript)
+ WriteCStrToOutput("dim ");
+ WriteCStrToOutput(new_d);
+ WriteEolToOutput();
+
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput(" = ");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput(" & \"\\");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput("\"");
+ WriteEolToOutput();
+#endif
+#if (gbo_script == gbk_script_xp)
+ WriteCStrToOutput("set ");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("=%");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput("%");
+ WriteCStrToOutput("\\");
+ WriteCStrToOutput(name);
+ WriteEolToOutput();
+
+ WriteCStrToOutput("if not exist \"%");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("%\" echo \"%");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("%\" is missing");
+ WriteEolToOutput();
+#endif
+}
+
+LOCALPROC MakeSubDirectory(char *new_d, char *parent_d, char *name,
+ char *FileExt)
+{
+ WriteEolToOutput();
+
+#if (gbo_script == gbk_script_mpw)
+ WriteCStrToOutput("Set ");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput(" \"{");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput("}");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput(FileExt);
+ WriteCStrToOutput(":\"");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("IF not \"`exists -q \"{");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("}\"`\"");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("\tNewFolder \"{");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("}\"");
+ WriteEolToOutput();
+
+ WriteLnCStrToOutput("END");
+#endif
+#if (gbo_script == gbk_script_applescript)
+ WriteCStrToOutput("\tset ");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput(" to ");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput(" & \"");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput(FileExt);
+ WriteCStrToOutput(":\"");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("\tmake new folder at alias ");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput(" with properties {name:\"");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput(FileExt);
+ WriteCStrToOutput("\"}");
+ WriteEolToOutput();
+#endif
+#if (gbo_script == gbk_script_bash)
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("=\"${");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput("}");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput(FileExt);
+ WriteCStrToOutput("/\"");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("if test ! -d \"${");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("}\" ; then");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("\tmkdir \"${");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("}\"");
+ WriteEolToOutput();
+
+ WriteLnCStrToOutput("fi");
+#endif
+#if (gbo_script == gbk_script_rc)
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("=$");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput("^");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput(FileExt);
+ WriteCStrToOutput("/");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("if(! test -d $");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput(") {");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("\tmkdir $");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("");
+ WriteEolToOutput();
+
+ WriteLnCStrToOutput("}");
+#endif
+#if (gbo_script == gbk_script_vbscript)
+ WriteCStrToOutput("dim ");
+ WriteCStrToOutput(new_d);
+ WriteEolToOutput();
+
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput(" = ");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput(" & \"\\");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput(FileExt);
+ WriteCStrToOutput("\"");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("if (NOT fso.FolderExists(");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput(")) Then");
+ WriteEolToOutput();
+
+ WriteCStrToOutput("\tfso.CreateFolder(");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput(")");
+ WriteEolToOutput();
+
+ WriteLnCStrToOutput("End If");
+#endif
+#if (gbo_script == gbk_script_xp)
+ WriteCStrToOutput("set ");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("=%");
+ WriteCStrToOutput(parent_d);
+ WriteCStrToOutput("%");
+ WriteCStrToOutput("\\");
+ WriteCStrToOutput(name);
+ WriteCStrToOutput(FileExt);
+ WriteEolToOutput();
+
+ WriteCStrToOutput("if not exist \"%");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("%\" mkdir \"%");
+ WriteCStrToOutput(new_d);
+ WriteCStrToOutput("%\"");
+ WriteEolToOutput();
+#endif
+}
+
+
+
+/* ------- utilities for writing to text files -------- */
+
+LOCALPROC WriteDestFileLn(char *s)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(s);
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteSpaceToDestFile(void)
+{
+ WriteCharToDestFile(' ');
+}
+
+LOCALPROC WriteQuoteToDestFile(void)
+{
+ WriteCharToDestFile('\"');
+}
+
+LOCALPROC WriteSingleQuoteToDestFile(void)
+{
+ WriteCharToDestFile('\'');
+}
+
+LOCALPROC WriteBackSlashToDestFile(void)
+{
+ WriteCharToDestFile('\\');
+}
--- /dev/null
+++ b/setup/WRXCDFLS.i
@@ -1,0 +1,2082 @@
+/*
+ WRXCDFLS.i
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ WRite XCoDe specific FiLeS
+
+ (also support older Apple Project Builder)
+*/
+
+LOCALPROC WriteNextLineSameDent(void)
+{
+ WriteEndDestFileLn();
+ WriteBgnDestFileLn();
+}
+
+static void WriteAPBXCDObjectId(unsigned int theClass, unsigned int v)
+{
+ WriteHexWordToOutput(theClass);
+ WriteHexWordToOutput(v);
+ WriteCStrToDestFile("0000000000000000");
+}
+
+enum {
+ APBoclsSrcBld,
+ APBoclsIcnsBld,
+ APBoclsFramBld,
+ APBospcLibStdcBld,
+ APBospcMnRsrcBld, /* only if HaveMacRrscs */
+ APBospcLangDummyBld,
+
+ APBospcBuildStyle,
+
+ APBoclsSrcRf,
+ APBoclsHdr, /* only if gbk_ide_xcd == cur_ide */
+ APBoclsInc, /* only if gbk_ide_xcd == cur_ide */
+ APBoclsIcnsRf,
+ APBoclsFramRf,
+ APBospcLibStdcRf,
+ APBospcProductRef,
+ APBospcPlistRf,
+ APBospcMainRsrcRf, /* only if HaveMacRrscs */
+ APBospcLangRf,
+
+ APBospcPhaseLibs,
+ APBospcSources,
+ APBospcResources, /* only if HaveMacBundleApp */
+ APBospcLibraries,
+ APBospcProducts,
+ APBospcMainGroup,
+ APBospcSrcHeaders, /* only if gbk_ide_xcd == cur_ide */
+ APBospcIncludes, /* only if gbk_ide_xcd == cur_ide */
+
+ APBospcTarget,
+ APBospcRoot,
+ APBospcBunRsrcs, /* only if HaveMacBundleApp */
+ APBospcPhaseRsrc, /* only if HaveMacRrscs */
+ APBospcHeaders,
+ APBospcPhaseSrcs,
+
+ APBospcLangDummyRf,
+
+ APBospcNatCnfg, /* only if gbk_ide_xcd == cur_ide */
+ APBospcPrjCnfg, /* only if gbk_ide_xcd == cur_ide */
+ APBospcLstNatCnfg, /* only if gbk_ide_xcd == cur_ide */
+ APBospcLstPrjCnfg, /* only if gbk_ide_xcd == cur_ide */
+
+ kNumAPBocls
+};
+
+#define HaveAPBXCD_LangDummy (ide_vers >= 1000)
+#define HaveAPBXCD_PlistFile (ide_vers >= 1000)
+#define HaveAPBXCD_NameCmmnt (ide_vers >= 2100)
+#define HaveAPBXCD_Headers (ide_vers >= 1000)
+#define HaveAPBXCD_StdcLib (ide_vers < 1500)
+#define HaveAPBXCD_IsaFirst (ide_vers >= 2100)
+
+static void WriteAPBXCDBgnObjList(char *s)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(s);
+ WriteCStrToDestFile(" = (");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+}
+
+static void WriteAPBXCDEndObjList(void)
+{
+ --DestFileIndent;
+ WriteDestFileLn(");");
+}
+
+LOCALPROC WriteAPBXCDObjectIdAndComment(unsigned int theClass,
+ unsigned int v, MyProc comment)
+{
+ WriteAPBXCDObjectId(theClass, v);
+ if (HaveAPBXCD_NameCmmnt) {
+ WriteCStrToDestFile(" /* ");
+ comment();
+ WriteCStrToDestFile(" */");
+ }
+}
+
+static void WriteAPBXCDBeginObject(unsigned int theClass,
+ unsigned int v, MyProc comment)
+{
+ WriteBgnDestFileLn();
+ WriteAPBXCDObjectIdAndComment(theClass, v, comment);
+ WriteCStrToDestFile(" = {");
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+}
+
+static void WriteAPBXCDEndObject(void)
+{
+ --DestFileIndent;
+ WriteDestFileLn("};");
+}
+
+static void WriteAPBQuotedField(char *s, char *v)
+{
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile(s);
+ WriteCStrToDestFile(" = ");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(v);
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(";");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteAPBXCDobjlistelmp(unsigned int theClass, unsigned int v,
+ MyProc comment)
+{
+ WriteBgnDestFileLn();
+ WriteAPBXCDObjectIdAndComment(theClass, v, comment);
+ WriteCStrToDestFile(",");
+ WriteEndDestFileLn();
+}
+
+LOCALVAR int APBXCDForceSameLine = 0;
+
+LOCALPROC WriteAPBXCDSepA(void)
+{
+ if (0 == APBXCDForceSameLine) {
+ WriteNextLineSameDent();
+ } else {
+ WriteSpaceToDestFile();
+ }
+}
+
+LOCALPROC WriteAPBXCDDObjectAPropBgn(void)
+{
+ if (0 == APBXCDForceSameLine) {
+ WriteBgnDestFileLn();
+ }
+}
+
+LOCALPROC WriteAPBXCDDObjectAPropEnd(void)
+{
+ WriteCStrToDestFile(";");
+ if (0 == APBXCDForceSameLine) {
+ WriteEndDestFileLn();
+ } else {
+ WriteSpaceToDestFile();
+ }
+}
+
+LOCALPROC WriteAPBXCDObjectAp(unsigned int theClass, unsigned int v,
+ MyProc comment, MyProc body)
+{
+ WriteBgnDestFileLn();
+ WriteAPBXCDObjectIdAndComment(theClass, v, comment);
+ WriteCStrToDestFile(" = {");
+ if (ide_vers < 2100) {
+ WriteEndDestFileLn();
+ ++DestFileIndent;
+ body();
+ --DestFileIndent;
+ WriteBgnDestFileLn();
+ } else {
+ ++APBXCDForceSameLine;
+ body();
+ --APBXCDForceSameLine;
+ }
+ WriteCStrToDestFile("};");
+ WriteEndDestFileLn();
+}
+
+LOCALPROC WriteAPBXCDDObjAProp_SS(char *ns, char *vs)
+{
+ WriteAPBXCDDObjectAPropBgn();
+ WriteCStrToDestFile(ns);
+ WriteCStrToDestFile(" = ");
+ WriteCStrToDestFile(vs);
+ WriteAPBXCDDObjectAPropEnd();
+}
+
+LOCALPROC WriteAPBXCDDObjAProp_SP(char *ns, MyProc p)
+{
+ WriteAPBXCDDObjectAPropBgn();
+ WriteCStrToDestFile(ns);
+ WriteCStrToDestFile(" = ");
+ p();
+ WriteAPBXCDDObjectAPropEnd();
+}
+
+LOCALPROC WriteAPBXCDDObjAProp_SO(char *ns,
+ unsigned int theClass, unsigned int v,
+ MyProc comment)
+{
+ WriteAPBXCDDObjectAPropBgn();
+ WriteCStrToDestFile(ns);
+ WriteCStrToDestFile(" = ");
+ WriteAPBXCDObjectIdAndComment(theClass,
+ v, comment);
+ WriteAPBXCDDObjectAPropEnd();
+}
+
+LOCALPROC WriteAPBXCDDObjAPropIsa(char *s)
+{
+ WriteAPBXCDDObjAProp_SS("isa", s);
+}
+
+LOCALPROC WriteAPBXCDDObjAPropIsaBuildFile(void)
+{
+ WriteAPBXCDDObjAPropIsa("PBXBuildFile");
+}
+
+LOCALPROC WriteAPBXCDDObjAPropIsaFileReference(void)
+{
+ WriteAPBXCDDObjAPropIsa("PBXFileReference");
+}
+
+LOCALPROC WriteAPBXCDDObjAPropIsaGroup(void)
+{
+ WriteAPBXCDDObjAPropIsa("PBXGroup");
+}
+
+LOCALPROC WriteAPBXCDDObjAPropFileEncoding30(void)
+{
+ WriteAPBXCDDObjAProp_SS("fileEncoding", "30");
+}
+
+LOCALPROC WriteAPBXCDDObjAPropFileEncoding4(void)
+{
+ WriteAPBXCDDObjAProp_SS("fileEncoding", "4");
+}
+
+LOCALPROC WriteAPBXCDDObjAPropRefType(char *ns)
+{
+ if (ide_vers < 2100) {
+ WriteAPBXCDDObjAProp_SS("refType", ns);
+ }
+}
+
+LOCALPROC WriteAPBXCDDObjAPropRefType0(void)
+{
+ WriteAPBXCDDObjAPropRefType("0");
+}
+
+LOCALPROC WriteAPBXCDDObjAPropRefType2(void)
+{
+ WriteAPBXCDDObjAPropRefType("2");
+}
+
+LOCALPROC WriteAPBXCDDObjAPropRefType3(void)
+{
+ WriteAPBXCDDObjAPropRefType("3");
+}
+
+LOCALPROC WriteAPBXCDDObjAPropRefType4(void)
+{
+ WriteAPBXCDDObjAPropRefType("4");
+}
+
+LOCALPROC WriteAPBXCDDObjAPropName(MyProc p)
+{
+ WriteAPBXCDDObjAProp_SP("name", p);
+}
+
+LOCALPROC WriteAPBXCDDObjAPropPath(MyProc p)
+{
+ WriteAPBXCDDObjAProp_SP("path", p);
+}
+
+LOCALPROC WriteAPBXCDDObjAPropSourceTree(char *s)
+{
+ if (ide_vers >= 1000) {
+ WriteAPBXCDDObjAProp_SS("sourceTree", s);
+ }
+}
+
+LOCALPROC WriteAPBXCDDObjAPropSourceTreeRoot(void)
+{
+ WriteAPBXCDDObjAPropSourceTree("SOURCE_ROOT");
+}
+
+LOCALPROC WriteAPBXCDDObjAPropSourceTreeSDKRoot(void)
+{
+ WriteAPBXCDDObjAPropSourceTree("SDKROOT");
+}
+
+LOCALPROC WriteAPBXCDDObjAPropSourceTreeAbsolute(void)
+{
+ WriteAPBXCDDObjAPropSourceTree("\"<absolute>\"");
+}
+
+LOCALPROC WriteAPBXCDDObjAPropSourceTreeGroup(void)
+{
+ WriteAPBXCDDObjAPropSourceTree("\"<group>\"");
+}
+
+LOCALPROC WriteAPBXCDDObjAPropExpectedFileType(MyProc p)
+{
+ if ((ide_vers < 1500) && (ide_vers >= 1000)) {
+ WriteAPBXCDDObjAProp_SP("expectedFileType", p);
+ }
+}
+
+LOCALPROC WriteAPBXCDDObjAPropLastKnownFType(MyProc p)
+{
+ if (ide_vers >= 1500) {
+ WriteAPBXCDDObjAProp_SP("lastKnownFileType", p);
+ }
+}
+
+LOCALPROC WriteAPBXCDDObjAPropFileRef(
+ unsigned int theClass, unsigned int v,
+ MyProc comment)
+{
+ WriteAPBXCDDObjAProp_SO("fileRef",
+ theClass, v, comment);
+}
+
+LOCALPROC WriteAPBXCDDObjAPropIncludeII0(void)
+{
+ if (ide_vers >= 1000) {
+ WriteAPBXCDDObjAProp_SS("includeInIndex", "0");
+ }
+}
+
+LOCALPROC WriteAPBXCDDObjAPropSettingsNull(void)
+{
+ if (ide_vers < 2100) {
+ WriteAPBXCDDObjectAPropBgn();
+ WriteCStrToDestFile("settings = {");
+ WriteAPBXCDSepA();
+ WriteCStrToDestFile("}");
+ WriteAPBXCDDObjectAPropEnd();
+ }
+}
+
+LOCALPROC WriteSrcFileAPBXCDNameInSources(void)
+{
+ WriteSrcFileFileName();
+ WriteCStrToDestFile(" in Sources");
+}
+
+LOCALPROC DoSrcFileAPBXCDaddFileBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaBuildFile();
+ }
+
+ WriteAPBXCDDObjAPropFileRef(APBoclsSrcRf,
+ FileCounter, WriteSrcFileFileName);
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaBuildFile();
+ }
+ WriteAPBXCDDObjAPropSettingsNull();
+}
+
+LOCALPROC DoSrcFileAPBXCDaddFile(void)
+{
+ WriteAPBXCDObjectAp(APBoclsSrcBld, FileCounter,
+ WriteSrcFileAPBXCDNameInSources, DoSrcFileAPBXCDaddFileBody);
+}
+
+LOCALPROC WriteSrcFileAPBXCDtype(void)
+{
+ char *s;
+ blnr UseObjc = ((DoSrcFile_gd()->Flgm & kCSrcFlgmOjbc) != 0);
+
+ if (UseObjc) {
+ s = "sourcecode.c.objc";
+ } else {
+ s = "sourcecode.c.c";
+ }
+ WriteCStrToDestFile(s);
+}
+
+LOCALPROC DoSrcFileAPBXCDaddFileRefBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+
+ WriteAPBXCDDObjAPropExpectedFileType(WriteSrcFileAPBXCDtype);
+ WriteAPBXCDDObjAPropFileEncoding30();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+ WriteAPBXCDDObjAPropLastKnownFType(WriteSrcFileAPBXCDtype);
+ WriteAPBXCDDObjAPropName(WriteSrcFileFileName);
+ WriteAPBXCDDObjAPropPath(WriteSrcFileFilePath);
+ WriteAPBXCDDObjAPropRefType2();
+ WriteAPBXCDDObjAPropSourceTreeRoot();
+}
+
+LOCALPROC DoSrcFileAPBXCDaddFileRef(void)
+{
+ WriteAPBXCDObjectAp(APBoclsSrcRf, FileCounter,
+ WriteSrcFileFileName,
+ DoSrcFileAPBXCDaddFileRefBody);
+}
+
+LOCALPROC DoSrcFileAPBXCDaddToGroup(void)
+{
+ WriteAPBXCDobjlistelmp(APBoclsSrcRf, FileCounter,
+ WriteSrcFileFileName);
+}
+
+LOCALPROC DoSrcFileAPBXCDaddToSources(void)
+{
+ WriteAPBXCDobjlistelmp(APBoclsSrcBld, FileCounter,
+ WriteSrcFileAPBXCDNameInSources);
+}
+
+LOCALPROC WriteHeaderFileAPBXCDtype(void)
+{
+ WriteCStrToDestFile("sourcecode.c.h");
+}
+
+LOCALPROC DoHeaderFileXCDaddFileRefBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+
+ WriteAPBXCDDObjAPropExpectedFileType(WriteHeaderFileAPBXCDtype);
+ WriteAPBXCDDObjAPropFileEncoding30();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+ WriteAPBXCDDObjAPropLastKnownFType(WriteHeaderFileAPBXCDtype);
+ WriteAPBXCDDObjAPropName(WriteSrcFileHeaderName);
+ WriteAPBXCDDObjAPropPath(WriteSrcFileHeaderPath);
+ WriteAPBXCDDObjAPropRefType2();
+ WriteAPBXCDDObjAPropSourceTreeRoot();
+}
+
+LOCALPROC DoHeaderFileXCDaddFileRef(void)
+{
+ if (0 == (DoSrcFile_gd()->Flgm & kCSrcFlgmNoHeader)) {
+ WriteAPBXCDObjectAp(APBoclsHdr, FileCounter,
+ WriteSrcFileHeaderName,
+ DoHeaderFileXCDaddFileRefBody);
+ }
+}
+
+LOCALPROC DoHeaderFileXCDaddToGroup(void)
+{
+ if (0 == (DoSrcFile_gd()->Flgm & kCSrcFlgmNoHeader)) {
+ WriteAPBXCDobjlistelmp(APBoclsHdr, FileCounter,
+ WriteSrcFileHeaderName);
+ }
+}
+
+LOCALPROC WriteDocTypeAPBXCDIconFileInResources(void)
+{
+ WriteDocTypeIconFileName();
+ WriteCStrToDestFile(" in Resources");
+}
+
+LOCALPROC DoDocTypeAPBXCDaddFileBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaBuildFile();
+ }
+
+ WriteAPBXCDDObjAPropFileRef(APBoclsIcnsRf,
+ DocTypeCounter, WriteDocTypeIconFileName);
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaBuildFile();
+ }
+ WriteAPBXCDDObjAPropSettingsNull();
+}
+
+LOCALPROC DoDocTypeAPBXCDaddFile(void)
+{
+ WriteAPBXCDObjectAp(APBoclsIcnsBld, DocTypeCounter,
+ WriteDocTypeAPBXCDIconFileInResources,
+ DoDocTypeAPBXCDaddFileBody);
+}
+
+LOCALPROC WriteDocTypeAPBXCDtype(void)
+{
+ WriteCStrToDestFile("image.icns");
+}
+
+LOCALPROC DoDocTypeAPBXCDaddFileRefBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+
+ WriteAPBXCDDObjAPropExpectedFileType(WriteDocTypeAPBXCDtype);
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+ WriteAPBXCDDObjAPropLastKnownFType(WriteDocTypeAPBXCDtype);
+ WriteAPBXCDDObjAPropName(WriteDocTypeIconFileName);
+ WriteAPBXCDDObjAPropPath(WriteDocTypeIconFilePath);
+ WriteAPBXCDDObjAPropRefType2();
+ WriteAPBXCDDObjAPropSourceTreeRoot();
+}
+
+LOCALPROC DoDocTypeAPBXCDaddFileRef(void)
+{
+ WriteAPBXCDObjectAp(APBoclsIcnsRf, DocTypeCounter,
+ WriteDocTypeIconFileName, DoDocTypeAPBXCDaddFileRefBody);
+}
+
+LOCALPROC DoDocTypeAPBXCDaddToGroup(void)
+{
+ WriteAPBXCDobjlistelmp(APBoclsIcnsRf, DocTypeCounter,
+ WriteDocTypeIconFileName);
+}
+
+LOCALPROC DoDocTypeAPBXCDaddToSources(void)
+{
+ WriteAPBXCDobjlistelmp(APBoclsIcnsBld, DocTypeCounter,
+ WriteDocTypeAPBXCDIconFileInResources);
+}
+
+LOCALPROC WriteFrameWorkAPBXCDFileName(void)
+{
+ WriteCStrToDestFile(DoFrameWork_gd()->s);
+ WriteCStrToDestFile(".framework");
+}
+
+LOCALPROC WriteFrameWorkAPBXCDFilePath(void)
+{
+ if (ide_vers < 4000) {
+ WriteCStrToDestFile("/");
+ }
+ WriteCStrToDestFile("System/Library/Frameworks/");
+ WriteFrameWorkAPBXCDFileName();
+}
+
+LOCALPROC WriteFrameWorkAPBXCDileInFrameworks(void)
+{
+ WriteFrameWorkAPBXCDFileName();
+ WriteCStrToDestFile(" in Frameworks");
+}
+
+LOCALPROC DoFrameWorkAPBXCDaddFileBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaBuildFile();
+ }
+
+ WriteAPBXCDDObjAPropFileRef(APBoclsFramRf,
+ FileCounter, WriteFrameWorkAPBXCDFileName);
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaBuildFile();
+ }
+ WriteAPBXCDDObjAPropSettingsNull();
+}
+
+LOCALPROC DoFrameWorkAPBXCDaddFile(void)
+{
+ WriteAPBXCDObjectAp(APBoclsFramBld, FileCounter,
+ WriteFrameWorkAPBXCDileInFrameworks,
+ DoFrameWorkAPBXCDaddFileBody);
+}
+
+LOCALPROC WriteAPBXCDDObjAPropIsaFrameworkRef(void)
+{
+ if (ide_vers < 1000) {
+ WriteAPBXCDDObjAPropIsa("PBXFrameworkReference");
+ } else {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+}
+
+LOCALPROC WriteFrameWorkAPBXCDtype(void)
+{
+ WriteCStrToDestFile("wrapper.framework");
+}
+
+LOCALPROC DoFrameWorkAPBXCDaddFileRefBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFrameworkRef();
+ }
+
+ WriteAPBXCDDObjAPropExpectedFileType(WriteFrameWorkAPBXCDtype);
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFrameworkRef();
+ }
+ WriteAPBXCDDObjAPropLastKnownFType(WriteFrameWorkAPBXCDtype);
+ WriteAPBXCDDObjAPropName(WriteFrameWorkAPBXCDFileName);
+ WriteAPBXCDDObjAPropPath(WriteFrameWorkAPBXCDFilePath);
+ WriteAPBXCDDObjAPropRefType0();
+ if (ide_vers >= 4000) {
+ WriteAPBXCDDObjAPropSourceTreeSDKRoot();
+ } else {
+ WriteAPBXCDDObjAPropSourceTreeAbsolute();
+ }
+}
+
+LOCALPROC DoFrameWorkAPBXCDaddFileRef(void)
+{
+ WriteAPBXCDObjectAp(APBoclsFramRf, FileCounter,
+ WriteFrameWorkAPBXCDFileName,
+ DoFrameWorkAPBXCDaddFileRefBody);
+}
+
+LOCALPROC DoFrameworkAPBXCDaddToBuild(void)
+{
+ WriteAPBXCDobjlistelmp(APBoclsFramBld, FileCounter,
+ WriteFrameWorkAPBXCDileInFrameworks);
+}
+
+LOCALPROC DoFrameworkAPBXCDaddToLibraries(void)
+{
+ WriteAPBXCDobjlistelmp(APBoclsFramRf, FileCounter,
+ WriteFrameWorkAPBXCDFileName);
+}
+
+LOCALPROC DoExtraHeaderFileXCDaddFileRefBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+
+ WriteAPBXCDDObjAPropExpectedFileType(WriteHeaderFileAPBXCDtype);
+ WriteAPBXCDDObjAPropFileEncoding30();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+ WriteAPBXCDDObjAPropLastKnownFType(WriteHeaderFileAPBXCDtype);
+ WriteAPBXCDDObjAPropName(WriteExtraHeaderFileName);
+ WriteAPBXCDDObjAPropPath(WriteExtraHeaderFilePath);
+ WriteAPBXCDDObjAPropRefType2();
+ WriteAPBXCDDObjAPropSourceTreeRoot();
+}
+
+LOCALPROC DoExtraHeaderFileXCDaddFileRef(void)
+{
+ WriteAPBXCDObjectAp(APBoclsInc, FileCounter,
+ WriteExtraHeaderFileName,
+ DoExtraHeaderFileXCDaddFileRefBody);
+}
+
+LOCALPROC DoExtraHeaderFileXCDaddToGroup(void)
+{
+ WriteAPBXCDobjlistelmp(APBoclsInc, FileCounter,
+ WriteExtraHeaderFileName);
+}
+
+LOCALPROC WriteMainAPBXCDRsrcNameinRez(void)
+{
+ WriteMainRsrcName();
+ WriteCStrToDestFile(" in Rez");
+}
+
+LOCALPROC DoRsrcAPBXCDaddFileBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaBuildFile();
+ }
+
+ WriteAPBXCDDObjAPropFileRef(APBospcMainRsrcRf, 0,
+ WriteMainRsrcName);
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaBuildFile();
+ }
+ WriteAPBXCDDObjAPropSettingsNull();
+}
+
+LOCALPROC DoRsrcAPBXCDaddFile(void)
+{
+ WriteAPBXCDObjectAp(APBospcMnRsrcBld, 0,
+ WriteMainAPBXCDRsrcNameinRez,
+ DoRsrcAPBXCDaddFileBody);
+}
+
+LOCALPROC WriteRsrcAPBXCDtype(void)
+{
+ WriteCStrToDestFile("sourcecode.rez");
+}
+
+LOCALPROC DoRsrcAPBXCDaddFileRefBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+
+ WriteAPBXCDDObjAPropExpectedFileType(WriteRsrcAPBXCDtype);
+ WriteAPBXCDDObjAPropFileEncoding30();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+ WriteAPBXCDDObjAPropLastKnownFType(WriteRsrcAPBXCDtype);
+ WriteAPBXCDDObjAPropName(WriteMainRsrcName);
+ WriteAPBXCDDObjAPropPath(WriteMainRsrcSrcPath);
+ WriteAPBXCDDObjAPropRefType2();
+ WriteAPBXCDDObjAPropSourceTreeRoot();
+}
+
+LOCALPROC DoRsrcAPBXCDaddFileRef(void)
+{
+ WriteAPBXCDObjectAp(APBospcMainRsrcRf, 0,
+ WriteMainRsrcName,
+ DoRsrcAPBXCDaddFileRefBody);
+}
+
+LOCALPROC WriteLibStdcName(void)
+{
+ WriteCStrToDestFile("libstdc++.a");
+}
+
+LOCALPROC DoLibStdcAPBXCDaddFileBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaBuildFile();
+ }
+
+ WriteAPBXCDDObjAPropFileRef(APBospcLibStdcRf, 0,
+ WriteLibStdcName);
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaBuildFile();
+ }
+ WriteAPBXCDDObjAPropSettingsNull();
+}
+
+LOCALPROC DoLibStdcAPBXCDaddFile(void)
+{
+ WriteAPBXCDObjectAp(APBospcLibStdcBld, 0,
+ WriteLibStdcName,
+ DoLibStdcAPBXCDaddFileBody);
+}
+
+LOCALPROC WriteLibStdcFileName(void)
+{
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("libstdc++.a");
+ WriteQuoteToDestFile();
+}
+
+LOCALPROC WriteLibStdcFilePath(void)
+{
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("/usr/lib/libstdc++.a");
+ WriteQuoteToDestFile();
+}
+
+LOCALPROC WriteLibStdcAPBXCDtype(void)
+{
+ WriteCStrToDestFile("archive.ar");
+}
+
+LOCALPROC DoLibStdcAPBXCDaddFileRefBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+
+ WriteAPBXCDDObjAPropExpectedFileType(WriteLibStdcAPBXCDtype);
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+ WriteAPBXCDDObjAPropLastKnownFType(WriteLibStdcAPBXCDtype);
+ WriteAPBXCDDObjAPropName(WriteLibStdcFileName);
+ WriteAPBXCDDObjAPropPath(WriteLibStdcFilePath);
+ WriteAPBXCDDObjAPropRefType0();
+ WriteAPBXCDDObjAPropSourceTreeAbsolute();
+}
+
+LOCALPROC DoLibStdcAPBXCDaddFileRef(void)
+{
+ WriteAPBXCDObjectAp(APBospcLibStdcRf, 0,
+ WriteLibStdcName,
+ DoLibStdcAPBXCDaddFileRefBody);
+}
+
+LOCALPROC WriteDummyLangFileNameInResources(void)
+{
+ WriteDummyLangFileName();
+ WriteCStrToDestFile(" in Resources");
+}
+
+LOCALPROC DoDummyLangAPBXCDaddFileBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaBuildFile();
+ }
+
+ WriteAPBXCDDObjAPropFileRef(APBospcLangDummyRf, 0,
+ WriteDummyLangFileName);
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaBuildFile();
+ }
+ WriteAPBXCDDObjAPropSettingsNull();
+}
+
+LOCALPROC DoDummyLangAPBXCDaddFile(void)
+{
+ WriteAPBXCDObjectAp(APBospcLangDummyBld, 0,
+ WriteDummyLangFileNameInResources,
+ DoDummyLangAPBXCDaddFileBody);
+}
+
+LOCALPROC WriteDummyLangFilePath(void)
+{
+ WriteFileInDirToDestFile0(WriteLProjFolderPath,
+ WriteDummyLangFileName);
+}
+
+LOCALPROC WriteLangDummyAPBXCDtype(void)
+{
+ WriteCStrToDestFile("text");
+}
+
+LOCALPROC DoLangDummyAPBXCDaddFileRefBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+
+ WriteAPBXCDDObjAPropExpectedFileType(WriteLangDummyAPBXCDtype);
+ WriteAPBXCDDObjAPropFileEncoding30();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+ WriteAPBXCDDObjAPropLastKnownFType(WriteLangDummyAPBXCDtype);
+ WriteAPBXCDDObjAPropName(WriteLProjName);
+ WriteAPBXCDDObjAPropPath(WriteDummyLangFilePath);
+ WriteAPBXCDDObjAPropRefType4();
+ WriteAPBXCDDObjAPropSourceTreeRoot();
+}
+
+LOCALPROC DoLangDummyAPBXCDaddFileRef(void)
+{
+ WriteAPBXCDObjectAp(APBospcLangRf, 0,
+ WriteLProjName,
+ DoLangDummyAPBXCDaddFileRefBody);
+}
+
+LOCALPROC DoLangDummyAPBXCDaddToSources(void)
+{
+ WriteAPBXCDobjlistelmp(APBospcLangDummyBld, 0,
+ WriteDummyLangFileNameInResources);
+}
+
+LOCALPROC DoLangDummyAPBXCDaddVariant(void)
+{
+ WriteAPBXCDBeginObject(APBospcLangDummyRf,
+ 0, WriteDummyLangFileName);
+
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXVariantGroup");
+ }
+
+ WriteAPBXCDBgnObjList("children");
+ WriteAPBXCDobjlistelmp(APBospcLangRf, 0, WriteLProjName);
+ WriteAPBXCDEndObjList();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXVariantGroup");
+ }
+ WriteAPBXCDDObjAPropName(WriteDummyLangFileName);
+ WriteAPBXCDDObjAPropRefType4();
+ WriteAPBXCDDObjAPropSourceTreeGroup();
+ WriteAPBXCDEndObject();
+}
+
+static void DoBeginSectionAPBXCD(char *Name)
+{
+ if (ide_vers >= 2100) {
+ --DestFileIndent; --DestFileIndent;
+ WriteBlankLineToDestFile();
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("/* Begin ");
+ WriteCStrToDestFile(Name);
+ WriteCStrToDestFile(" section */");
+ WriteEndDestFileLn();
+ ++DestFileIndent; ++DestFileIndent;
+ }
+}
+
+static void DoEndSectionAPBXCD(char *Name)
+{
+ if (ide_vers >= 2100) {
+ --DestFileIndent; --DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("/* End ");
+ WriteCStrToDestFile(Name);
+ WriteCStrToDestFile(" section */");
+ WriteEndDestFileLn();
+ ++DestFileIndent; ++DestFileIndent;
+ }
+}
+
+LOCALPROC WriteXCDconfigname(void)
+{
+ char *s;
+
+ switch (gbo_dbg) {
+ case gbk_dbg_on:
+ if (ide_vers < 2100) {
+ s = "Development";
+ } else {
+ s = "Debug";
+ }
+ break;
+ case gbk_dbg_test:
+ s = "Test";
+ break;
+ case gbk_dbg_off:
+ if (ide_vers < 2100) {
+ s = "Deployment";
+ } else {
+ s = "Release";
+ }
+ break;
+ default:
+ s = "(unknown Debug Level)";
+ break;
+ }
+
+ WriteCStrToDestFile(s);
+}
+
+LOCALPROC WriteAPBXCDDObjAPropIsaApplicationRef(void)
+{
+ if (ide_vers < 1000) {
+ WriteAPBXCDDObjAPropIsa("PBXApplicationReference");
+ } else {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+}
+
+LOCALPROC WriteProductAPBXCDtype(void)
+{
+ if (HaveMacBundleApp) {
+ WriteCStrToDestFile("wrapper.application");
+ } else {
+ WriteCStrToDestFile("\"compiled.mach-o.executable\"");
+ }
+}
+
+LOCALPROC DoProductAPBXCDaddFileRefBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaApplicationRef();
+ }
+
+ WriteAPBXCDDObjAPropExpectedFileType(WriteProductAPBXCDtype);
+ WriteAPBXCDDObjAPropIncludeII0();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaApplicationRef();
+ }
+ WriteAPBXCDDObjAPropLastKnownFType(WriteProductAPBXCDtype);
+ WriteAPBXCDDObjAPropPath(WriteAppNameStr);
+ WriteAPBXCDDObjAPropRefType3();
+ WriteAPBXCDDObjAPropSourceTree("BUILT_PRODUCTS_DIR");
+}
+
+LOCALPROC DoProductAPBXCDaddFileRef(void)
+{
+ WriteAPBXCDObjectAp(APBospcProductRef, 0,
+ WriteAppNameStr,
+ DoProductAPBXCDaddFileRefBody);
+}
+
+LOCALPROC WritePlistAPBXCDtype(void)
+{
+ if (ide_vers >= 3100) {
+ WriteCStrToDestFile("text.plist.xml");
+ } else {
+ WriteCStrToDestFile("text.xml");
+ }
+}
+
+LOCALPROC DoPlistAPBXCDaddFileRefBody(void)
+{
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+
+ WriteAPBXCDDObjAPropExpectedFileType(WritePlistAPBXCDtype);
+ WriteAPBXCDDObjAPropFileEncoding4();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaFileReference();
+ }
+ WriteAPBXCDDObjAPropLastKnownFType(WritePlistAPBXCDtype);
+ WriteAPBXCDDObjAPropName(WriteInfoPlistFileName);
+ WriteAPBXCDDObjAPropPath(WriteInfoPlistFilePath);
+ WriteAPBXCDDObjAPropRefType2();
+ WriteAPBXCDDObjAPropSourceTreeRoot();
+}
+
+LOCALPROC DoPlistAPBXCDaddFileRef(void)
+{
+ WriteAPBXCDObjectAp(APBospcPlistRf, 0,
+ WriteInfoPlistFileName,
+ DoPlistAPBXCDaddFileRefBody);
+}
+
+LOCALPROC WriteAPBXCDBuildSettings(void)
+{
+ if (ide_vers >= 3100) {
+ WriteDestFileLn("ALWAYS_SEARCH_USER_PATHS = NO;");
+ }
+
+ if (ide_vers >= 2100) {
+ /* if (CrossCompile) */ {
+ if (gbk_cpufam_x86 == gbo_cpufam) {
+ WriteDestFileLn("ARCHS = i386;");
+ /*
+ may be preferred in later versions:
+ WriteDestFileLn(
+ "ARCHS = \"$(ARCHS_STANDARD_32_BIT)\";");
+ */
+ } else if (gbk_cpufam_x64 == gbo_cpufam) {
+ WriteDestFileLn("ARCHS = x86_64;");
+ } else {
+ WriteDestFileLn("ARCHS = ppc;");
+ }
+ }
+ }
+ if (ide_vers >= 2100) { /*^*/
+ /*
+ seems to work in Xcode 2.1, but doesn't
+ really appear in settings user interface
+ until Xcode 2.2
+ */
+ WriteDestFileLn(
+ "CONFIGURATION_BUILD_DIR = \"$(PROJECT_DIR)\";");
+ }
+ if (ide_vers >= 2200) { /*^*/
+ WriteDestFileLn("COPY_PHASE_STRIP = NO;");
+ } else {
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteDestFileLn("COPY_PHASE_STRIP = YES;");
+ } else {
+ WriteDestFileLn("COPY_PHASE_STRIP = NO;");
+ }
+ }
+ if (ide_vers >= 1500) {
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteDestFileLn("DEPLOYMENT_POSTPROCESSING = YES;");
+ }
+ }
+ if (ide_vers < 1500) {
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteDestFileLn("DEBUGGING_SYMBOLS = NO;");
+ }
+ }
+ if (ide_vers >= 1500) {
+ WriteDestFileLn("GCC_CW_ASM_SYNTAX = NO;");
+ }
+ if (ide_vers >= 1000) {
+ WriteDestFileLn("GCC_DYNAMIC_NO_PIC = YES;");
+ }
+ if (ide_vers < 1500) {
+ WriteAPBQuotedField("FRAMEWORK_SEARCH_PATHS", "");
+ }
+ if ((ide_vers >= 1000) && (ide_vers < 4000)) {
+ WriteDestFileLn("GCC_ENABLE_FIX_AND_CONTINUE = NO;");
+ }
+ if (ide_vers >= 1000) {
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteDestFileLn("GCC_GENERATE_DEBUGGING_SYMBOLS = NO;");
+ }
+ }
+ if ((ide_vers >= 1500) && (ide_vers < 4000)) {
+ WriteDestFileLn("GCC_MODEL_TUNING = \"\";");
+ }
+ if (ide_vers >= 1000) {
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteDestFileLn("GCC_OPTIMIZATION_LEVEL = 0;");
+ } else {
+ WriteDestFileLn("GCC_OPTIMIZATION_LEVEL = s;");
+ }
+ }
+ if (ide_vers >= 2100) {
+ WriteDestFileLn("GCC_PRECOMPILE_PREFIX_HEADER = NO;");
+ WriteDestFileLn("GCC_PREFIX_HEADER = \"\";");
+ WriteDestFileLn("GCC_SYMBOLS_PRIVATE_EXTERN = NO;");
+ }
+ if (ide_vers >= 3100) {
+ if (ide_vers < 3200) {
+ WriteDestFileLn("GCC_VERSION = 4.0;");
+ }
+ }
+ if (ide_vers >= 1000) {
+ WriteDestFileLn("GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;");
+ }
+
+ if (HaveMacBundleApp) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("INFOPLIST_FILE = ");
+ WriteInfoPlistFilePath();
+ WriteCStrToDestFile(";");
+ WriteEndDestFileLn();
+ }
+ if (ide_vers >= 1000) {
+ WriteDestFileLn("INSTALL_PATH = \"$(HOME)/Applications\";");
+ }
+ if (ide_vers < 1500) {
+ WriteAPBQuotedField("LIBRARY_SEARCH_PATHS", "");
+ }
+ if (ide_vers >= 2100) {
+ if (gbk_cpufam_ppc == gbo_cpufam) {
+ WriteDestFileLn("MACOSX_DEPLOYMENT_TARGET = 10.1;");
+ } else {
+ if (ide_vers >= 9000) {
+ WriteDestFileLn("MACOSX_DEPLOYMENT_TARGET = 10.6;");
+ } else {
+ WriteDestFileLn("MACOSX_DEPLOYMENT_TARGET = 10.4;");
+ }
+ }
+ }
+ if (ide_vers < 1500) {
+ if (gbk_dbg_on == gbo_dbg) {
+ WriteAPBQuotedField("OPTIMIZATION_CFLAGS", "-O0");
+ }
+ }
+ if (ide_vers < 1500) {
+ WriteAPBQuotedField("OTHER_LDFLAGS", "");
+ WriteAPBQuotedField("OTHER_REZFLAGS", "");
+ } else {
+ if (! HaveMacBundleApp) {
+ WriteAPBXCDBgnObjList("OTHER_LDFLAGS");
+ WriteDestFileLn("\"-L/usr/X11R6/lib\",");
+#if 0
+ WriteDestFileLn("\"-lXext\",");
+#endif
+ WriteDestFileLn("\"-lX11\",");
+ WriteAPBXCDEndObjList();
+ }
+ }
+ if ((ide_vers >= 1500) && (ide_vers < 4000)) {
+ WriteDestFileLn("PREBINDING = NO;");
+ }
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("PRODUCT_NAME = ");
+ WriteStrAppAbbrev();
+ WriteCStrToDestFile(";");
+ WriteEndDestFileLn();
+ if (ide_vers >= 2200) {
+ if (ide_vers >= 4300) {
+ WriteDestFileLn("SDKROOT = macosx;");
+ } else if (ide_vers >= 3200) {
+ WriteDestFileLn("SDKROOT = macosx10.6;");
+ } else if (ide_vers >= 3100) {
+ WriteDestFileLn("SDKROOT = macosx10.5;");
+ } else {
+ WriteDestFileLn(
+ "SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;");
+ }
+ }
+ if (ide_vers < 1500) {
+ WriteAPBQuotedField("SECTORDER_FLAGS", "");
+ }
+ if (ide_vers >= 2200) {
+ if (gbk_dbg_on != gbo_dbg) {
+ WriteDestFileLn("SEPARATE_STRIP = YES;");
+ WriteDestFileLn("STRIPFLAGS = \"-u -r\";");
+ WriteDestFileLn("STRIP_INSTALLED_PRODUCT = YES;");
+ }
+ }
+ if ((ide_vers >= 1500) && (ide_vers < 2100)) {
+ WriteDestFileLn("SYMROOT = \"$(PROJECT_DIR)\";");
+ }
+ WriteDestFileLn("USER_HEADER_SEARCH_PATHS = \"$(SRCROOT)/"
+ cfg_d_name
+ "\";");
+ if (ide_vers >= 2100) {
+ WriteAPBXCDBgnObjList("WARNING_CFLAGS");
+ WriteDestFileLn("\"-Wall\",");
+ WriteDestFileLn("\"-Wundef\",");
+ WriteDestFileLn("\"-Wstrict-prototypes\",");
+ WriteDestFileLn("\"-Wno-uninitialized\",");
+ WriteAPBXCDEndObjList();
+ } else {
+ WriteAPBQuotedField("WARNING_CFLAGS",
+ "-Wall -Wstrict-prototypes -Wno-uninitialized"
+ " -Wno-four-char-constants -Wno-unknown-pragmas");
+ }
+ if ((HaveMacBundleApp) && (ide_vers < 3100)) {
+ WriteDestFileLn("WRAPPER_EXTENSION = app;");
+ }
+ if ((ide_vers >= 1000) && (ide_vers < 3100)) {
+ WriteDestFileLn("ZERO_LINK = NO;");
+ }
+}
+
+LOCALPROC WriteAPBplist(void)
+{
+ int SaveDestFileIndent = DestFileIndent;
+
+ DestFileIndent = 0;
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<!DOCTYPE plist PUBLIC ");
+ WriteBackSlashToDestFile();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("-//Apple Computer//DTD PLIST 1.0//EN");
+ WriteBackSlashToDestFile();
+ WriteQuoteToDestFile();
+ WriteSpaceToDestFile();
+ WriteBackSlashToDestFile();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd");
+ WriteBackSlashToDestFile();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(">");
+ WriteEndDestFileLn();
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("<plist version=");
+ WriteBackSlashToDestFile();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("1.0");
+ WriteBackSlashToDestFile();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(">");
+ WriteEndDestFileLn();
+
+ CurPListFormat = kPListRaw;
+
+ WriteMyInfoPListContents();
+
+ WriteDestFileLn("</plist>");
+ WriteBgnDestFileLn();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(";");
+ WriteEndDestFileLn();
+
+ DestFileIndent = SaveDestFileIndent;
+}
+
+LOCALPROC WriteStrFrameworks(void)
+{
+ WriteCStrToDestFile("Frameworks");
+}
+
+LOCALPROC WriteStrSources(void)
+{
+ WriteCStrToDestFile("Sources");
+}
+
+LOCALPROC WriteStrResources(void)
+{
+ WriteCStrToDestFile("Resources");
+}
+
+LOCALPROC WriteStrRez(void)
+{
+ WriteCStrToDestFile("Rez");
+}
+
+LOCALPROC WriteStrFrameworksLibraries(void)
+{
+ WriteCStrToDestFile("External Frameworks and Libraries");
+}
+
+LOCALPROC WriteStrQuoteFrameworksLibraries(void)
+{
+ WriteQuoteToDestFile();
+ WriteStrFrameworksLibraries();
+ WriteQuoteToDestFile();
+}
+
+LOCALPROC WriteStrProducts(void)
+{
+ WriteCStrToDestFile("Products");
+}
+
+LOCALPROC WriteStrHeaders(void)
+{
+ WriteCStrToDestFile("Headers");
+}
+
+LOCALPROC WriteStrIncludes(void)
+{
+ WriteCStrToDestFile("Includes");
+}
+
+LOCALPROC WriteStrProjectObject(void)
+{
+ WriteCStrToDestFile("Project object");
+}
+
+LOCALPROC WriteStrEmptyQuote(void)
+{
+ WriteQuoteToDestFile();
+ WriteQuoteToDestFile();
+}
+
+LOCALPROC WriteAPBXCDDObjAPropPathNull(void)
+{
+ if (ide_vers < 2100) {
+ WriteAPBXCDDObjAPropPath(WriteStrEmptyQuote);
+ }
+}
+
+LOCALPROC WriteAPBXCDMainGroupName(void)
+{
+ if (ide_vers < 1000) {
+ WriteQuoteToDestFile();
+ WriteAppVariationStr();
+ WriteQuoteToDestFile();
+ } else {
+ WriteStrAppAbbrev();
+ }
+}
+
+LOCALPROC WriteAPBXCDDObjAPropIsaAppTarg(void)
+{
+ if (ide_vers < 1000) {
+ WriteAPBXCDDObjAPropIsa("PBXApplicationTarget");
+ } else {
+ WriteAPBXCDDObjAPropIsa("PBXNativeTarget");
+ }
+}
+
+LOCALPROC WriteStrConfListPBXProject(void)
+{
+ WriteCStrToDestFile("Build configuration list for PBXProject \"");
+ WriteStrAppAbbrev();
+ WriteCStrToDestFile("\"");
+}
+
+LOCALPROC WriteStrConfListPBXNativeTarget(void)
+{
+ WriteCStrToDestFile(
+ "Build configuration list for PBXNativeTarget \"");
+ WriteStrAppAbbrev();
+ WriteCStrToDestFile("\"");
+}
+
+#define HaveFrameworks HaveMacBundleApp
+
+LOCALPROC WriteXCDdummyfile(void)
+{
+ WriteDestFileLn("dummy");
+}
+
+LOCALPROC WriteXCDProjectFile(void)
+{
+ WriteDestFileLn("// !$*UTF8*$!");
+ WriteDestFileLn("{");
+ ++DestFileIndent;
+ WriteDestFileLn("archiveVersion = 1;");
+ WriteDestFileLn("classes = {");
+ WriteDestFileLn("};");
+ if (ide_vers >= 3200) {
+ WriteDestFileLn("objectVersion = 46;");
+ } else if (ide_vers >= 3100) {
+ WriteDestFileLn("objectVersion = 45;");
+ } else if (ide_vers >= 2100) {
+ WriteDestFileLn("objectVersion = 42;");
+ } else if (ide_vers >= 1000) {
+ WriteDestFileLn("objectVersion = 39;");
+ } else {
+ WriteDestFileLn("objectVersion = 38;");
+ }
+ WriteDestFileLn("objects = {");
+ ++DestFileIndent;
+
+ DoBeginSectionAPBXCD("PBXBuildFile");
+ DoAllSrcFilesWithSetup(DoSrcFileAPBXCDaddFile);
+ if (HaveMacBundleApp) {
+ DoAllDocTypesWithSetup(DoDocTypeAPBXCDaddFile);
+ }
+
+ if (HaveFrameworks) {
+ DoAllFrameWorksWithSetup(DoFrameWorkAPBXCDaddFile);
+ }
+ if (HaveAPBXCD_StdcLib) {
+ DoLibStdcAPBXCDaddFile();
+ }
+
+ if (HaveMacRrscs) {
+ DoRsrcAPBXCDaddFile();
+ }
+
+ if (HaveMacBundleApp) {
+ if (HaveAPBXCD_LangDummy) {
+ DoDummyLangAPBXCDaddFile();
+ }
+ }
+ DoEndSectionAPBXCD("PBXBuildFile");
+
+ if (ide_vers < 2300) {
+ DoBeginSectionAPBXCD("PBXBuildStyle");
+ WriteAPBXCDBeginObject(APBospcBuildStyle,
+ 0, WriteXCDconfigname);
+
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXBuildStyle");
+ }
+
+ if (ide_vers < 1500) {
+ WriteAPBXCDBgnObjList("buildRules");
+ WriteAPBXCDEndObjList();
+ }
+ WriteDestFileLn("buildSettings = {");
+ WriteDestFileLn("};");
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXBuildStyle");
+ }
+ WriteAPBXCDDObjAPropName(WriteXCDconfigname);
+ WriteAPBXCDEndObject();
+ DoEndSectionAPBXCD("PBXBuildStyle");
+ }
+
+ DoBeginSectionAPBXCD("PBXFileReference");
+ DoAllSrcFilesWithSetup(DoSrcFileAPBXCDaddFileRef);
+
+ if (HaveAPBXCD_Headers) {
+ DoAllSrcFilesWithSetup(DoHeaderFileXCDaddFileRef);
+ DoAllExtraHeaders2WithSetup(
+ DoExtraHeaderFileXCDaddFileRef);
+ }
+
+ if (HaveMacBundleApp) {
+ DoAllDocTypesWithSetup(DoDocTypeAPBXCDaddFileRef);
+ }
+
+ if (HaveFrameworks) {
+ DoAllFrameWorksWithSetup(DoFrameWorkAPBXCDaddFileRef);
+ }
+ if (HaveAPBXCD_StdcLib) {
+ DoLibStdcAPBXCDaddFileRef();
+ }
+
+ DoProductAPBXCDaddFileRef();
+
+ if (HaveMacBundleApp) {
+ if (HaveAPBXCD_PlistFile) {
+ DoPlistAPBXCDaddFileRef();
+ }
+ }
+ if (HaveMacRrscs) {
+ DoRsrcAPBXCDaddFileRef();
+ }
+ if (HaveMacBundleApp) {
+ if (HaveAPBXCD_LangDummy) {
+ DoLangDummyAPBXCDaddFileRef();
+ }
+ }
+ DoEndSectionAPBXCD("PBXFileReference");
+
+ DoBeginSectionAPBXCD("PBXFrameworksBuildPhase");
+ WriteAPBXCDBeginObject(APBospcPhaseLibs, 0, WriteStrFrameworks);
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXFrameworksBuildPhase");
+ }
+
+ WriteDestFileLn("buildActionMask = 2147483647;");
+ WriteAPBXCDBgnObjList("files");
+ if (HaveFrameworks) {
+ DoAllFrameWorksWithSetup(
+ DoFrameworkAPBXCDaddToBuild);
+ }
+ if (HaveAPBXCD_StdcLib) {
+ WriteAPBXCDobjlistelmp(APBospcLibStdcBld,
+ 0, WriteLibStdcName);
+ }
+ WriteAPBXCDEndObjList();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXFrameworksBuildPhase");
+ }
+ WriteDestFileLn("runOnlyForDeploymentPostprocessing = 0;");
+ WriteAPBXCDEndObject();
+ DoEndSectionAPBXCD("PBXFrameworksBuildPhase");
+
+ DoBeginSectionAPBXCD("PBXGroup");
+ WriteAPBXCDBeginObject(APBospcSources, 0, WriteStrSources);
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+
+ WriteAPBXCDBgnObjList("children");
+ DoAllSrcFilesWithSetup(DoSrcFileAPBXCDaddToGroup);
+ if (HaveMacRrscs) {
+ if (ide_vers >= 2100) {
+ WriteAPBXCDobjlistelmp(APBospcMainRsrcRf, 0,
+ WriteMainRsrcName);
+ }
+ }
+ WriteAPBXCDEndObjList();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+ WriteAPBXCDDObjAPropName(WriteStrSources);
+ WriteAPBXCDDObjAPropPathNull();
+ WriteAPBXCDDObjAPropRefType4();
+ WriteAPBXCDDObjAPropSourceTreeGroup();
+ WriteAPBXCDEndObject();
+
+ if (HaveMacBundleApp) {
+ WriteAPBXCDBeginObject(APBospcResources,
+ 0, WriteStrResources);
+
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+
+ WriteAPBXCDBgnObjList("children");
+ if (HaveMacRrscs) {
+ if (ide_vers < 2100) {
+ WriteAPBXCDobjlistelmp(APBospcMainRsrcRf,
+ 0, WriteMainRsrcName);
+ }
+ }
+ DoAllDocTypesWithSetup(
+ DoDocTypeAPBXCDaddToGroup);
+ if (HaveAPBXCD_PlistFile) {
+ WriteAPBXCDobjlistelmp(APBospcPlistRf,
+ 0, WriteInfoPlistFileName);
+ }
+ if (HaveAPBXCD_LangDummy) {
+#if 0
+ WriteAPBXCDobjlistelmp(APBospcLangRf,
+ 0, WriteLProjFolderName);
+#endif
+ WriteAPBXCDobjlistelmp(APBospcLangDummyRf,
+ 0, WriteDummyLangFileName);
+ }
+ WriteAPBXCDEndObjList();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+ WriteAPBXCDDObjAPropName(WriteStrResources);
+ WriteAPBXCDDObjAPropPathNull();
+ WriteAPBXCDDObjAPropRefType4();
+ WriteAPBXCDDObjAPropSourceTreeGroup();
+ WriteAPBXCDEndObject();
+ }
+
+ if (HaveFrameworks) {
+ WriteAPBXCDBeginObject(APBospcLibraries,
+ 0, WriteStrFrameworksLibraries);
+
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+
+ WriteAPBXCDBgnObjList("children");
+ DoAllFrameWorksWithSetup(
+ DoFrameworkAPBXCDaddToLibraries);
+ if (HaveAPBXCD_StdcLib) {
+ WriteAPBXCDobjlistelmp(APBospcLibStdcRf,
+ 0, WriteLibStdcName);
+ }
+ WriteAPBXCDEndObjList();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+ WriteAPBXCDDObjAPropName(
+ WriteStrQuoteFrameworksLibraries);
+ WriteAPBXCDDObjAPropPathNull();
+ WriteAPBXCDDObjAPropRefType4();
+ WriteAPBXCDDObjAPropSourceTreeGroup();
+ WriteAPBXCDEndObject();
+ }
+
+ WriteAPBXCDBeginObject(APBospcProducts, 0, WriteStrProducts);
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+
+ WriteAPBXCDBgnObjList("children");
+ WriteAPBXCDobjlistelmp(APBospcProductRef,
+ 0, WriteAppNameStr);
+ WriteAPBXCDEndObjList();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+ WriteAPBXCDDObjAPropName(WriteStrProducts);
+ WriteAPBXCDDObjAPropRefType4();
+ WriteAPBXCDDObjAPropSourceTreeGroup();
+ WriteAPBXCDEndObject();
+
+ WriteAPBXCDBeginObject(APBospcMainGroup, 0, WriteStrAppAbbrev);
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+
+ WriteAPBXCDBgnObjList("children");
+ WriteAPBXCDobjlistelmp(APBospcSources,
+ 0, WriteStrSources);
+ if (HaveAPBXCD_Headers) {
+ WriteAPBXCDobjlistelmp(APBospcSrcHeaders,
+ 0, WriteStrHeaders);
+ WriteAPBXCDobjlistelmp(APBospcIncludes,
+ 0, WriteStrIncludes);
+ }
+ if (HaveMacBundleApp) {
+ WriteAPBXCDobjlistelmp(APBospcResources,
+ 0, WriteStrResources);
+ }
+ if (HaveFrameworks) {
+ WriteAPBXCDobjlistelmp(APBospcLibraries,
+ 0, WriteStrFrameworksLibraries);
+ }
+ WriteAPBXCDobjlistelmp(APBospcProducts,
+ 0, WriteStrProducts);
+ WriteAPBXCDEndObjList();
+
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+ WriteAPBXCDDObjAPropName(WriteAPBXCDMainGroupName);
+ WriteAPBXCDDObjAPropPathNull();
+ WriteAPBXCDDObjAPropRefType4();
+ WriteAPBXCDDObjAPropSourceTreeGroup();
+ WriteAPBXCDEndObject();
+ if (HaveAPBXCD_Headers) {
+ WriteAPBXCDBeginObject(APBospcSrcHeaders,
+ 0, WriteStrHeaders);
+
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+
+ WriteAPBXCDBgnObjList("children");
+ DoAllSrcFilesWithSetup(
+ DoHeaderFileXCDaddToGroup);
+ WriteAPBXCDEndObjList();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+ WriteAPBXCDDObjAPropName(WriteStrHeaders);
+ WriteAPBXCDDObjAPropRefType4();
+ WriteAPBXCDDObjAPropSourceTreeGroup();
+ WriteAPBXCDEndObject();
+ WriteAPBXCDBeginObject(APBospcIncludes,
+ 0, WriteStrIncludes);
+
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+
+ WriteAPBXCDBgnObjList("children");
+ DoAllExtraHeaders2WithSetup(
+ DoExtraHeaderFileXCDaddToGroup);
+ WriteAPBXCDEndObjList();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+ WriteAPBXCDDObjAPropName(WriteStrIncludes);
+ WriteAPBXCDDObjAPropRefType4();
+ WriteAPBXCDDObjAPropSourceTreeGroup();
+ WriteAPBXCDEndObject();
+#if 0
+ WriteAPBXCDBeginObject(APBospcLangRf,
+ 0, WriteLProjFolderName);
+
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+
+ WriteAPBXCDBgnObjList("children");
+ WriteAPBXCDobjlistelmp(APBospcLangDummyRf,
+ 0, WriteDummyLangFileName);
+ WriteAPBXCDEndObjList();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaGroup();
+ }
+ WriteAPBXCDDObjAPropName(WriteLProjFolderName);
+ WriteAPBXCDDObjAPropPath(WriteLProjFolderPath);
+ WriteAPBXCDDObjAPropRefType4();
+ WriteAPBXCDDObjAPropSourceTreeGroup();
+ WriteAPBXCDEndObject();
+#endif
+ }
+ DoEndSectionAPBXCD("PBXGroup");
+
+ DoBeginSectionAPBXCD("PBXNativeTarget");
+ WriteAPBXCDBeginObject(APBospcTarget, 0, WriteStrAppAbbrev);
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaAppTarg();
+ }
+
+ if (ide_vers >= 2100) {
+ WriteAPBXCDDObjAProp_SO("buildConfigurationList",
+ APBospcLstNatCnfg, 0,
+ WriteStrConfListPBXNativeTarget);
+ }
+ WriteAPBXCDBgnObjList("buildPhases");
+ if (ide_vers < 1500) {
+ WriteAPBXCDobjlistelmp(APBospcHeaders,
+ 0, WriteStrHeaders);
+ }
+ if (HaveMacBundleApp) {
+ WriteAPBXCDobjlistelmp(APBospcBunRsrcs,
+ 0, WriteStrResources);
+ }
+ WriteAPBXCDobjlistelmp(APBospcPhaseSrcs,
+ 0, WriteStrSources);
+ WriteAPBXCDobjlistelmp(APBospcPhaseLibs,
+ 0, WriteStrFrameworks);
+ if (HaveMacRrscs) {
+ WriteAPBXCDobjlistelmp(APBospcPhaseRsrc,
+ 0, WriteStrRez);
+ }
+ WriteAPBXCDEndObjList();
+ if (ide_vers >= 1000) {
+ WriteAPBXCDBgnObjList("buildRules");
+ WriteAPBXCDEndObjList();
+ }
+ if (ide_vers < 2300) {
+ WriteDestFileLn("buildSettings = {");
+ ++DestFileIndent;
+ if (ide_vers < 2100) {
+ WriteAPBXCDBuildSettings();
+ }
+ --DestFileIndent;
+ WriteDestFileLn("};");
+ }
+ WriteAPBXCDBgnObjList("dependencies");
+ WriteAPBXCDEndObjList();
+
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsaAppTarg();
+ }
+
+ WriteAPBXCDDObjAPropName(WriteStrAppAbbrev);
+
+ if (ide_vers >= 1000) {
+ WriteDestFileLn(
+ "productInstallPath = \"$(HOME)/Applications\";");
+ }
+
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("productName = ");
+ if (ide_vers < 1000) {
+ WriteQuoteToDestFile();
+ }
+ WriteStrAppAbbrev();
+ if (ide_vers < 1000) {
+ WriteQuoteToDestFile();
+ }
+ WriteCStrToDestFile(";");
+ WriteEndDestFileLn();
+
+ WriteAPBXCDDObjAProp_SO("productReference",
+ APBospcProductRef, 0,
+ WriteAppNameStr);
+
+ if (ide_vers >= 1000) {
+ if (HaveMacBundleApp) {
+ WriteDestFileLn(
+ "productType = "
+ "\"com.apple.product-type.application\";");
+ } else {
+ WriteDestFileLn(
+ "productType = "
+ "\"com.apple.product-type.tool\";");
+ }
+ }
+ if ((! HaveAPBXCD_PlistFile) && HaveMacBundleApp) {
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("productSettingsXML = ");
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("<?xml version=");
+ WriteBackSlashToDestFile();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile("1.0");
+ WriteBackSlashToDestFile();
+ WriteQuoteToDestFile();
+ WriteCStrToDestFile(" encoding=\\\"UTF-8\\\"?>");
+ WriteEndDestFileLn();
+
+ WriteAPBplist();
+ }
+ WriteAPBXCDEndObject();
+ DoEndSectionAPBXCD("PBXNativeTarget");
+
+ DoBeginSectionAPBXCD("PBXProject");
+ WriteAPBXCDBeginObject(APBospcRoot, 0, WriteStrProjectObject);
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXProject");
+ }
+ if (ide_vers >= 4300) {
+ WriteDestFileLn("attributes = {");
+ ++DestFileIndent;
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("LastUpgradeCheck = ");
+ WriteCharToDestFile('0'
+ + ((ide_vers / 10000) % 10));
+ WriteCharToDestFile('0' + ((ide_vers / 1000) % 10));
+ WriteCharToDestFile('0' + ((ide_vers / 100) % 10));
+ WriteCStrToDestFile("0;");
+ WriteEndDestFileLn();
+ --DestFileIndent;
+ WriteDestFileLn("};");
+ }
+ if (ide_vers >= 2100) {
+ WriteAPBXCDDObjAProp_SO("buildConfigurationList",
+ APBospcLstPrjCnfg, 0,
+ WriteStrConfListPBXProject);
+ }
+ if (ide_vers < 2300) {
+ if (ide_vers >= 1000) {
+ WriteDestFileLn("buildSettings = {");
+ WriteDestFileLn("};");
+ }
+ WriteAPBXCDBgnObjList("buildStyles");
+ WriteAPBXCDobjlistelmp(APBospcBuildStyle,
+ 0, WriteXCDconfigname);
+ WriteAPBXCDEndObjList();
+ }
+ if (ide_vers >= 3200) {
+ WriteDestFileLn(
+ "compatibilityVersion = \"Xcode 3.2\";");
+ } else if (ide_vers >= 3100) {
+ WriteDestFileLn(
+ "compatibilityVersion = \"Xcode 3.1\";");
+ }
+ WriteDestFileLn("hasScannedForEncodings = 1;");
+
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXProject");
+ }
+
+ WriteAPBXCDDObjAProp_SO("mainGroup",
+ APBospcMainGroup, 0,
+ WriteStrAppAbbrev);
+
+ if (ide_vers >= 4000) {
+ WriteAPBXCDDObjAProp_SO("productRefGroup",
+ APBospcProducts, 0,
+ WriteStrProducts);
+ }
+
+ WriteDestFileLn("projectDirPath = \"\";");
+
+ if (ide_vers >= 3100) {
+ WriteDestFileLn("projectRoot = \"\";");
+ }
+
+ WriteAPBXCDBgnObjList("targets");
+ WriteAPBXCDobjlistelmp(APBospcTarget,
+ 0, WriteStrAppAbbrev);
+ WriteAPBXCDEndObjList();
+ WriteAPBXCDEndObject();
+ DoEndSectionAPBXCD("PBXProject");
+
+ if (HaveMacBundleApp) {
+ DoBeginSectionAPBXCD("PBXResourcesBuildPhase");
+ WriteAPBXCDBeginObject(APBospcBunRsrcs,
+ 0, WriteStrResources);
+
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXResourcesBuildPhase");
+ }
+
+ WriteDestFileLn("buildActionMask = 2147483647;");
+ WriteAPBXCDBgnObjList("files");
+ DoAllDocTypesWithSetup(
+ DoDocTypeAPBXCDaddToSources);
+ if (HaveAPBXCD_LangDummy) {
+ DoLangDummyAPBXCDaddToSources();
+ }
+ WriteAPBXCDEndObjList();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXResourcesBuildPhase");
+ }
+ WriteDestFileLn(
+ "runOnlyForDeploymentPostprocessing = 0;");
+ WriteAPBXCDEndObject();
+ DoEndSectionAPBXCD("PBXResourcesBuildPhase");
+ }
+ if (HaveMacRrscs) {
+ DoBeginSectionAPBXCD("PBXRezBuildPhase");
+ WriteAPBXCDBeginObject(APBospcPhaseRsrc, 0, WriteStrRez);
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXRezBuildPhase");
+ }
+
+ WriteDestFileLn("buildActionMask = 2147483647;");
+ WriteAPBXCDBgnObjList("files");
+ WriteAPBXCDobjlistelmp(APBospcMnRsrcBld, 0,
+ WriteMainAPBXCDRsrcNameinRez);
+ WriteAPBXCDEndObjList();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXRezBuildPhase");
+ }
+ WriteDestFileLn(
+ "runOnlyForDeploymentPostprocessing = 0;");
+ WriteAPBXCDEndObject();
+ DoEndSectionAPBXCD("PBXRezBuildPhase");
+ }
+
+ if (ide_vers < 1500) {
+ WriteAPBXCDBeginObject(APBospcHeaders, 0, WriteStrHeaders);
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXHeadersBuildPhase");
+ }
+
+ WriteDestFileLn("buildActionMask = 2147483647;");
+ WriteAPBXCDBgnObjList("files");
+ WriteAPBXCDEndObjList();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXHeadersBuildPhase");
+ }
+ WriteDestFileLn("runOnlyForDeploymentPostprocessing = 0;");
+ WriteAPBXCDEndObject();
+ }
+
+ DoBeginSectionAPBXCD("PBXSourcesBuildPhase");
+ WriteAPBXCDBeginObject(APBospcPhaseSrcs, 0, WriteStrSources);
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXSourcesBuildPhase");
+ }
+
+ WriteDestFileLn("buildActionMask = 2147483647;");
+ WriteAPBXCDBgnObjList("files");
+ DoAllSrcFilesSortWithSetup(
+ DoSrcFileAPBXCDaddToSources);
+ WriteAPBXCDEndObjList();
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("PBXSourcesBuildPhase");
+ }
+ WriteDestFileLn("runOnlyForDeploymentPostprocessing = 0;");
+ WriteAPBXCDEndObject();
+ DoEndSectionAPBXCD("PBXSourcesBuildPhase");
+
+ if (HaveMacBundleApp) {
+ if (HaveAPBXCD_LangDummy) {
+ DoBeginSectionAPBXCD("PBXVariantGroup");
+ DoLangDummyAPBXCDaddVariant();
+ DoEndSectionAPBXCD("PBXVariantGroup");
+ }
+ }
+
+ if (ide_vers >= 2100) {
+ DoBeginSectionAPBXCD("XCBuildConfiguration");
+ WriteAPBXCDBeginObject(APBospcNatCnfg,
+ 0, WriteXCDconfigname);
+
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("XCBuildConfiguration");
+ }
+
+ WriteDestFileLn("buildSettings = {");
+ ++DestFileIndent;
+ WriteAPBXCDBuildSettings();
+ --DestFileIndent;
+ WriteDestFileLn("};");
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("XCBuildConfiguration");
+ }
+ WriteAPBXCDDObjAPropName(WriteXCDconfigname);
+ WriteAPBXCDEndObject();
+ WriteAPBXCDBeginObject(APBospcPrjCnfg,
+ 0, WriteXCDconfigname);
+
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("XCBuildConfiguration");
+ }
+
+ WriteDestFileLn("buildSettings = {");
+ WriteDestFileLn("};");
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("XCBuildConfiguration");
+ }
+ WriteAPBXCDDObjAPropName(WriteXCDconfigname);
+ WriteAPBXCDEndObject();
+ DoEndSectionAPBXCD("XCBuildConfiguration");
+ }
+
+ if (ide_vers >= 2100) {
+ DoBeginSectionAPBXCD("XCConfigurationList");
+ WriteAPBXCDBeginObject(APBospcLstNatCnfg, 0,
+ WriteStrConfListPBXNativeTarget);
+
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("XCConfigurationList");
+ }
+
+ WriteAPBXCDBgnObjList("buildConfigurations");
+ WriteAPBXCDobjlistelmp(APBospcNatCnfg,
+ 0, WriteXCDconfigname);
+ WriteAPBXCDEndObjList();
+ WriteAPBXCDDObjAProp_SS(
+ "defaultConfigurationIsVisible", "0");
+ WriteAPBXCDDObjAProp_SP(
+ "defaultConfigurationName", WriteXCDconfigname);
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("XCConfigurationList");
+ }
+ WriteAPBXCDEndObject();
+ WriteAPBXCDBeginObject(APBospcLstPrjCnfg, 0,
+ WriteStrConfListPBXProject);
+
+ if (HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("XCConfigurationList");
+ }
+
+ WriteAPBXCDBgnObjList("buildConfigurations");
+ WriteAPBXCDobjlistelmp(APBospcPrjCnfg,
+ 0, WriteXCDconfigname);
+ WriteAPBXCDEndObjList();
+ WriteAPBXCDDObjAProp_SS(
+ "defaultConfigurationIsVisible", "0");
+ WriteAPBXCDDObjAProp_SP(
+ "defaultConfigurationName", WriteXCDconfigname);
+ if (! HaveAPBXCD_IsaFirst) {
+ WriteAPBXCDDObjAPropIsa("XCConfigurationList");
+ }
+ WriteAPBXCDEndObject();
+ DoEndSectionAPBXCD("XCConfigurationList");
+ }
+
+ --DestFileIndent;
+ WriteDestFileLn("};");
+ WriteBgnDestFileLn();
+ WriteCStrToDestFile("rootObject = ");
+ WriteAPBXCDObjectIdAndComment(APBospcRoot,
+ 0, WriteStrProjectObject);
+ WriteCStrToDestFile(";");
+ WriteEndDestFileLn();
+ --DestFileIndent;
+ WriteDestFileLn("}");
+}
+
+LOCALPROC WriteOutDummyLangContents(void)
+{
+ WriteDestFileLn(
+ "This file is here because some archive extraction");
+ WriteDestFileLn("software will not create an empty directory.");
+}
+
+LOCALPROC WriteXCDSpecificFiles(void)
+{
+ MakeSubDirectory("my_proj_d", "my_project_d", vStrAppAbbrev,
+ (ide_vers >= 2100) ? ".xcodeproj" : ".pbproj");
+
+ WriteADstFile1("my_proj_d",
+ "project", ".pbxproj", "project file",
+ WriteXCDProjectFile);
+
+ if (HaveMacBundleApp) {
+ if (HaveAPBXCD_PlistFile) {
+ WritePListData();
+ }
+
+ MakeSubDirectory("my_lang_d", "my_config_d",
+ GetLProjName(gbo_lang), ".lproj");
+
+ WriteADstFile1("my_lang_d",
+ "dummy", ".txt", "Dummy",
+ WriteOutDummyLangContents);
+ }
+
+ if (WantSandbox) {
+ WriteEntitlementsData();
+ }
+}
--- /dev/null
+++ b/setup/mkfile
@@ -1,0 +1,8 @@
+</$objtype/mkfile
+
+CFLAGS=-p -D__plan9__ $CFLAGS
+TARG=setup
+OFILES=tool.$O
+default:V: all
+
+</sys/src/cmd/mkone
--- /dev/null
+++ b/setup/tool.c
@@ -1,0 +1,175 @@
+/*
+ app.c
+ Copyright (C) 2009 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef __plan9__
+#include <u.h>
+#include <libc.h>
+#else
+#include <stdlib.h>
+#include <string.h>
+#endif
+#include <stdio.h>
+
+#include "COREDEFS.i"
+
+#include "CNFGOPTS.i"
+#include "CONFIGUR.i"
+#include "CNFGDLFT.i"
+
+
+#define MyMoveBytes(src, dst, n) \
+ (void) memmove((void *)(dst), (void *)(src), n)
+
+#define kMyErr_noErr 0 /* no error */
+
+#define kMyErrReported 1029
+ /* already notified user, no further report needed */
+#define kMyErrNoMatch 1030
+ /* (so try something else) always should be handled, not reported */
+
+#if NeedSegmenting
+#pragma segment Utilities
+#endif
+
+#include "STRUTILS.i"
+
+#include "CMDARGT1.i"
+
+#include "WRTEXTFL.i"
+
+#if NeedSegmenting
+#pragma segment Body
+#endif
+
+#include "SPBASDEF.i"
+
+#include "GNBLDOPT.i"
+#ifdef Have_SPBLDOPT
+#include "SPBLDOPT.i"
+#endif
+
+#if NeedSegmenting
+#pragma segment Body1
+#endif
+
+#include "BLDUTIL3.i"
+
+#include "DFFILDEF.i"
+#include "SPFILDEF.i"
+
+#if NeedSegmenting
+#pragma segment Body2
+#endif
+
+#include "USFILDEF.i"
+#include "WRMACRES.i"
+#include "WRMPLIST.i"
+#include "WRCNFGGL.i"
+#include "WRCNFGAP.i"
+
+#if NeedSegmenting
+#pragma segment Body3
+#endif
+
+#if gbk_ide_mpw == cur_ide
+#include "WRMPWFLS.i"
+#endif
+
+#if gbk_ide_mw8 == cur_ide
+#include "WRMW8FLS.i"
+#endif
+
+#if gbk_ide_mvc == cur_ide
+#include "WRMVCFLS.i"
+#endif
+
+#if (gbk_ide_bgc == cur_ide) \
+ || (gbk_ide_cyg == cur_ide) \
+ || (gbk_ide_mgw == cur_ide) \
+ || (gbk_ide_dkp == cur_ide) \
+ || (gbk_ide_dvc == cur_ide) \
+ || (gbk_ide_xcd == cur_ide)
+#include "WRBGCFLS.i"
+#endif
+
+#if gbk_ide_snc == cur_ide
+#include "WRSNCFLS.i"
+#endif
+
+#if gbk_ide_msv == cur_ide
+#include "WRMSCFLS.i"
+#endif
+
+#if gbk_ide_lcc == cur_ide
+#include "WRLCCFLS.i"
+#endif
+
+#if gbk_ide_dvc == cur_ide
+#include "WRDVCFLS.i"
+#endif
+
+#if gbk_ide_xcd == cur_ide
+#include "WRXCDFLS.i"
+#endif
+
+#if gbk_ide_dmc == cur_ide
+#include "WRDMCFLS.i"
+#endif
+
+#if gbk_ide_plc == cur_ide
+#include "WRPLCFLS.i"
+#endif
+
+#if gbk_ide_ccc == cur_ide || gbk_ide_9pc == cur_ide
+#include "WRCCCFLS.i"
+#endif
+
+#if NeedSegmenting
+#pragma segment Body4
+#endif
+
+#ifdef Have_SPCNFGGL
+#include "SPCNFGGL.i"
+#endif
+#ifdef Have_SPCNFGAP
+#include "SPCNFGAP.i"
+#endif
+#include "SPOTHRCF.i"
+
+#if NeedSegmenting
+#pragma segment Main
+#endif
+
+#include "BLDUTIL4.i"
+
+int main(int argc, char *argv[])
+{
+ tMyErr err;
+ int return_code = 1;
+
+ BeginParseCommandLineArguments(argc, argv);
+
+ err = DoTheCommand();
+
+ if (kMyErr_noErr == err) {
+ return_code = 0;
+ } else {
+ if (kMyErrReported != err) {
+ fprintf(stderr, "Unknown Error in %s", argv[0]);
+ }
+ }
+
+ return return_code;
+}
--- /dev/null
+++ b/src/ACTVCODE.h
@@ -1,0 +1,373 @@
+/*
+ ACTVCODE.h
+
+ Copyright (C) 2009 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ ACTiVation CODE
+*/
+
+LOCALFUNC uimr KeyFun0(uimr x, uimr y, uimr m)
+{
+ uimr r = x + y;
+
+ if ((r >= m) || (r < x)) {
+ r -= m;
+ }
+
+ return r;
+}
+
+LOCALFUNC uimr KeyFun1(uimr x, uimr y, uimr m)
+{
+ uimr r = 0;
+ uimr t = x;
+ uimr s = y;
+
+ while (s > 0) {
+ if (0 != (s & 1)) {
+ r = KeyFun0(r, t, m);
+ }
+ t = KeyFun0(t, t, m);
+ s >>= 1;
+ }
+
+ return r;
+}
+
+LOCALFUNC uimr KeyFun2(uimr x, uimr y, uimr m)
+{
+ uimr r = 1;
+ uimr t = x;
+ uimr s = y;
+
+ while (s > 0) {
+ if (0 != (s & 1)) {
+ r = KeyFun1(r, t, m);
+ }
+ t = KeyFun1(t, t, m);
+ s >>= 1;
+ }
+
+ return r;
+}
+
+LOCALFUNC blnr CheckActvCode(ui3p p, blnr *Trial)
+{
+ blnr IsOk = falseblnr;
+ uimr v0 = do_get_mem_long(p);
+ uimr v1 = do_get_mem_long(p + 4);
+
+ if (v0 > KeyCon2) {
+ /* v0 too big */
+ } else if (v1 > KeyCon4) {
+ /* v1 too big */
+ } else {
+ uimr t0 = KeyFun0(v0, KeyCon0, KeyCon2);
+ uimr t1 = KeyFun2(KeyCon1, t0, KeyCon2);
+ uimr t2 = KeyFun2(v1, KeyCon3, KeyCon4);
+ uimr t3 = KeyFun0(t2, KeyCon4 - t1, KeyCon4);
+ uimr t4 = KeyFun0(t3, KeyCon4 - KeyCon5, KeyCon4);
+ if ((0 == (t4 >> 8)) && (t4 >= KeyCon6)) {
+ *Trial = falseblnr;
+ IsOk = trueblnr;
+ } else if (0 == t4) {
+ *Trial = trueblnr;
+ IsOk = trueblnr;
+ }
+ }
+
+ return IsOk;
+}
+
+/* user interface */
+
+LOCALFUNC blnr Key2Digit(ui3r key, ui3r *r)
+{
+ ui3r v;
+
+ switch (key) {
+ case MKC_0:
+ case MKC_KP0:
+ v = 0;
+ break;
+ case MKC_1:
+ case MKC_KP1:
+ v = 1;
+ break;
+ case MKC_2:
+ case MKC_KP2:
+ v = 2;
+ break;
+ case MKC_3:
+ case MKC_KP3:
+ v = 3;
+ break;
+ case MKC_4:
+ case MKC_KP4:
+ v = 4;
+ break;
+ case MKC_5:
+ case MKC_KP5:
+ v = 5;
+ break;
+ case MKC_6:
+ case MKC_KP6:
+ v = 6;
+ break;
+ case MKC_7:
+ case MKC_KP7:
+ v = 7;
+ break;
+ case MKC_8:
+ case MKC_KP8:
+ v = 8;
+ break;
+ case MKC_9:
+ case MKC_KP9:
+ v = 9;
+ break;
+ default:
+ return falseblnr;
+ break;
+ }
+
+ *r = v;
+ return trueblnr;
+}
+
+#define ActvCodeMaxLen 20
+LOCALVAR ui4r ActvCodeLen = 0;
+LOCALVAR ui3b ActvCodeDigits[ActvCodeMaxLen];
+
+#define ActvCodeFileLen 8
+
+#if UseActvFile
+FORWARDFUNC tMacErr ActvCodeFileSave(ui3p p);
+FORWARDFUNC tMacErr ActvCodeFileLoad(ui3p p);
+#endif
+
+LOCALVAR ui3b CurActvCode[ActvCodeFileLen];
+
+LOCALPROC DoActvCodeModeKey(ui3r key)
+{
+ ui3r digit;
+ ui3r L;
+ int i;
+ blnr Trial;
+
+ if (MKC_BackSpace == key) {
+ if (ActvCodeLen > 0) {
+ --ActvCodeLen;
+ NeedWholeScreenDraw = trueblnr;
+ }
+ } else if (Key2Digit(key, &digit)) {
+ if (ActvCodeLen < (ActvCodeMaxLen - 1)) {
+ ActvCodeDigits[ActvCodeLen] = digit;
+ ++ActvCodeLen;
+ NeedWholeScreenDraw = trueblnr;
+ L = ActvCodeDigits[0] + (1 + 9);
+ if (ActvCodeLen == L) {
+ uimr v0 = 0;
+ uimr v1 = 0;
+
+ for (i = 1; i < (ActvCodeDigits[0] + 1); ++i) {
+ v0 = v0 * 10 + ActvCodeDigits[i];
+ }
+ for (; i < ActvCodeLen; ++i) {
+ v1 = v1 * 10 + ActvCodeDigits[i];
+ }
+
+ do_put_mem_long(&CurActvCode[0], v0);
+ do_put_mem_long(&CurActvCode[4], v1);
+
+ if (CheckActvCode(CurActvCode, &Trial)) {
+ SpecialModeClr(SpclModeActvCode);
+ NeedWholeScreenDraw = trueblnr;
+#if UseActvFile
+ if (Trial) {
+ MacMsg(
+ "Using temporary code.",
+ "Thank you for trying Mini vMac!",
+ falseblnr);
+ } else {
+ if (mnvm_noErr != ActvCodeFileSave(CurActvCode))
+ {
+ MacMsg("Oops",
+ "I could not save the activation code"
+ " to disk.",
+ falseblnr);
+ } else {
+ MacMsg("Activation succeeded.",
+ "Thank you!", falseblnr);
+ }
+ }
+#else
+ MacMsg(
+ "Thank you for trying Mini vMac!",
+ "sample variation : ^v",
+ falseblnr);
+#endif
+ }
+ } else if (ActvCodeLen > L) {
+ --ActvCodeLen;
+ }
+ }
+ }
+}
+
+LOCALPROC DrawCellsActvCodeModeBody(void)
+{
+#if UseActvFile
+ DrawCellsOneLineStr("Please enter your activation code:");
+ DrawCellsBlankLine();
+#else
+ DrawCellsOneLineStr(
+ "To try this variation of ^p, please type these numbers:");
+ DrawCellsBlankLine();
+ DrawCellsOneLineStr("281 953 822 340");
+ DrawCellsBlankLine();
+#endif
+
+ if (0 == ActvCodeLen) {
+ DrawCellsOneLineStr("?");
+ } else {
+ int i;
+ ui3r L = ActvCodeDigits[0] + (1 + 9);
+
+ DrawCellsBeginLine();
+ for (i = 0; i < L; ++i) {
+ if (0 == ((L - i) % 3)) {
+ if (0 != i) {
+ DrawCellAdvance(kCellSpace);
+ }
+ }
+ if (i < ActvCodeLen) {
+ DrawCellAdvance(kCellDigit0 + ActvCodeDigits[i]);
+ } else if (i == ActvCodeLen) {
+ DrawCellAdvance(kCellQuestion);
+ } else {
+ DrawCellAdvance(kCellHyphen);
+ }
+ }
+ DrawCellsEndLine();
+ if (L == ActvCodeLen) {
+ DrawCellsBlankLine();
+ DrawCellsOneLineStr(
+ "Sorry, this is not a valid activation code.");
+ }
+ }
+
+#if UseActvFile
+ DrawCellsBlankLine();
+ DrawCellsOneLineStr(
+ "If you haven;}t obtained an activation code yet,"
+ " here is a temporary one:");
+ DrawCellsBlankLine();
+ DrawCellsOneLineStr("281 953 822 340");
+#else
+ DrawCellsBlankLine();
+ DrawCellsOneLineStr(kStrForMoreInfo);
+ DrawCellsOneLineStr("http://www.gryphel.com/c/var/");
+#endif
+}
+
+LOCALPROC DrawActvCodeMode(void)
+{
+ DrawSpclMode0(
+#if UseActvFile
+ "Activation Code",
+#else
+ "sample variation : ^v",
+#endif
+ DrawCellsActvCodeModeBody);
+}
+
+#if UseActvFile
+LOCALPROC ClStrAppendHexLong(int *L0, ui3b *r, ui5r v)
+{
+ ClStrAppendHexWord(L0, r, (v >> 16) & 0xFFFF);
+ ClStrAppendHexWord(L0, r, v & 0xFFFF);
+}
+#endif
+
+LOCALPROC CopyRegistrationStr(void)
+{
+ ui3b ps[ClStrMaxLength];
+ int i;
+ int L;
+ tPbuf j;
+#if UseActvFile
+ int L0;
+ ui5r sum;
+
+ ClStrFromSubstCStr(&L0, ps, "^v ");
+
+ for (i = 0; i < L0; ++i) {
+ ps[i] = Cell2MacAsciiMap[ps[i]];
+ }
+ L = L0;
+
+ sum = 0;
+ for (i = 0; i < L; ++i) {
+ sum += ps[i];
+ sum = (sum << 5) | ((sum >> (32 - 5)) & 0x1F);
+ sum += (sum << 8);
+ }
+
+ sum &= 0x1FFFFFFF;
+
+ sum = KeyFun0(sum, do_get_mem_long(&CurActvCode[0]), KeyCon4);
+
+ ClStrAppendHexLong(&L, ps, sum);
+
+ sum = KeyFun0(sum, do_get_mem_long(&CurActvCode[4]), KeyCon4);
+ sum = KeyFun2(sum, KeyCon3, KeyCon4);
+
+ ClStrAppendHexLong(&L, ps, sum);
+
+ for (i = L0; i < L; ++i) {
+ ps[i] = Cell2MacAsciiMap[ps[i]];
+ }
+#else
+ ClStrFromSubstCStr(&L, ps, "^v");
+
+ for (i = 0; i < L; ++i) {
+ ps[i] = Cell2MacAsciiMap[ps[i]];
+ }
+#endif
+
+ if (mnvm_noErr == PbufNew(L, &j)) {
+ PbufTransfer(ps, j, 0, L, trueblnr);
+ HTCEexport(j);
+ }
+}
+
+LOCALFUNC blnr ActvCodeInit(void)
+{
+#if UseActvFile
+ blnr Trial;
+
+ if ((mnvm_noErr != ActvCodeFileLoad(CurActvCode))
+ || (! CheckActvCode(CurActvCode, &Trial))
+ || Trial
+ )
+#endif
+ {
+ SpecialModeSet(SpclModeActvCode);
+ NeedWholeScreenDraw = trueblnr;
+ }
+
+ return trueblnr;
+}
--- /dev/null
+++ b/src/ADBEMDEV.c
@@ -1,0 +1,214 @@
+/*
+ ADBEMDEV.c
+
+ Copyright (C) 2008 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Apple Desktop Bus EMulated DEVice
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+#include "MYOSGLUE.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#endif
+
+#include "ADBEMDEV.h"
+
+#ifdef _VIA_Debug
+#include <stdio.h>
+#endif
+
+/*
+ ReportAbnormalID unused 0x0C06 - 0x0CFF
+*/
+
+IMPORTPROC ADB_ShiftOutData(ui3b v);
+IMPORTFUNC ui3b ADB_ShiftInData(void);
+
+#include "ADBSHARE.h"
+
+LOCALVAR blnr ADB_ListenDatBuf;
+LOCALVAR ui3b ADB_IndexDatBuf;
+
+GLOBALPROC ADB_DoNewState(void)
+{
+ ui3b state = ADB_st1 * 2 + ADB_st0;
+#ifdef _VIA_Debug
+ fprintf(stderr, "ADB_DoNewState: %d\n", state);
+#endif
+ {
+ ADB_Int = 1;
+ switch (state) {
+ case 0: /* Start a new command */
+ if (ADB_ListenDatBuf) {
+ ADB_ListenDatBuf = falseblnr;
+ ADB_SzDatBuf = ADB_IndexDatBuf;
+ ADB_EndListen();
+ }
+ ADB_TalkDatBuf = falseblnr;
+ ADB_IndexDatBuf = 0;
+ ADB_CurCmd = ADB_ShiftInData();
+ /* which sets interrupt, acknowleding command */
+#ifdef _VIA_Debug
+ fprintf(stderr, "in: %d\n", ADB_CurCmd);
+#endif
+ switch ((ADB_CurCmd >> 2) & 3) {
+ case 0: /* reserved */
+ switch (ADB_CurCmd & 3) {
+ case 0: /* Send Reset */
+ ADB_DoReset();
+ break;
+ case 1: /* Flush */
+ ADB_Flush();
+ break;
+ case 2: /* reserved */
+ case 3: /* reserved */
+ ReportAbnormalID(0x0C01,
+ "Reserved ADB command");
+ break;
+ }
+ break;
+ case 1: /* reserved */
+ ReportAbnormalID(0x0C02,
+ "Reserved ADB command");
+ break;
+ case 2: /* listen */
+ ADB_ListenDatBuf = trueblnr;
+#ifdef _VIA_Debug
+ fprintf(stderr, "*** listening\n");
+#endif
+ break;
+ case 3: /* talk */
+ ADB_DoTalk();
+ break;
+ }
+ break;
+ case 1: /* Transfer date byte (even) */
+ case 2: /* Transfer date byte (odd) */
+ if (! ADB_ListenDatBuf) {
+ /*
+ will get here even if no pending talk data,
+ when there is pending event from device
+ other than the one polled by the last talk
+ command. this probably indicates a bug.
+ */
+ if ((! ADB_TalkDatBuf)
+ || (ADB_IndexDatBuf >= ADB_SzDatBuf))
+ {
+ ADB_ShiftOutData(0xFF);
+ ADB_Data = 1;
+ ADB_Int = 0;
+ } else {
+#ifdef _VIA_Debug
+ fprintf(stderr, "*** talk one\n");
+#endif
+ ADB_ShiftOutData(ADB_DatBuf[ADB_IndexDatBuf]);
+ ADB_Data = 1;
+ ADB_IndexDatBuf += 1;
+ }
+ } else {
+ if (ADB_IndexDatBuf >= ADB_MaxSzDatBuf) {
+ ReportAbnormalID(0x0C03, "ADB listen too much");
+ /* ADB_MaxSzDatBuf isn't big enough */
+ (void) ADB_ShiftInData();
+ } else {
+#ifdef _VIA_Debug
+ fprintf(stderr, "*** listen one\n");
+#endif
+ ADB_DatBuf[ADB_IndexDatBuf] = ADB_ShiftInData();
+ ADB_IndexDatBuf += 1;
+ }
+ }
+ break;
+ case 3: /* idle */
+ if (ADB_ListenDatBuf) {
+ ReportAbnormalID(0x0C04, "ADB idle follows listen");
+ /* apparently doesn't happen */
+ }
+ if (ADB_TalkDatBuf) {
+ if (ADB_IndexDatBuf != 0) {
+ ReportAbnormalID(0x0C05,
+ "idle when not done talking");
+ }
+ ADB_ShiftOutData(0xFF);
+ /* ADB_Int = 0; */
+ } else if (CheckForADBanyEvt()) {
+ if (((ADB_CurCmd >> 2) & 3) == 3) {
+ ADB_DoTalk();
+ }
+ ADB_ShiftOutData(0xFF);
+ /* ADB_Int = 0; */
+ }
+ break;
+ }
+ }
+}
+
+GLOBALPROC ADBstate_ChangeNtfy(void)
+{
+#ifdef _VIA_Debug
+ fprintf(stderr, "ADBstate_ChangeNtfy: %d, %d, %d\n",
+ ADB_st1, ADB_st0, GetCuriCount());
+#endif
+ ICT_add(kICT_ADB_NewState,
+ 348160UL * kCycleScale / 64 * kMyClockMult);
+ /*
+ Macintosh Family Hardware Reference say device "must respond
+ to talk command within 260 microseconds", which translates
+ to about 190 instructions. But haven't seen much problems
+ even for very large values (tens of thousands), and do see
+ problems for small values. 50 is definitely too small,
+ mouse doesn't move smoothly. There may still be some
+ signs of this problem with 150.
+
+ On the other hand, how fast the device must respond may
+ not be related to how fast the ADB transceiver responds.
+ */
+}
+
+GLOBALPROC ADB_DataLineChngNtfy(void)
+{
+#ifdef _VIA_Debug
+ fprintf(stderr, "ADB_DataLineChngNtfy: %d\n", ADB_Data);
+#endif
+}
+
+GLOBALPROC ADB_Update(void)
+{
+ ui3b state = ADB_st1 * 2 + ADB_st0;
+
+ if (state == 3) { /* idle */
+ if (ADB_TalkDatBuf) {
+ /* ignore, presumably being taken care of */
+ } else if (CheckForADBanyEvt())
+ {
+ if (((ADB_CurCmd >> 2) & 3) == 3) {
+ ADB_DoTalk();
+ }
+ ADB_ShiftOutData(0xFF);
+ /*
+ Wouldn't expect this would be needed unless
+ there is actually talk data. But without it,
+ ADB never polls the other devices. Clearing
+ ADB_Int has no effect.
+ */
+ /*
+ ADB_Int = 0;
+ seems to have no effect, which probably indicates a bug
+ */
+ }
+ }
+}
--- /dev/null
+++ b/src/ADBEMDEV.h
@@ -1,0 +1,27 @@
+/*
+ ADBEMDEV.h
+
+ Copyright (C) 2008 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef ADBEMDEV_H
+#error "header already included"
+#else
+#define ADBEMDEV_H
+#endif
+
+
+EXPORTPROC ADBstate_ChangeNtfy(void);
+EXPORTPROC ADB_DoNewState(void);
+EXPORTPROC ADB_DataLineChngNtfy(void);
+EXPORTPROC ADB_Update(void);
--- /dev/null
+++ b/src/ADBSHARE.h
@@ -1,0 +1,290 @@
+/*
+ ADBSHARE.h
+
+ Copyright (C) 2008 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Apple Desktop Bus SHAREd code
+ shared by emulation of different implementations of ADB
+*/
+
+#ifdef ADBSHARE_H
+#error "header already included"
+#else
+#define ADBSHARE_H
+#endif
+
+
+/*
+ ReportAbnormalID unused 0x0D08 - 0x0DFF
+*/
+
+#define ADB_MaxSzDatBuf 8
+
+LOCALVAR ui3b ADB_SzDatBuf;
+LOCALVAR blnr ADB_TalkDatBuf = falseblnr;
+LOCALVAR ui3b ADB_DatBuf[ADB_MaxSzDatBuf];
+LOCALVAR ui3b ADB_CurCmd = 0;
+LOCALVAR ui3b NotSoRandAddr = 1;
+
+LOCALVAR ui3b MouseADBAddress;
+LOCALVAR blnr SavedCurMouseButton = falseblnr;
+LOCALVAR ui4r MouseADBDeltaH = 0;
+LOCALVAR ui4r MouseADBDeltaV = 0;
+
+LOCALPROC ADB_DoMouseTalk(void)
+{
+ switch (ADB_CurCmd & 3) {
+ case 0:
+ {
+ MyEvtQEl *p;
+ ui4b partH;
+ ui4b partV;
+ blnr overflow = falseblnr;
+ blnr MouseButtonChange = falseblnr;
+
+ if (nullpr != (p = MyEvtQOutP())) {
+ if (MyEvtQElKindMouseDelta == p->kind) {
+ MouseADBDeltaH += p->u.pos.h;
+ MouseADBDeltaV += p->u.pos.v;
+ MyEvtQOutDone();
+ }
+ }
+ partH = MouseADBDeltaH;
+ partV = MouseADBDeltaV;
+
+ if ((si4b)MouseADBDeltaH < 0) {
+ partH = - partH;
+ }
+ if ((si4b)MouseADBDeltaV < 0) {
+ partV = - partV;
+ }
+ if ((partH >> 6) > 0) {
+ overflow = trueblnr;
+ partH = (1 << 6) - 1;
+ }
+ if ((partV >> 6) > 0) {
+ overflow = trueblnr;
+ partV = (1 << 6) - 1;
+ }
+ if ((si4b)MouseADBDeltaH < 0) {
+ partH = - partH;
+ }
+ if ((si4b)MouseADBDeltaV < 0) {
+ partV = - partV;
+ }
+ MouseADBDeltaH -= partH;
+ MouseADBDeltaV -= partV;
+ if (! overflow) {
+ if (nullpr != (p = MyEvtQOutP())) {
+ if (MyEvtQElKindMouseButton == p->kind) {
+ SavedCurMouseButton = p->u.press.down;
+ MouseButtonChange = trueblnr;
+ MyEvtQOutDone();
+ }
+ }
+ }
+ if ((0 != partH) || (0 != partV) || MouseButtonChange) {
+ ADB_SzDatBuf = 2;
+ ADB_TalkDatBuf = trueblnr;
+ ADB_DatBuf[0] = (SavedCurMouseButton ? 0x00 : 0x80)
+ | (partV & 127);
+ ADB_DatBuf[1] = /* 0x00 */ 0x80 | (partH & 127);
+ }
+ }
+ ADBMouseDisabled = 0;
+ break;
+ case 3:
+ ADB_SzDatBuf = 2;
+ ADB_TalkDatBuf = trueblnr;
+ ADB_DatBuf[0] = 0x60 | (NotSoRandAddr & 0x0f);
+ ADB_DatBuf[1] = 0x01;
+ NotSoRandAddr += 1;
+ break;
+ default:
+ ReportAbnormalID(0x0D01, "Talk to unknown mouse register");
+ break;
+ }
+}
+
+LOCALPROC ADB_DoMouseListen(void)
+{
+ switch (ADB_CurCmd & 3) {
+ case 3:
+ if (ADB_DatBuf[1] == 0xFE) {
+ /* change address */
+ MouseADBAddress = (ADB_DatBuf[0] & 0x0F);
+ } else {
+ ReportAbnormalID(0x0D02,
+ "unknown listen op to mouse register 3");
+ }
+ break;
+ default:
+ ReportAbnormalID(0x0D03,
+ "listen to unknown mouse register");
+ break;
+ }
+}
+
+LOCALVAR ui3b KeyboardADBAddress;
+
+LOCALFUNC blnr CheckForADBkeyEvt(ui3b *NextADBkeyevt)
+{
+ int i;
+ blnr KeyDown;
+
+ if (! FindKeyEvent(&i, &KeyDown)) {
+ return falseblnr;
+ } else {
+#if dbglog_HAVE && 0
+ if (KeyDown) {
+ dbglog_WriteNote("Got a KeyDown");
+ }
+#endif
+ switch (i) {
+ case MKC_Control:
+ i = 0x36;
+ break;
+ case MKC_Left:
+ i = 0x3B;
+ break;
+ case MKC_Right:
+ i = 0x3C;
+ break;
+ case MKC_Down:
+ i = 0x3D;
+ break;
+ case MKC_Up:
+ i = 0x3E;
+ break;
+ default:
+ /* unchanged */
+ break;
+ }
+ *NextADBkeyevt = (KeyDown ? 0x00 : 0x80) | i;
+ return trueblnr;
+ }
+}
+
+LOCALPROC ADB_DoKeyboardTalk(void)
+{
+ switch (ADB_CurCmd & 3) {
+ case 0:
+ {
+ ui3b NextADBkeyevt;
+
+ if (CheckForADBkeyEvt(&NextADBkeyevt)) {
+ ADB_SzDatBuf = 2;
+ ADB_TalkDatBuf = trueblnr;
+ ADB_DatBuf[0] = NextADBkeyevt;
+ if (! CheckForADBkeyEvt(&NextADBkeyevt)) {
+ ADB_DatBuf[1] = 0xFF;
+ } else {
+ ADB_DatBuf[1] = NextADBkeyevt;
+ }
+ }
+ }
+ break;
+ case 3:
+ ADB_SzDatBuf = 2;
+ ADB_TalkDatBuf = trueblnr;
+ ADB_DatBuf[0] = 0x60 | (NotSoRandAddr & 0x0f);
+ ADB_DatBuf[1] = 0x01;
+ NotSoRandAddr += 1;
+ break;
+ default:
+ ReportAbnormalID(0x0D04,
+ "Talk to unknown keyboard register");
+ break;
+ }
+}
+
+LOCALPROC ADB_DoKeyboardListen(void)
+{
+ switch (ADB_CurCmd & 3) {
+ case 3:
+ if (ADB_DatBuf[1] == 0xFE) {
+ /* change address */
+ KeyboardADBAddress = (ADB_DatBuf[0] & 0x0F);
+ } else {
+ ReportAbnormalID(0x0D05,
+ "unknown listen op to keyboard register 3");
+ }
+ break;
+ default:
+ ReportAbnormalID(0x0D06,
+ "listen to unknown keyboard register");
+ break;
+ }
+}
+
+LOCALFUNC blnr CheckForADBanyEvt(void)
+{
+ MyEvtQEl *p = MyEvtQOutP();
+ if (nullpr != p) {
+ switch (p->kind) {
+ case MyEvtQElKindMouseButton:
+ case MyEvtQElKindMouseDelta:
+ case MyEvtQElKindKey:
+ return trueblnr;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return (0 != MouseADBDeltaH) && (0 != MouseADBDeltaV);
+}
+
+LOCALPROC ADB_DoTalk(void)
+{
+ ui3b Address = ADB_CurCmd >> 4;
+ if (Address == MouseADBAddress) {
+ ADB_DoMouseTalk();
+ } else if (Address == KeyboardADBAddress) {
+ ADB_DoKeyboardTalk();
+ }
+}
+
+LOCALPROC ADB_EndListen(void)
+{
+ ui3b Address = ADB_CurCmd >> 4;
+ if (Address == MouseADBAddress) {
+ ADB_DoMouseListen();
+ } else if (Address == KeyboardADBAddress) {
+ ADB_DoKeyboardListen();
+ }
+}
+
+LOCALPROC ADB_DoReset(void)
+{
+ MouseADBAddress = 3;
+ KeyboardADBAddress = 2;
+}
+
+LOCALPROC ADB_Flush(void)
+{
+ ui3b Address = ADB_CurCmd >> 4;
+
+ if ((Address == KeyboardADBAddress)
+ || (Address == MouseADBAddress))
+ {
+ ADB_SzDatBuf = 2;
+ ADB_TalkDatBuf = trueblnr;
+ ADB_DatBuf[0] = 0x00;
+ ADB_DatBuf[1] = 0x00;
+ } else {
+ ReportAbnormalID(0x0D07, "Unhandled ADB Flush");
+ }
+}
--- /dev/null
+++ b/src/ALTKEYSM.h
@@ -1,0 +1,209 @@
+/*
+ ALTKEYSM.h
+
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ ALTernate KEYs Mode
+*/
+
+#ifdef ALTKEYSM_H
+#error "header already included"
+#else
+#define ALTKEYSM_H
+#endif
+
+LOCALVAR blnr AltKeysLockText = falseblnr;
+LOCALVAR blnr AltKeysTrueCmnd = falseblnr;
+LOCALVAR blnr AltKeysTrueOption = falseblnr;
+LOCALVAR blnr AltKeysTrueShift = falseblnr;
+LOCALVAR blnr AltKeysModOn = falseblnr;
+LOCALVAR blnr AltKeysTextOn = falseblnr;
+
+LOCALPROC CheckAltKeyUseMode(void)
+{
+ blnr NewAltKeysTextOn;
+
+ AltKeysModOn = AltKeysTrueCmnd
+ || AltKeysTrueOption || AltKeysTrueShift;
+ NewAltKeysTextOn = AltKeysLockText || AltKeysModOn;
+ if (NewAltKeysTextOn != AltKeysTextOn) {
+ DisconnectKeyCodes(kKeepMaskControl | kKeepMaskCapsLock
+ | (AltKeysTrueCmnd ? kKeepMaskCommand : 0)
+ | (AltKeysTrueOption ? kKeepMaskOption : 0)
+ | (AltKeysTrueShift ? kKeepMaskShift : 0));
+ AltKeysTextOn = NewAltKeysTextOn;
+ }
+}
+
+LOCALPROC Keyboard_UpdateKeyMap1(ui3r key, blnr down)
+{
+ if (MKC_Command == key) {
+ AltKeysTrueCmnd = down;
+ CheckAltKeyUseMode();
+ Keyboard_UpdateKeyMap(key, down);
+ } else if (MKC_Option == key) {
+ AltKeysTrueOption = down;
+ CheckAltKeyUseMode();
+ Keyboard_UpdateKeyMap(key, down);
+ } else if (MKC_Shift == key) {
+ AltKeysTrueShift = down;
+ CheckAltKeyUseMode();
+ Keyboard_UpdateKeyMap(key, down);
+ } else if (MKC_SemiColon == key) {
+ if (down && ! AltKeysModOn) {
+ if (AltKeysLockText) {
+ AltKeysLockText = falseblnr;
+ NeedWholeScreenDraw = trueblnr;
+ SpecialModeClr(SpclModeAltKeyText);
+
+ CheckAltKeyUseMode();
+ }
+ } else {
+ Keyboard_UpdateKeyMap(key, down);
+ }
+ } else if (AltKeysTextOn) {
+ Keyboard_UpdateKeyMap(key, down);
+ } else if (MKC_M == key) {
+ if (down) {
+ if (! AltKeysLockText) {
+ AltKeysLockText = trueblnr;
+ SpecialModeSet(SpclModeAltKeyText);
+ NeedWholeScreenDraw = trueblnr;
+ CheckAltKeyUseMode();
+ }
+ }
+ } else {
+ switch (key) {
+ case MKC_A:
+ key = MKC_SemiColon;
+ break;
+ case MKC_B:
+ key = MKC_BackSlash;
+ break;
+ case MKC_C:
+ key = MKC_F3;
+ break;
+ case MKC_D:
+ key = MKC_Option;
+ break;
+ case MKC_E:
+ key = MKC_BackSpace;
+ break;
+ case MKC_F:
+ key = MKC_Command;
+ break;
+ case MKC_G:
+ key = MKC_Enter;
+ break;
+ case MKC_H:
+ key = MKC_Equal;
+ break;
+ case MKC_I:
+ key = MKC_Up;
+ break;
+ case MKC_J:
+ key = MKC_Left;
+ break;
+ case MKC_K:
+ key = MKC_Down;
+ break;
+ case MKC_L:
+ key = MKC_Right;
+ break;
+ case MKC_M:
+ /* handled above */
+ break;
+ case MKC_N:
+ key = MKC_Minus;
+ break;
+ case MKC_O:
+ key = MKC_RightBracket;
+ break;
+ case MKC_P:
+ return; /* none */
+ break;
+ case MKC_Q:
+ key = MKC_Grave;
+ break;
+ case MKC_R:
+ key = MKC_Return;
+ break;
+ case MKC_S:
+ key = MKC_Shift;
+ break;
+ case MKC_T:
+ key = MKC_Tab;
+ break;
+ case MKC_U:
+ key = MKC_LeftBracket;
+ break;
+ case MKC_V:
+ key = MKC_F4;
+ break;
+ case MKC_W:
+ return; /* none */
+ break;
+ case MKC_X:
+ key = MKC_F2;
+ break;
+ case MKC_Y:
+ key = MKC_Escape;
+ break;
+ case MKC_Z:
+ key = MKC_F1;
+ break;
+ default:
+ break;
+ }
+ Keyboard_UpdateKeyMap(key, down);
+ }
+}
+
+LOCALPROC DisconnectKeyCodes1(ui5b KeepMask)
+{
+ DisconnectKeyCodes(KeepMask);
+
+ if (! (0 != (KeepMask & kKeepMaskCommand))) {
+ AltKeysTrueCmnd = falseblnr;
+ }
+ if (! (0 != (KeepMask & kKeepMaskOption))) {
+ AltKeysTrueOption = falseblnr;
+ }
+ if (! (0 != (KeepMask & kKeepMaskShift))) {
+ AltKeysTrueShift = falseblnr;
+ }
+ AltKeysModOn = AltKeysTrueCmnd
+ || AltKeysTrueOption || AltKeysTrueShift;
+ AltKeysTextOn = AltKeysLockText || AltKeysModOn;
+}
+
+LOCALPROC DrawAltKeyMode(void)
+{
+ int i;
+
+ CurCellv0 = ControlBoxv0;
+ CurCellh0 = ControlBoxh0;
+
+ DrawCellAdvance(kInsertText00);
+ for (i = (ControlBoxw - 4) / 2; --i >= 0; ) {
+ DrawCellAdvance(kInsertText04);
+ }
+ DrawCellAdvance(kInsertText01);
+ DrawCellAdvance(kInsertText02);
+ for (i = (ControlBoxw - 4) / 2; --i >= 0; ) {
+ DrawCellAdvance(kInsertText04);
+ }
+ DrawCellAdvance(kInsertText03);
+}
--- /dev/null
+++ b/src/ASCEMDEV.c
@@ -1,0 +1,868 @@
+/*
+ ASCEMDEV.c
+
+ Copyright (C) 2008 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Apple Sound Chip EMulated DEVice
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+#include "ENDIANAC.h"
+#include "MYOSGLUE.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#include "VIAEMDEV.h"
+#endif
+
+#include "ASCEMDEV.h"
+
+/*
+ ReportAbnormalID unused 0x0F0E, 0x0F1E - 0x0FFF
+*/
+
+LOCALVAR ui3r SoundReg801 = 0;
+LOCALVAR ui3r SoundReg802 = 0;
+LOCALVAR ui3r SoundReg803 = 0;
+LOCALVAR ui3r SoundReg804 = 0;
+LOCALVAR ui3r SoundReg805 = 0;
+LOCALVAR ui3r SoundReg_Volume = 0; /* 0x806 */
+/* LOCALVAR ui3r SoundReg807 = 0; */
+
+LOCALVAR ui3b ASC_SampBuff[0x800];
+
+struct ASC_ChanR {
+ ui3b freq[4];
+ ui3b phase[4];
+};
+typedef struct ASC_ChanR ASC_ChanR;
+
+LOCALVAR ASC_ChanR ASC_ChanA[4];
+
+LOCALVAR ui4b ASC_FIFO_Out = 0;
+LOCALVAR ui4b ASC_FIFO_InA = 0;
+LOCALVAR ui4b ASC_FIFO_InB = 0;
+LOCALVAR blnr ASC_Playing = falseblnr;
+
+#define ASC_dolog (dbglog_HAVE && 0)
+
+#ifdef ASC_interrupt_PulseNtfy
+IMPORTPROC ASC_interrupt_PulseNtfy(void);
+#endif
+
+LOCALPROC ASC_RecalcStatus(void)
+{
+ if ((1 == SoundReg801) && ASC_Playing) {
+ if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x200) {
+ SoundReg804 &= ~ 0x01;
+ } else {
+ SoundReg804 |= 0x01;
+ }
+ if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x400) {
+ SoundReg804 |= 0x02;
+ } else {
+ SoundReg804 &= ~ 0x02;
+ }
+ if (0 != (SoundReg802 & 2)) {
+ if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) >= 0x200) {
+ SoundReg804 &= ~ 0x04;
+ } else {
+ SoundReg804 |= 0x04;
+ }
+ if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) >= 0x400) {
+ SoundReg804 |= 0x08;
+ } else {
+ SoundReg804 &= ~ 0x08;
+ }
+ }
+ }
+}
+
+LOCALPROC ASC_ClearFIFO(void)
+{
+ ASC_FIFO_Out = 0;
+ ASC_FIFO_InA = 0;
+ ASC_FIFO_InB = 0;
+ ASC_Playing = falseblnr;
+ ASC_RecalcStatus();
+}
+
+GLOBALFUNC ui5b ASC_Access(ui5b Data, blnr WriteMem, CPTR addr)
+{
+ if (addr < 0x800) {
+ if (WriteMem) {
+ if (1 == SoundReg801) {
+ if (0 == (addr & 0x400)) {
+ if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x400)
+ {
+#if 0 /* seems to happen in tetris */
+ ReportAbnormalID(0x0F01,
+ "ASC - Channel A Overflow");
+#endif
+ SoundReg804 |= 0x02;
+ } else {
+
+ ASC_SampBuff[ASC_FIFO_InA & 0x3FF] = Data;
+
+ ++ASC_FIFO_InA;
+ if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x200)
+ {
+ if (0 != (SoundReg804 & 0x01)) {
+ /* happens normally */
+ SoundReg804 &= ~ 0x01;
+ }
+ } else {
+#if 0 /* doesn't seem to be necessary, but doesn't hurt either */
+ SoundReg804 |= 0x01;
+#endif
+ }
+ if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x400)
+ {
+ SoundReg804 |= 0x02;
+#if ASC_dolog
+ dbglog_WriteNote("ASC : setting full flag A");
+#endif
+ } else {
+ if (0 != (SoundReg804 & 0x02)) {
+ ReportAbnormalID(0x0F02, "ASC_Access : "
+ "full flag A not already clear");
+ SoundReg804 &= ~ 0x02;
+ }
+ }
+
+ }
+ } else {
+ if (0 == (SoundReg802 & 2)) {
+ ReportAbnormalID(0x0F03,
+ "ASC - Channel B for Mono");
+ }
+ if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) >= 0x400)
+ {
+ ReportAbnormalID(0x0F04,
+ "ASC - Channel B Overflow");
+ SoundReg804 |= 0x08;
+ } else {
+
+ ASC_SampBuff[0x400 + (ASC_FIFO_InB & 0x3FF)] = Data;
+
+ ++ASC_FIFO_InB;
+ if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) >= 0x200)
+ {
+ if (0 != (SoundReg804 & 0x04)) {
+ /* happens normally */
+ SoundReg804 &= ~ 0x04;
+ }
+ } else {
+#if 0 /* doesn't seem to be necessary, but doesn't hurt either */
+ SoundReg804 |= 0x04;
+#endif
+ }
+ if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) >= 0x400)
+ {
+ SoundReg804 |= 0x08;
+#if ASC_dolog
+ dbglog_WriteNote("ASC : setting full flag B");
+#endif
+ } else {
+ if (0 != (SoundReg804 & 0x08)) {
+ ReportAbnormalID(0x0F05, "ASC_Access : "
+ "full flag B not already clear");
+ SoundReg804 &= ~ 0x08;
+ }
+ }
+
+ }
+ }
+#if ASC_dolog && 0
+ dbglog_writeCStr("ASC_InputIndex =");
+ dbglog_writeNum(ASC_InputIndex);
+ dbglog_writeReturn();
+#endif
+ } else {
+ ASC_SampBuff[addr] = Data;
+ }
+ } else {
+ Data = ASC_SampBuff[addr];
+ }
+
+#if ASC_dolog && 1
+#if 0
+ if (((addr & 0x1FF) >= 0x04)
+ && ((addr & 0x1FF) < (0x200 - 0x04)))
+ {
+ /* don't report them all */
+ } else
+#endif
+ {
+ dbglog_AddrAccess("ASC_Access SampBuff",
+ Data, WriteMem, addr);
+ }
+#endif
+ } else if (addr < 0x810) {
+ switch (addr) {
+ case 0x800: /* VERSION */
+ if (WriteMem) {
+ ReportAbnormalID(0x0F06, "ASC - writing VERSION");
+ } else {
+ Data = 0;
+ }
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control (VERSION)",
+ Data, WriteMem, addr);
+#endif
+ break;
+ case 0x801: /* ENABLE */
+ if (WriteMem) {
+ if (1 == Data) {
+ if (1 != SoundReg801) {
+ ASC_ClearFIFO();
+ }
+ } else {
+ if (Data > 2) {
+ ReportAbnormalID(0x0F07,
+ "ASC - unexpected ENABLE");
+ }
+ }
+ SoundReg801 = Data;
+ } else {
+ Data = SoundReg801;
+ /* happens in LodeRunner */
+ }
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control (ENABLE)",
+ Data, WriteMem, addr);
+#endif
+ break;
+ case 0x802: /* CONTROL */
+ if (WriteMem) {
+#if 1
+ if (0 != SoundReg801) {
+ if (SoundReg802 == Data) {
+ /*
+ this happens normally,
+ such as in Lunar Phantom
+ */
+ } else {
+ if (1 == SoundReg801) {
+/*
+ happens in dark castle, if play other sound first,
+ such as by changing beep sound in sound control panel.
+*/
+ ASC_ClearFIFO();
+ }
+
+#if 0
+ ReportAbnormalID(0x0F08,
+ "ASC - changing CONTROL while ENABLEd");
+#endif
+ }
+ }
+#endif
+ if (0 != (Data & ~ 2)) {
+ ReportAbnormalID(0x0F09,
+ "ASC - unexpected CONTROL value");
+ }
+ SoundReg802 = Data;
+ } else {
+ Data = SoundReg802;
+ ReportAbnormalID(0x0F0A,
+ "ASC - reading CONTROL value");
+ }
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control (CONTROL)",
+ Data, WriteMem, addr);
+#endif
+ break;
+ case 0x803:
+ if (WriteMem) {
+ if (0 != (Data & ~ 0x80)) {
+ ReportAbnormalID(0x0F0B,
+ "ASC - unexpected FIFO MODE");
+ }
+ if (0 != (Data & 0x80)) {
+ if (0 != (SoundReg803 & 0x80)) {
+ ReportAbnormalID(0x0F0C,
+ "ASC - set clear FIFO again");
+ } else
+ if (1 != SoundReg801) {
+#if 0 /* happens in system 6, such as with Lunar Phantom */
+ ReportAbnormalID(0x0F0D,
+ "ASC - clear FIFO when not FIFO mode");
+#endif
+ } else
+ {
+ ASC_ClearFIFO();
+ /*
+ ASC_interrupt_PulseNtfy();
+ Doesn't seem to be needed,
+ but doesn't hurt either.
+ */
+ }
+ }
+ SoundReg803 = Data;
+ } else {
+ Data = SoundReg803;
+ }
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control (FIFO MODE)",
+ Data, WriteMem, addr);
+#endif
+ break;
+ case 0x804:
+ if (WriteMem) {
+#if 0
+ if ((0 != SoundReg804) && (0 != Data)) {
+ ReportAbnormalID(0x0F0F,
+ "ASC - set FIFO IRQ STATUS when not 0");
+ }
+#endif
+ SoundReg804 = Data;
+ if (0 != SoundReg804) {
+ ASC_interrupt_PulseNtfy();
+ /*
+ Generating this interrupt seems
+ to be the point of writing to
+ this register.
+ */
+ }
+#if ASC_dolog && 1
+ dbglog_AddrAccess(
+ "ASC_Access Control (FIFO IRQ STATUS)",
+ Data, WriteMem, addr);
+#endif
+ } else {
+ Data = SoundReg804;
+#if 0
+ if (1 != SoundReg801) {
+ /* no, ok, part of normal interrupt handling */
+ ReportAbnormalID(0x0F10,
+ "ASC - read STATUS when not FIFO");
+ }
+#endif
+ /* SoundReg804 = 0; */
+ SoundReg804 &= ~ 0x01;
+ SoundReg804 &= ~ 0x04;
+ /*
+ In lunar phantom, observe checking
+ full flag before first write, but
+ status was read previous.
+ */
+#if ASC_dolog && 1
+#if 0
+ if (0 != Data)
+#endif
+ {
+ dbglog_AddrAccess(
+ "ASC_Access Control (FIFO IRQ STATUS)",
+ Data, WriteMem, addr);
+ }
+#endif
+ }
+ break;
+ case 0x805:
+ if (WriteMem) {
+ SoundReg805 = Data;
+ /* cleared in LodeRunner */
+ } else {
+ Data = SoundReg805;
+ ReportAbnormalID(0x0F11,
+ "ASC - reading WAVE CONTROL register");
+ }
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control (WAVE CONTROL)",
+ Data, WriteMem, addr);
+#endif
+ break;
+ case 0x806: /* VOLUME */
+ if (WriteMem) {
+ SoundReg_Volume = Data >> 5;
+ if (0 != (Data & 0x1F)) {
+ ReportAbnormalID(0x0F12,
+ "ASC - unexpected volume value");
+ }
+ } else {
+ Data = SoundReg_Volume << 5;
+ ReportAbnormalID(0x0F13,
+ "ASC - reading volume register");
+ }
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control (VOLUME)",
+ Data, WriteMem, addr);
+#endif
+ break;
+ case 0x807: /* CLOCK RATE */
+ if (WriteMem) {
+ /* SoundReg807 = Data; */
+ if (0 != Data) {
+ ReportAbnormalID(0x0F14,
+ "ASC - nonstandard CLOCK RATE");
+ }
+ } else {
+ /* Data = SoundReg807; */
+ ReportAbnormalID(0x0F15,
+ "ASC - reading CLOCK RATE");
+ }
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control (CLOCK RATE)",
+ Data, WriteMem, addr);
+#endif
+ break;
+ case 0x808: /* CONTROL */
+ if (WriteMem) {
+ ReportAbnormalID(0x0F16, "ASC - write to 808");
+ } else {
+ /* happens on boot System 7.5.5 */
+ Data = 0;
+ }
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control (CONTROL)",
+ Data, WriteMem, addr);
+#endif
+ break;
+ case 0x80A: /* ? */
+ if (WriteMem) {
+ ReportAbnormalID(0x0F17, "ASC - write to 80A");
+ } else {
+ /*
+ happens in system 6, Lunar Phantom,
+ soon after new game.
+ */
+ Data = 0;
+ }
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control (80A)",
+ Data, WriteMem, addr);
+#endif
+ break;
+ default:
+ if (WriteMem) {
+ } else {
+ Data = 0;
+ }
+ ReportAbnormalID(0x0F18, "ASC - unknown ASC reg");
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control (?)",
+ Data, WriteMem, addr);
+#endif
+ break;
+ }
+ } else if (addr < 0x830) {
+ ui3r b = addr & 3;
+ ui3r chan = ((addr - 0x810) >> 3) & 3;
+
+ if (0 != (addr & 4)) {
+
+ if (WriteMem) {
+ ASC_ChanA[chan].freq[b] = Data;
+ } else {
+ Data = ASC_ChanA[chan].freq[b];
+ }
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control (frequency)",
+ Data, WriteMem, addr);
+#endif
+#if ASC_dolog && 0
+ dbglog_writeCStr("freq b=");
+ dbglog_writeNum(WriteMem);
+ dbglog_writeCStr(", chan=");
+ dbglog_writeNum(chan);
+ dbglog_writeReturn();
+#endif
+ } else {
+
+ if (WriteMem) {
+ ASC_ChanA[chan].phase[b] = Data;
+ } else {
+ Data = ASC_ChanA[chan].phase[b];
+ }
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control (phase)",
+ Data, WriteMem, addr);
+#endif
+ }
+ } else if (addr < 0x838) {
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control *** unknown reg",
+ Data, WriteMem, addr);
+#endif
+ } else {
+#if ASC_dolog && 1
+ dbglog_AddrAccess("ASC_Access Control ? *** unknown reg",
+ Data, WriteMem, addr);
+#endif
+
+ ReportAbnormalID(0x0F19, "unknown ASC reg");
+ }
+
+ return Data;
+}
+
+/*
+ approximate volume levels of vMac, so:
+
+ x * vol_mult[SoundVolume] >> 16
+ + vol_offset[SoundVolume]
+ = {approx} (x - kCenterSound) / (8 - SoundVolume) + kCenterSound;
+*/
+
+LOCALVAR const ui4b vol_mult[] = {
+ 8192, 9362, 10922, 13107, 16384, 21845, 32768
+};
+
+LOCALVAR const trSoundSamp vol_offset[] = {
+#if 3 == kLn2SoundSampSz
+ 112, 110, 107, 103, 96, 86, 64, 0
+#elif 4 == kLn2SoundSampSz
+ 28672, 28087, 27307, 26215, 24576, 21846, 16384, 0
+#else
+#error "unsupported kLn2SoundSampSz"
+#endif
+};
+
+LOCALVAR const ui3r SubTick_n[kNumSubTicks] = {
+ 23, 23, 23, 23, 23, 23, 23, 24,
+ 23, 23, 23, 23, 23, 23, 23, 24
+};
+
+GLOBALPROC ASC_SubTick(int SubTick)
+{
+ ui4r actL;
+#if MySoundEnabled
+ tpSoundSamp p;
+#endif
+ ui4r i;
+ ui4r n = SubTick_n[SubTick];
+#if MySoundEnabled
+ ui3b SoundVolume = SoundReg_Volume;
+#endif
+
+#if MySoundEnabled
+label_retry:
+ p = MySound_BeginWrite(n, &actL);
+#else
+ actL = n;
+#endif
+ if (actL > 0) {
+
+ if (1 == SoundReg801) {
+#if MySoundEnabled
+ ui3p addr;
+#endif
+
+ if (0 != (SoundReg802 & 2)) {
+
+ if (! ASC_Playing) {
+ if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x200) {
+ if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) >= 0x200)
+ {
+ SoundReg804 &= ~ 0x01;
+ SoundReg804 &= ~ 0x04;
+ ASC_Playing = trueblnr;
+#if ASC_dolog
+ dbglog_WriteNote("ASC : start stereo playing");
+#endif
+ } else {
+ if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) == 0)
+ if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out))
+ >= 370)
+ {
+#if ASC_dolog
+ dbglog_WriteNote("ASC : switch to mono");
+#endif
+ SoundReg802 &= ~ 2;
+ /*
+ cludge to get Tetris to work,
+ may not actually work on real machine.
+ */
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < actL; i++) {
+ if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) == 0) {
+ ASC_Playing = falseblnr;
+ }
+ if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) == 0) {
+ ASC_Playing = falseblnr;
+ }
+ if (! ASC_Playing) {
+#if MySoundEnabled
+ *p++ = 0x80;
+#endif
+ } else
+ {
+
+#if MySoundEnabled
+ addr = ASC_SampBuff + (ASC_FIFO_Out & 0x3FF);
+
+#if ASC_dolog && 1
+ dbglog_StartLine();
+ dbglog_writeCStr("out sound ");
+ dbglog_writeCStr("[");
+ dbglog_writeHex(ASC_FIFO_Out);
+ dbglog_writeCStr("]");
+ dbglog_writeCStr(" = ");
+ dbglog_writeHex(*addr);
+ dbglog_writeCStr(" , ");
+ dbglog_writeHex(addr[0x400]);
+ dbglog_writeReturn();
+#endif
+
+ *p++ = ((addr[0] + addr[0x400])
+#if 4 == kLn2SoundSampSz
+ << 8
+#endif
+ ) >> 1;
+#endif /* MySoundEnabled */
+
+ ASC_FIFO_Out += 1;
+
+ }
+ }
+
+ } else {
+
+ /* mono */
+
+ if (! ASC_Playing) {
+ if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x200)
+ {
+ SoundReg804 &= ~ 0x01;
+ ASC_Playing = trueblnr;
+#if ASC_dolog
+ dbglog_WriteNote("ASC : start mono playing");
+#endif
+ }
+ }
+
+ for (i = 0; i < actL; i++) {
+ if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) == 0) {
+ ASC_Playing = falseblnr;
+ }
+ if (! ASC_Playing) {
+#if MySoundEnabled
+ *p++ = 0x80;
+#endif
+ } else
+ {
+
+#if MySoundEnabled
+ addr = ASC_SampBuff + (ASC_FIFO_Out & 0x3FF);
+
+#if ASC_dolog && 1
+ dbglog_StartLine();
+ dbglog_writeCStr("out sound ");
+ dbglog_writeCStr("[");
+ dbglog_writeHex(ASC_FIFO_Out);
+ dbglog_writeCStr("]");
+ dbglog_writeCStr(" = ");
+ dbglog_writeHex(*addr);
+ dbglog_writeCStr(", in buff: ");
+ dbglog_writeHex((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out));
+ dbglog_writeReturn();
+#endif
+
+ *p++ = (addr[0])
+#if 4 == kLn2SoundSampSz
+ << 8
+#endif
+ ;
+#endif /* MySoundEnabled */
+
+ /* Move the address on */
+ /* *addr = 0x80; */
+ /* addr += 2; */
+ ASC_FIFO_Out += 1;
+
+ }
+ }
+
+ }
+ } else if (2 == SoundReg801) {
+#if MySoundEnabled
+ ui4r v;
+ ui4r i0;
+ ui4r i1;
+ ui4r i2;
+ ui4r i3;
+#endif
+ ui5r freq0 = do_get_mem_long(ASC_ChanA[0].freq);
+ ui5r freq1 = do_get_mem_long(ASC_ChanA[1].freq);
+ ui5r freq2 = do_get_mem_long(ASC_ChanA[2].freq);
+ ui5r freq3 = do_get_mem_long(ASC_ChanA[3].freq);
+ ui5r phase0 = do_get_mem_long(ASC_ChanA[0].phase);
+ ui5r phase1 = do_get_mem_long(ASC_ChanA[1].phase);
+ ui5r phase2 = do_get_mem_long(ASC_ChanA[2].phase);
+ ui5r phase3 = do_get_mem_long(ASC_ChanA[3].phase);
+#if ASC_dolog && 1
+ dbglog_writeCStr("freq0=");
+ dbglog_writeNum(freq0);
+ dbglog_writeCStr(", freq1=");
+ dbglog_writeNum(freq1);
+ dbglog_writeCStr(", freq2=");
+ dbglog_writeNum(freq2);
+ dbglog_writeCStr(", freq3=");
+ dbglog_writeNum(freq3);
+ dbglog_writeReturn();
+#endif
+ for (i = 0; i < actL; i++) {
+
+ phase0 += freq0;
+ phase1 += freq1;
+ phase2 += freq2;
+ phase3 += freq3;
+
+#if MySoundEnabled
+
+#if 1
+ i0 = ((phase0 + 0x4000) >> 15) & 0x1FF;
+ i1 = ((phase1 + 0x4000) >> 15) & 0x1FF;
+ i2 = ((phase2 + 0x4000) >> 15) & 0x1FF;
+ i3 = ((phase3 + 0x4000) >> 15) & 0x1FF;
+#else
+ i0 = ((phase0 + 0x8000) >> 16) & 0x1FF;
+ i1 = ((phase1 + 0x8000) >> 16) & 0x1FF;
+ i2 = ((phase2 + 0x8000) >> 16) & 0x1FF;
+ i3 = ((phase3 + 0x8000) >> 16) & 0x1FF;
+#endif
+
+ v = ASC_SampBuff[i0]
+ + ASC_SampBuff[0x0200 + i1]
+ + ASC_SampBuff[0x0400 + i2]
+ + ASC_SampBuff[0x0600 + i3];
+
+#if ASC_dolog && 1
+ dbglog_StartLine();
+ dbglog_writeCStr("i0=");
+ dbglog_writeNum(i0);
+ dbglog_writeCStr(", i1=");
+ dbglog_writeNum(i1);
+ dbglog_writeCStr(", i2=");
+ dbglog_writeNum(i2);
+ dbglog_writeCStr(", i3=");
+ dbglog_writeNum(i3);
+ dbglog_writeCStr(", output sound v=");
+ dbglog_writeNum(v);
+ dbglog_writeReturn();
+#endif
+
+ *p++ = (v >> 2);
+#endif /* MySoundEnabled */
+ }
+
+ do_put_mem_long(ASC_ChanA[0].phase, phase0);
+ do_put_mem_long(ASC_ChanA[1].phase, phase1);
+ do_put_mem_long(ASC_ChanA[2].phase, phase2);
+ do_put_mem_long(ASC_ChanA[3].phase, phase3);
+ } else {
+#if MySoundEnabled
+ for (i = 0; i < actL; i++) {
+ *p++ = kCenterSound;
+ }
+#endif
+ }
+
+
+#if MySoundEnabled
+ if (SoundVolume < 7) {
+ /*
+ Usually have volume at 7, so this
+ is just for completeness.
+ */
+ ui5b mult = (ui5b)vol_mult[SoundVolume];
+ trSoundSamp offset = vol_offset[SoundVolume];
+
+ p -= actL;
+ for (i = 0; i < actL; i++) {
+ *p = (trSoundSamp)((ui5b)(*p) * mult >> 16) + offset;
+ ++p;
+ }
+ }
+
+ MySound_EndWrite(actL);
+ n -= actL;
+ if (n > 0) {
+ goto label_retry;
+ }
+#endif
+ }
+
+#if 1
+ if ((1 == SoundReg801) && ASC_Playing) {
+ if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x200) {
+ if (0 != (SoundReg804 & 0x01)) {
+ ReportAbnormalID(0x0F1A,
+ "half flag A not already clear");
+ SoundReg804 &= ~ 0x01;
+ }
+ } else {
+ if (0 != (SoundReg804 & 0x01)) {
+ /* happens in lode runner */
+ } else {
+#if ASC_dolog
+ dbglog_WriteNote("setting half flag A");
+#endif
+ ASC_interrupt_PulseNtfy();
+ SoundReg804 |= 0x01;
+ }
+ }
+ if (((ui4b)(ASC_FIFO_InA - ASC_FIFO_Out)) >= 0x400) {
+ if (0 == (SoundReg804 & 0x02)) {
+ ReportAbnormalID(0x0F1B, "full flag A not already set");
+ SoundReg804 |= 0x02;
+ }
+ } else {
+ if (0 != (SoundReg804 & 0x02)) {
+ /* ReportAbnormal("full flag A not already clear"); */
+ SoundReg804 &= ~ 0x02;
+ }
+ }
+ if (0 != (SoundReg802 & 2)) {
+ if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) >= 0x200) {
+ if (0 != (SoundReg804 & 0x04)) {
+ ReportAbnormalID(0x0F1C,
+ "half flag B not already clear");
+ SoundReg804 &= ~ 0x04;
+ }
+ } else {
+ if (0 != (SoundReg804 & 0x04)) {
+ /* happens in Lunar Phantom */
+ } else {
+#if ASC_dolog
+ dbglog_WriteNote("setting half flag B");
+#endif
+ ASC_interrupt_PulseNtfy();
+ SoundReg804 |= 0x04;
+ }
+ }
+ if (((ui4b)(ASC_FIFO_InB - ASC_FIFO_Out)) >= 0x400) {
+ if (0 == (SoundReg804 & 0x08)) {
+ ReportAbnormalID(0x0F1D,
+ "full flag B not already set");
+ SoundReg804 |= 0x08;
+ }
+ } else {
+ if (0 != (SoundReg804 & 0x08)) {
+ /*
+ ReportAbnormal("full flag B not already clear");
+ */
+ SoundReg804 &= ~ 0x08;
+ }
+ }
+ }
+ }
+#endif
+}
--- /dev/null
+++ b/src/ASCEMDEV.h
@@ -1,0 +1,24 @@
+/*
+ ASCEMDEV.h
+
+ Copyright (C) 2008 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef ASCEMDEV_H
+#error "header already included"
+#else
+#define ASCEMDEV_H
+#endif
+
+EXPORTFUNC ui5b ASC_Access(ui5b Data, blnr WriteMem, CPTR addr);
+EXPORTPROC ASC_SubTick(int SubTick);
--- /dev/null
+++ b/src/BPFILTER.h
@@ -1,0 +1,365 @@
+/*
+ BPFILTER.h
+
+ Copyright (C) 2012 Michael Fort, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Berkeley Packet Filter for localtalk emulation
+*/
+
+/* BPF and devices */
+static unsigned char device_address[6] = {
+ 0
+};
+static unsigned int device_buffer_size = 0;
+static int fd = -1; /* BPF file descriptor */
+static struct bpf_version bpf_version;
+static struct bpf_program bpf_program;
+static struct bpf_insn insns[] =
+{
+ /* Program for BPF to filter out non-LTOE packets */
+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12),
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x809B, 0, 1),
+ BPF_STMT(BPF_RET + BPF_K, 65535),
+ BPF_STMT(BPF_RET + BPF_K, 0),
+};
+
+GLOBALVAR ui3p LT_TxBuffer = NULL;
+
+/* Transmit state */
+GLOBALVAR ui4r LT_TxBuffSz = 0;
+
+/*
+ Transmit buffer that is reused from tx packet to tx packet.
+ The 's' byte represents the source mac address (ours) and we don't
+ have to initialize it because the MAC device will automatically
+ fill it in for us. The four 'p' bytes represent the process number
+ of this Mini vMac application. It helps differentiate packets
+ between two applications running on the same machine. It is not
+ used at this time. There is a small chance two applications could
+ get the same LLAP/SDLC address to start with and would not work
+ correctly (1 in 254). The 'S' bytes are the size of the LLAP packet
+ since it can be smaller than the minimum sized Ethernet frame.
+ The process number is replaced at initialization. The size is
+ updated just before sending to BPF. All LLAP data is inserted
+ starting at byte 20.
+*/
+static unsigned char tx_buffer[20 + LT_TxBfMxSz] =
+ "\xFF\xFF\xFF\xFF\xFF\xFFssssss\x80\x9BppppSS";
+
+/* Receive state */
+GLOBALVAR ui3p LT_RxBuffer = NULL;
+ /* When data pending, this is used */
+GLOBALVAR ui5r LT_RxBuffSz = 0;
+ /* When data pending, this is used */
+
+/* Macro used by only the get_sockaddrs function for readability. */
+#define ROUNDUP(a, size) \
+ (((a) & ((size) - 1)) ? (1 + ((a) | ((size) - 1))) : (a))
+
+/*
+ Utility function needed for walking the addresses of the
+ kernel route lookup
+*/
+LOCALPROC get_sockaddrs(int addrs, struct sockaddr* sa,
+ struct sockaddr** rti_info)
+{
+ int loop;
+ int incr;
+
+ for (loop = 0; loop < RTAX_MAX; loop++) {
+ if (addrs & (1 << loop)) {
+ rti_info[loop] = sa;
+ incr = sa->sa_len ? ROUNDUP(sa->sa_len, sizeof(uint32_t))
+ : sizeof(uint32_t);
+ sa = (struct sockaddr*)((unsigned long int)sa + incr);
+ } else {
+ rti_info[loop] = NULL;
+ }
+ }
+}
+
+/*
+ This ugly function does a lot of steps to prepare the BPF
+ for our use.
+ 1. Find the ethernet interface that the default route uses.
+ 2. Determine the maximum number of BPF devices can exist.
+ 3. Search for a usable BPF device and open it.
+ 4. Set the BPF device to use our ethernet interface.
+ 5. Get the proper buffer size to use with the BPF device.
+ 6. Set some useful modes of operation on the BPF device.
+ 7. Install a program on the device that filters out non-LTOE
+ packets.
+*/
+
+LOCALFUNC int get_ethernet(void)
+{
+ int result;
+ int size;
+ struct rt_msghdr* message;
+ struct sockaddr_in* addrs;
+ struct sockaddr* sa_list[RTAX_MAX];
+ int loop;
+ char filename[64];
+ struct ifreq ifreq;
+ int enable = 1;
+ struct kinfo_proc kp;
+ size_t len = sizeof(kp);
+ int max = 4;
+
+ char device[32];
+
+ /* Get a socket to routed for IPv4 */
+ fd = socket(PF_ROUTE, SOCK_RAW, AF_INET);
+ if (fd == -1) {
+ return falseblnr;
+ }
+
+ /* Allocate a message */
+ size = sizeof(struct rt_msghdr) + 16 * sizeof(struct sockaddr_in);
+ message = (struct rt_msghdr*)malloc(size);
+ if (! message) {
+ close(fd);
+ return falseblnr;
+ }
+ memset(message, 0, size);
+ addrs = (struct sockaddr_in*)(message + 1);
+
+ /* Fill in the request */
+ message->rtm_msglen = size;
+ message->rtm_version = RTM_VERSION;
+ message->rtm_type = RTM_GET;
+ message->rtm_addrs
+ = RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_IFP | RTA_IFA;
+ addrs->sin_len = sizeof(struct sockaddr_in);
+ addrs->sin_family = AF_INET;
+ addrs->sin_addr.s_addr = 0; /* 0.0.0.0 is default route */
+
+ /* Send the message to the kernel */
+ result = write(fd, message, size);
+ if (result < 0) {
+ close(fd);
+ free(message);
+ return falseblnr;
+ }
+
+ /* Read the result from the kernel */
+ result = read(fd, message, size);
+ if (result < 0) {
+ close(fd);
+ free(message);
+ return falseblnr;
+ }
+
+ /* Close the route socket */
+ close(fd);
+
+ /* Get pointer to the result then parse it */
+ struct sockaddr* sa = (struct sockaddr*)
+ ((unsigned long int)message + sizeof(struct rt_msghdr));
+ get_sockaddrs(message->rtm_addrs, sa, sa_list);
+
+ /* Must have a LINK (Ethernet) */
+ if ((! sa_list[RTAX_IFP])
+ || (sa_list[RTAX_IFP]->sa_family != AF_LINK))
+ {
+ return falseblnr;
+ }
+
+ int namelen = ((struct sockaddr_dl*)sa_list[RTAX_IFP])->sdl_nlen;
+#if 0
+ int addrlen = ((struct sockaddr_dl*)sa_list[RTAX_IFP])->sdl_alen;
+#endif
+
+ strncpy(device,
+ &((struct sockaddr_dl*)sa_list[RTAX_IFP])->sdl_data[0],
+ namelen);
+ device[namelen] = 0;
+ memcpy(device_address,
+ &((struct sockaddr_dl*)sa_list[RTAX_IFP])->sdl_data[namelen],
+ 6);
+ memcpy(&(tx_buffer[6]),
+ &((struct sockaddr_dl*)sa_list[RTAX_IFP])->sdl_data[namelen],
+ 6);
+
+ result = sysctlbyname("debug.bpf_maxdevices", &kp, &len, NULL, 0);
+ if (result == -1) {
+ return falseblnr;
+ }
+ max = *((int *)&kp);
+
+ for (loop = 0; loop < max; loop++) {
+ sprintf(filename, "/dev/bpf%d", loop);
+ fd = open(filename, O_RDWR | O_NONBLOCK | O_EXLOCK);
+ if (fd >= 0) {
+ /* sprintf(buffer, "using %s\n", filename); */
+ break;
+ }
+ }
+
+ if (fd <= 0) {
+ return falseblnr;
+ }
+
+ memset(&ifreq, 0, sizeof(struct ifreq));
+ strncpy(ifreq.ifr_name, device, IFNAMSIZ);
+ result = ioctl(fd, BIOCSETIF, &ifreq);
+ if (result) {
+ return falseblnr;
+ }
+
+ result = ioctl(fd, BIOCGBLEN, &device_buffer_size);
+ if (result) {
+ return falseblnr;
+ }
+
+ result = ioctl(fd, BIOCPROMISC, &enable);
+ if (result) {
+ return falseblnr;
+ }
+
+ result = ioctl(fd, BIOCSSEESENT, &enable);
+ if (result) {
+ return falseblnr;
+ }
+
+ result = ioctl(fd, BIOCSHDRCMPLT, &enable);
+ if (result) {
+ return falseblnr;
+ }
+
+ result = ioctl(fd, BIOCIMMEDIATE, &enable);
+ if (result) {
+ return falseblnr;
+ }
+
+ result = ioctl(fd, BIOCVERSION, &bpf_version);
+ if (result) {
+ return falseblnr;
+ }
+
+ bpf_program.bf_len = 4;
+ bpf_program.bf_insns = insns;
+
+ result = ioctl(fd, BIOCSETF, &bpf_program);
+ if (result) {
+ return falseblnr;
+ }
+
+ return trueblnr;
+}
+
+LOCALVAR unsigned char *MyRxBuffer = NULL;
+
+/*
+ External function needed at startup to initialize the LocalTalk
+ functionality.
+*/
+LOCALFUNC int InitLocalTalk(void)
+{
+ /* Perform a lot of stuff to get access to the Ethernet */
+ get_ethernet();
+
+ /*
+ Save the process id in the transmit buffer as it may be used
+ later to uniquely identify the sender to identify collisions
+ in dynamic llap node address assignment.
+ */
+ *((uint32_t*)(&tx_buffer[14])) = htonl(getpid());
+
+ LT_TxBuffer = (ui3p)&tx_buffer[20];
+
+ MyRxBuffer = malloc(device_buffer_size);
+ if (NULL == MyRxBuffer) {
+ return falseblnr;
+ }
+
+ /* Initialized properly */
+ return trueblnr;
+}
+
+GLOBALOSGLUPROC LT_TransmitPacket(void)
+{
+ int count;
+
+ /*
+ Write the length in the packet. This is needed because
+ Ethernet has a minimum 60 bytes length, which the MAC chip
+ will enforce on TX. Without the size, a simple 3 byte LLAP
+ packet would look like a (60 - 14 =) 46 byte LLAP packet.
+ */
+ *((uint16_t*)(&tx_buffer[18])) = htons(LT_TxBuffSz);
+
+ /* Send the packet to Ethernet */
+ count = write(fd, tx_buffer, 20 + LT_TxBuffSz);
+
+ (void)count; /* unused */
+}
+
+LOCALVAR unsigned char* NextPacket = NULL;
+LOCALVAR unsigned char* EndPackets = NULL;
+
+LOCALPROC LocalTalkTick0(void)
+{
+ /* Get a single buffer worth of packets from BPF */
+ unsigned char* device_buffer = MyRxBuffer;
+ int bytes = read(fd, device_buffer, device_buffer_size);
+ if (bytes > 0) {
+ /* Maybe multiple packets in this buffer */
+#if 0
+ dbglog_WriteNote("SCC founds packets from BPF");
+#endif
+ NextPacket = device_buffer;
+ EndPackets = device_buffer + bytes;
+ }
+}
+
+GLOBALOSGLUPROC LT_ReceivePacket(void)
+{
+label_retry:
+ if (NextPacket == NULL) {
+ LocalTalkTick0();
+ if (NextPacket != NULL) {
+ goto label_retry;
+ }
+ } else if (NextPacket >= EndPackets) {
+#if 0
+ dbglog_WriteNote("SCC finished set of packets from BPF");
+#endif
+ NextPacket = NULL;
+ goto label_retry;
+ } else {
+ unsigned char* packet = NextPacket;
+ /* Get pointer to BPF header */
+ struct bpf_hdr* header = (struct bpf_hdr *)packet;
+
+ /* Advance to next packet in buffer */
+ NextPacket += BPF_WORDALIGN(header->bh_hdrlen
+ + header->bh_caplen);
+
+ /* Get clean references to data */
+ int ethernet_length = header->bh_caplen - 14;
+ int llap_length = htons(*((uint16_t*)(packet
+ + header->bh_hdrlen + 18)));
+ unsigned char* start = packet + header->bh_hdrlen + 20;
+
+ if (llap_length <= ethernet_length) {
+ /* Start the receiver */
+ LT_RxBuffer = (ui3p)start;
+ LT_RxBuffSz = llap_length;
+ } else {
+ goto label_retry;
+ }
+ }
+}
--- /dev/null
+++ b/src/COMOSGLU.h
@@ -1,0 +1,1219 @@
+/*
+ COMOSGLU.h
+
+ Copyright (C) 2009 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ COMmon code for Operating System GLUe
+*/
+
+#if EnableMouseMotion && MayFullScreen
+#define EnableFSMouseMotion 1
+#else
+#define EnableFSMouseMotion 0
+#endif
+
+#if EnableMagnify || VarFullScreen
+#define EnableRecreateW 1
+#else
+#define EnableRecreateW 0
+#endif
+
+#if EnableRecreateW || EnableFSMouseMotion
+#define EnableMoveMouse 1
+#else
+#define EnableMoveMouse 0
+#endif
+
+GLOBALVAR ui3p ROM = nullpr;
+LOCALVAR blnr ROM_loaded = falseblnr;
+
+GLOBALVAR ui5b vSonyWritableMask = 0;
+GLOBALVAR ui5b vSonyInsertedMask = 0;
+
+#if IncludeSonyRawMode
+GLOBALVAR blnr vSonyRawMode = falseblnr;
+#endif
+
+#if IncludeSonyNew
+GLOBALVAR blnr vSonyNewDiskWanted = falseblnr;
+GLOBALVAR ui5b vSonyNewDiskSize;
+#endif
+
+#if IncludeSonyNameNew
+GLOBALVAR tPbuf vSonyNewDiskName = NotAPbuf;
+#endif
+
+GLOBALVAR ui5b CurMacDateInSeconds = 0;
+#if AutoLocation
+GLOBALVAR ui5b CurMacLatitude = 0;
+GLOBALVAR ui5b CurMacLongitude = 0;
+#endif
+#if AutoTimeZone
+GLOBALVAR ui5b CurMacDelta = 0;
+#endif
+
+#if 0 != vMacScreenDepth
+GLOBALVAR blnr UseColorMode = falseblnr;
+GLOBALVAR blnr ColorModeWorks = falseblnr;
+#endif
+
+#if 0 != vMacScreenDepth
+GLOBALVAR blnr ColorMappingChanged = falseblnr;
+#endif
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+GLOBALVAR ui4r CLUT_reds[CLUT_size];
+GLOBALVAR ui4r CLUT_greens[CLUT_size];
+GLOBALVAR ui4r CLUT_blues[CLUT_size];
+#endif
+
+LOCALVAR blnr RequestMacOff = falseblnr;
+
+GLOBALVAR blnr ForceMacOff = falseblnr;
+
+GLOBALVAR blnr WantMacInterrupt = falseblnr;
+
+GLOBALVAR blnr WantMacReset = falseblnr;
+
+GLOBALVAR ui3b SpeedValue = WantInitSpeedValue;
+
+#if EnableAutoSlow
+GLOBALVAR blnr WantNotAutoSlow = (WantInitNotAutoSlow != 0);
+#endif
+
+GLOBALVAR ui4b CurMouseV = 0;
+GLOBALVAR ui4b CurMouseH = 0;
+
+#if EnableFSMouseMotion
+LOCALVAR blnr HaveMouseMotion = falseblnr;
+#endif
+
+#if EnableAutoSlow
+GLOBALVAR ui5r QuietTime = 0;
+GLOBALVAR ui5r QuietSubTicks = 0;
+#endif
+
+#ifndef GrabKeysFullScreen
+#define GrabKeysFullScreen 1
+#endif
+
+#ifndef GrabKeysMaxFullScreen
+#define GrabKeysMaxFullScreen 0
+#endif
+
+#if IncludePbufs
+LOCALVAR ui5b PbufAllocatedMask;
+LOCALVAR ui5b PbufSize[NumPbufs];
+#endif
+
+#if IncludePbufs
+#define PbufIsAllocated(i) ((PbufAllocatedMask & ((ui5b)1 << (i))) != 0)
+#endif
+
+#if IncludePbufs
+LOCALFUNC blnr FirstFreePbuf(tPbuf *r)
+{
+ tPbuf i;
+
+ for (i = 0; i < NumPbufs; ++i) {
+ if (! PbufIsAllocated(i)) {
+ *r = i;
+ return trueblnr;
+ }
+ }
+ return falseblnr;
+}
+#endif
+
+#if IncludePbufs
+LOCALPROC PbufNewNotify(tPbuf Pbuf_No, ui5b count)
+{
+ PbufSize[Pbuf_No] = count;
+ PbufAllocatedMask |= ((ui5b)1 << Pbuf_No);
+}
+#endif
+
+#if IncludePbufs
+LOCALPROC PbufDisposeNotify(tPbuf Pbuf_No)
+{
+ PbufAllocatedMask &= ~ ((ui5b)1 << Pbuf_No);
+}
+#endif
+
+#if IncludePbufs
+GLOBALOSGLUFUNC tMacErr CheckPbuf(tPbuf Pbuf_No)
+{
+ tMacErr result;
+
+ if (Pbuf_No >= NumPbufs) {
+ result = mnvm_nsDrvErr;
+ } else if (! PbufIsAllocated(Pbuf_No)) {
+ result = mnvm_offLinErr;
+ } else {
+ result = mnvm_noErr;
+ }
+
+ return result;
+}
+#endif
+
+#if IncludePbufs
+GLOBALOSGLUFUNC tMacErr PbufGetSize(tPbuf Pbuf_No, ui5r *Count)
+{
+ tMacErr result = CheckPbuf(Pbuf_No);
+
+ if (mnvm_noErr == result) {
+ *Count = PbufSize[Pbuf_No];
+ }
+
+ return result;
+}
+#endif
+
+LOCALFUNC blnr FirstFreeDisk(tDrive *Drive_No)
+{
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ if (! vSonyIsInserted(i)) {
+ if (nullpr != Drive_No) {
+ *Drive_No = i;
+ }
+ return trueblnr;
+ }
+ }
+ return falseblnr;
+}
+
+GLOBALOSGLUFUNC blnr AnyDiskInserted(void)
+{
+#if 0
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ if (vSonyIsInserted(i)) {
+ return trueblnr;
+ }
+ }
+ return falseblnr;
+#endif
+ return 0 != vSonyInsertedMask;
+}
+
+GLOBALOSGLUPROC DiskRevokeWritable(tDrive Drive_No)
+{
+ vSonyWritableMask &= ~ ((ui5b)1 << Drive_No);
+}
+
+LOCALPROC DiskInsertNotify(tDrive Drive_No, blnr locked)
+{
+ vSonyInsertedMask |= ((ui5b)1 << Drive_No);
+ if (! locked) {
+ vSonyWritableMask |= ((ui5b)1 << Drive_No);
+ }
+
+ QuietEnds();
+}
+
+LOCALPROC DiskEjectedNotify(tDrive Drive_No)
+{
+ vSonyWritableMask &= ~ ((ui5b)1 << Drive_No);
+ vSonyInsertedMask &= ~ ((ui5b)1 << Drive_No);
+}
+
+/*
+ block type - for operating on multiple ui3b elements
+ at a time.
+*/
+
+#if LittleEndianUnaligned || BigEndianUnaligned
+
+#define uibb ui5b
+#define uibr ui5r
+#define ln2uiblockn 2
+
+#if 0
+#define uibb long long
+#define uibr long long
+#define ln2uiblockn 3
+#endif
+
+#else
+
+#define uibb ui3b
+#define uibr ui3r
+#define ln2uiblockn 0
+
+#endif
+
+#define uiblockn (1 << ln2uiblockn)
+#define ln2uiblockbitsn (3 + ln2uiblockn)
+#define uiblockbitsn (8 * uiblockn)
+
+LOCALFUNC blnr FindFirstChangeInLVecs(uibb *ptr1, uibb *ptr2,
+ uimr L, uimr *j)
+{
+/*
+ find index of first difference
+*/
+ uibb *p1 = ptr1;
+ uibb *p2 = ptr2;
+ uimr i;
+
+ for (i = L; i != 0; --i) {
+ if (*p1++ != *p2++) {
+ --p1;
+ *j = p1 - ptr1;
+ return trueblnr;
+ }
+ }
+ return falseblnr;
+}
+
+LOCALPROC FindLastChangeInLVecs(uibb *ptr1, uibb *ptr2,
+ uimr L, uimr *j)
+{
+/*
+ find index of last difference, assuming there is one
+*/
+ uibb *p1 = ptr1 + L;
+ uibb *p2 = ptr2 + L;
+
+ while (*--p1 == *--p2) {
+ }
+ *j = p1 - ptr1;
+}
+
+LOCALPROC FindLeftRightChangeInLMat(uibb *ptr1, uibb *ptr2,
+ uimr width, uimr top, uimr bottom,
+ uimr *LeftMin0, uibr *LeftMask0,
+ uimr *RightMax0, uibr *RightMask0)
+{
+ uimr i;
+ uimr j;
+ uibb *p1;
+ uibb *p2;
+ uibr x;
+ ui5r offset = top * width;
+ uibb *p10 = (uibb *)ptr1 + offset;
+ uibb *p20 = (uibb *)ptr2 + offset;
+ uimr LeftMin = *LeftMin0;
+ uimr RightMax = *RightMax0;
+ uibr LeftMask = 0;
+ uibr RightMask = 0;
+ for (i = top; i < bottom; ++i) {
+ p1 = p10;
+ p2 = p20;
+ for (j = 0; j < LeftMin; ++j) {
+ x = *p1++ ^ *p2++;
+ if (0 != x) {
+ LeftMin = j;
+ LeftMask = x;
+ goto Label_3;
+ }
+ }
+ LeftMask |= (*p1 ^ *p2);
+Label_3:
+ p1 = p10 + RightMax;
+ p2 = p20 + RightMax;
+ RightMask |= (*p1++ ^ *p2++);
+ for (j = RightMax + 1; j < width; ++j) {
+ x = *p1++ ^ *p2++;
+ if (0 != x) {
+ RightMax = j;
+ RightMask = x;
+ }
+ }
+
+ p10 += width;
+ p20 += width;
+ }
+ *LeftMin0 = LeftMin;
+ *RightMax0 = RightMax;
+ *LeftMask0 = LeftMask;
+ *RightMask0 = RightMask;
+}
+
+LOCALVAR ui3p screencomparebuff = nullpr;
+
+LOCALVAR uimr NextDrawRow = 0;
+
+
+#if BigEndianUnaligned
+
+#define FlipCheckMonoBits (uiblockbitsn - 1)
+
+#else
+
+#define FlipCheckMonoBits 7
+
+#endif
+
+#define FlipCheckBits (FlipCheckMonoBits >> vMacScreenDepth)
+
+#ifndef WantColorTransValid
+#define WantColorTransValid 0
+#endif
+
+#if WantColorTransValid
+LOCALVAR blnr ColorTransValid = falseblnr;
+#endif
+
+LOCALFUNC blnr ScreenFindChanges(ui3p screencurrentbuff,
+ si3b TimeAdjust, si4b *top, si4b *left, si4b *bottom, si4b *right)
+{
+ uimr j0;
+ uimr j1;
+ uimr j0h;
+ uimr j1h;
+ uimr j0v;
+ uimr j1v;
+ uimr copysize;
+ uimr copyoffset;
+ uimr copyrows;
+ uimr LimitDrawRow;
+ uimr MaxRowsDrawnPerTick;
+ uimr LeftMin;
+ uimr RightMax;
+ uibr LeftMask;
+ uibr RightMask;
+ int j;
+
+ if (TimeAdjust < 4) {
+ MaxRowsDrawnPerTick = vMacScreenHeight;
+ } else if (TimeAdjust < 6) {
+ MaxRowsDrawnPerTick = vMacScreenHeight / 2;
+ } else {
+ MaxRowsDrawnPerTick = vMacScreenHeight / 4;
+ }
+
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+ if (ColorMappingChanged) {
+ ColorMappingChanged = falseblnr;
+ j0h = 0;
+ j1h = vMacScreenWidth;
+ j0v = 0;
+ j1v = vMacScreenHeight;
+#if WantColorTransValid
+ ColorTransValid = falseblnr;
+#endif
+ } else {
+ if (! FindFirstChangeInLVecs(
+ (uibb *)screencurrentbuff
+ + NextDrawRow * (vMacScreenBitWidth / uiblockbitsn),
+ (uibb *)screencomparebuff
+ + NextDrawRow * (vMacScreenBitWidth / uiblockbitsn),
+ ((uimr)(vMacScreenHeight - NextDrawRow)
+ * (uimr)vMacScreenBitWidth) / uiblockbitsn,
+ &j0))
+ {
+ NextDrawRow = 0;
+ return falseblnr;
+ }
+ j0v = j0 / (vMacScreenBitWidth / uiblockbitsn);
+ j0h = j0 - j0v * (vMacScreenBitWidth / uiblockbitsn);
+ j0v += NextDrawRow;
+ LimitDrawRow = j0v + MaxRowsDrawnPerTick;
+ if (LimitDrawRow >= vMacScreenHeight) {
+ LimitDrawRow = vMacScreenHeight;
+ NextDrawRow = 0;
+ } else {
+ NextDrawRow = LimitDrawRow;
+ }
+ FindLastChangeInLVecs((uibb *)screencurrentbuff,
+ (uibb *)screencomparebuff,
+ ((uimr)LimitDrawRow
+ * (uimr)vMacScreenBitWidth) / uiblockbitsn,
+ &j1);
+ j1v = j1 / (vMacScreenBitWidth / uiblockbitsn);
+ j1h = j1 - j1v * (vMacScreenBitWidth / uiblockbitsn);
+ j1v++;
+
+ if (j0h < j1h) {
+ LeftMin = j0h;
+ RightMax = j1h;
+ } else {
+ LeftMin = j1h;
+ RightMax = j0h;
+ }
+
+ FindLeftRightChangeInLMat((uibb *)screencurrentbuff,
+ (uibb *)screencomparebuff,
+ (vMacScreenBitWidth / uiblockbitsn),
+ j0v, j1v, &LeftMin, &LeftMask, &RightMax, &RightMask);
+
+#if vMacScreenDepth > ln2uiblockbitsn
+ j0h = (LeftMin >> (vMacScreenDepth - ln2uiblockbitsn));
+#elif ln2uiblockbitsn > vMacScreenDepth
+ for (j = 0; j < (1 << (ln2uiblockbitsn - vMacScreenDepth));
+ ++j)
+ {
+ if (0 != (LeftMask
+ & (((((uibr)1) << (1 << vMacScreenDepth)) - 1)
+ << ((j ^ FlipCheckBits) << vMacScreenDepth))))
+ {
+ goto Label_1c;
+ }
+ }
+Label_1c:
+ j0h = (LeftMin << (ln2uiblockbitsn - vMacScreenDepth)) + j;
+#else
+ j0h = LeftMin;
+#endif
+
+#if vMacScreenDepth > ln2uiblockbitsn
+ j1h = (RightMax >> (vMacScreenDepth - ln2uiblockbitsn)) + 1;
+#elif ln2uiblockbitsn > vMacScreenDepth
+ for (j = (uiblockbitsn >> vMacScreenDepth); --j >= 0; ) {
+ if (0 != (RightMask
+ & (((((uibr)1) << (1 << vMacScreenDepth)) - 1)
+ << ((j ^ FlipCheckBits) << vMacScreenDepth))))
+ {
+ goto Label_2c;
+ }
+ }
+Label_2c:
+ j1h = (RightMax << (ln2uiblockbitsn - vMacScreenDepth))
+ + j + 1;
+#else
+ j1h = RightMax + 1;
+#endif
+ }
+
+ copyrows = j1v - j0v;
+ copyoffset = j0v * vMacScreenByteWidth;
+ copysize = copyrows * vMacScreenByteWidth;
+ } else
+#endif
+ {
+#if 0 != vMacScreenDepth
+ if (ColorMappingChanged) {
+ ColorMappingChanged = falseblnr;
+ j0h = 0;
+ j1h = vMacScreenWidth;
+ j0v = 0;
+ j1v = vMacScreenHeight;
+#if WantColorTransValid
+ ColorTransValid = falseblnr;
+#endif
+ } else
+#endif
+ {
+ if (! FindFirstChangeInLVecs(
+ (uibb *)screencurrentbuff
+ + NextDrawRow * (vMacScreenWidth / uiblockbitsn),
+ (uibb *)screencomparebuff
+ + NextDrawRow * (vMacScreenWidth / uiblockbitsn),
+ ((uimr)(vMacScreenHeight - NextDrawRow)
+ * (uimr)vMacScreenWidth) / uiblockbitsn,
+ &j0))
+ {
+ NextDrawRow = 0;
+ return falseblnr;
+ }
+ j0v = j0 / (vMacScreenWidth / uiblockbitsn);
+ j0h = j0 - j0v * (vMacScreenWidth / uiblockbitsn);
+ j0v += NextDrawRow;
+ LimitDrawRow = j0v + MaxRowsDrawnPerTick;
+ if (LimitDrawRow >= vMacScreenHeight) {
+ LimitDrawRow = vMacScreenHeight;
+ NextDrawRow = 0;
+ } else {
+ NextDrawRow = LimitDrawRow;
+ }
+ FindLastChangeInLVecs((uibb *)screencurrentbuff,
+ (uibb *)screencomparebuff,
+ ((uimr)LimitDrawRow
+ * (uimr)vMacScreenWidth) / uiblockbitsn,
+ &j1);
+ j1v = j1 / (vMacScreenWidth / uiblockbitsn);
+ j1h = j1 - j1v * (vMacScreenWidth / uiblockbitsn);
+ j1v++;
+
+ if (j0h < j1h) {
+ LeftMin = j0h;
+ RightMax = j1h;
+ } else {
+ LeftMin = j1h;
+ RightMax = j0h;
+ }
+
+ FindLeftRightChangeInLMat((uibb *)screencurrentbuff,
+ (uibb *)screencomparebuff,
+ (vMacScreenWidth / uiblockbitsn),
+ j0v, j1v, &LeftMin, &LeftMask, &RightMax, &RightMask);
+
+ for (j = 0; j < uiblockbitsn; ++j) {
+ if (0 != (LeftMask
+ & (((uibr)1) << (j ^ FlipCheckMonoBits))))
+ {
+ goto Label_1;
+ }
+ }
+Label_1:
+ j0h = LeftMin * uiblockbitsn + j;
+
+ for (j = uiblockbitsn; --j >= 0; ) {
+ if (0 != (RightMask
+ & (((uibr)1) << (j ^ FlipCheckMonoBits))))
+ {
+ goto Label_2;
+ }
+ }
+Label_2:
+ j1h = RightMax * uiblockbitsn + j + 1;
+ }
+
+ copyrows = j1v - j0v;
+ copyoffset = j0v * vMacScreenMonoByteWidth;
+ copysize = copyrows * vMacScreenMonoByteWidth;
+ }
+
+ MyMoveBytes((anyp)screencurrentbuff + copyoffset,
+ (anyp)screencomparebuff + copyoffset,
+ copysize);
+
+ *top = j0v;
+ *left = j0h;
+ *bottom = j1v;
+ *right = j1h;
+
+ return trueblnr;
+}
+
+GLOBALVAR blnr EmVideoDisable = falseblnr;
+GLOBALVAR si3b EmLagTime = 0;
+
+GLOBALVAR ui5b OnTrueTime = 0;
+ /*
+ The time slice we are currently dealing
+ with, in the same units as TrueEmulatedTime.
+ */
+
+LOCALVAR si4b ScreenChangedTop;
+LOCALVAR si4b ScreenChangedLeft;
+LOCALVAR si4b ScreenChangedBottom;
+LOCALVAR si4b ScreenChangedRight;
+
+LOCALPROC ScreenClearChanges(void)
+{
+ ScreenChangedTop = vMacScreenHeight;
+ ScreenChangedBottom = 0;
+ ScreenChangedLeft = vMacScreenWidth;
+ ScreenChangedRight = 0;
+}
+
+LOCALPROC ScreenChangedAll(void)
+{
+ ScreenChangedTop = 0;
+ ScreenChangedBottom = vMacScreenHeight;
+ ScreenChangedLeft = 0;
+ ScreenChangedRight = vMacScreenWidth;
+}
+
+#if EnableAutoSlow
+LOCALVAR si4b ScreenChangedQuietTop = vMacScreenHeight;
+LOCALVAR si4b ScreenChangedQuietLeft = vMacScreenWidth;
+LOCALVAR si4b ScreenChangedQuietBottom = 0;
+LOCALVAR si4b ScreenChangedQuietRight = 0;
+#endif
+
+GLOBALOSGLUPROC Screen_OutputFrame(ui3p screencurrentbuff)
+{
+ si4b top;
+ si4b left;
+ si4b bottom;
+ si4b right;
+
+ if (! EmVideoDisable) {
+ if (ScreenFindChanges(screencurrentbuff, EmLagTime,
+ &top, &left, &bottom, &right))
+ {
+ if (top < ScreenChangedTop) {
+ ScreenChangedTop = top;
+ }
+ if (bottom > ScreenChangedBottom) {
+ ScreenChangedBottom = bottom;
+ }
+ if (left < ScreenChangedLeft) {
+ ScreenChangedLeft = left;
+ }
+ if (right > ScreenChangedRight) {
+ ScreenChangedRight = right;
+ }
+
+#if EnableAutoSlow
+ if (top < ScreenChangedQuietTop) {
+ ScreenChangedQuietTop = top;
+ }
+ if (bottom > ScreenChangedQuietBottom) {
+ ScreenChangedQuietBottom = bottom;
+ }
+ if (left < ScreenChangedQuietLeft) {
+ ScreenChangedQuietLeft = left;
+ }
+ if (right > ScreenChangedQuietRight) {
+ ScreenChangedQuietRight = right;
+ }
+
+ if (((ScreenChangedQuietRight - ScreenChangedQuietLeft) > 1)
+ || ((ScreenChangedQuietBottom
+ - ScreenChangedQuietTop) > 32))
+ {
+ ScreenChangedQuietTop = vMacScreenHeight;
+ ScreenChangedQuietLeft = vMacScreenWidth;
+ ScreenChangedQuietBottom = 0;
+ ScreenChangedQuietRight = 0;
+
+ QuietEnds();
+ }
+#endif
+ }
+ }
+}
+
+#if MayFullScreen
+LOCALVAR ui4r ViewHSize;
+LOCALVAR ui4r ViewVSize;
+LOCALVAR ui4r ViewHStart = 0;
+LOCALVAR ui4r ViewVStart = 0;
+#if EnableFSMouseMotion
+LOCALVAR si4b SavedMouseH;
+LOCALVAR si4b SavedMouseV;
+#endif
+#endif
+
+#ifndef WantAutoScrollBorder
+#define WantAutoScrollBorder 0
+#endif
+
+#if EnableFSMouseMotion
+LOCALPROC AutoScrollScreen(void)
+{
+ si4b Shift;
+ si4b Limit;
+
+ /*
+ Scroll in multiples of two pixels, so as to
+ work better with the common gray pattern.
+ ViewHSize and ViewVSize are constrained
+ to a multiple of two.
+
+ Mac OS (some versions at least) constrains
+ the mouse position to be less than the screen
+ height and width, not allowing equal to it.
+ Can still scroll to see last pixel because
+ scroll in multiples of two pixels.
+ */
+
+ if (vMacScreenWidth != ViewHSize) {
+ Shift = 0;
+ Limit = ViewHStart
+#if WantAutoScrollBorder
+ + (ViewHSize / 16)
+#endif
+ ;
+ if (CurMouseH < Limit) {
+ Shift = (Limit - CurMouseH + 1) & (~ 1);
+ Limit = ViewHStart;
+ if (Shift >= Limit) {
+ Shift = Limit;
+ }
+ Shift = - Shift;
+ } else {
+ Limit = ViewHStart + ViewHSize
+#if WantAutoScrollBorder
+ - (ViewHSize / 16)
+#endif
+ ;
+ if (CurMouseH > Limit) {
+ Shift = (CurMouseH - Limit + 1) & (~ 1);
+ Limit = vMacScreenWidth - ViewHSize - ViewHStart;
+ if (Shift >= Limit) {
+ Shift = Limit;
+ }
+ }
+ }
+
+ if (Shift != 0) {
+ ViewHStart += Shift;
+ SavedMouseH += Shift;
+ ScreenChangedAll();
+ }
+ }
+
+ if (vMacScreenHeight != ViewVSize) {
+ Shift = 0;
+ Limit = ViewVStart
+#if WantAutoScrollBorder
+ + (ViewVSize / 16)
+#endif
+ ;
+ if (CurMouseV < Limit) {
+ Shift = (Limit - CurMouseV + 1) & (~ 1);
+ Limit = ViewVStart;
+ if (Shift >= Limit) {
+ Shift = Limit;
+ }
+ Shift = - Shift;
+ } else {
+ Limit = ViewVStart + ViewVSize
+#if WantAutoScrollBorder
+ - (ViewVSize / 16)
+#endif
+ ;
+ if (CurMouseV > Limit) {
+ Shift = (CurMouseV - Limit + 1) & (~ 1);
+ Limit = vMacScreenHeight - ViewVSize - ViewVStart;
+ if (Shift >= Limit) {
+ Shift = Limit;
+ }
+ }
+ }
+
+ if (Shift != 0) {
+ ViewVStart += Shift;
+ SavedMouseV += Shift;
+ ScreenChangedAll();
+ }
+ }
+}
+#endif
+
+LOCALPROC SetLongs(ui5b *p, long n)
+{
+ long i;
+
+ for (i = n; --i >= 0; ) {
+ *p++ = (ui5b) -1;
+ }
+}
+
+LOCALVAR uimr ReserveAllocOffset;
+LOCALVAR ui3p ReserveAllocBigBlock = nullpr;
+
+#define PowOf2(p) ((uimr)1 << (p))
+#define Pow2Mask(p) (PowOf2(p) - 1)
+#define ModPow2(i, p) ((i) & Pow2Mask(p))
+#define FloorDivPow2(i, p) ((i) >> (p))
+#define FloorPow2Mult(i, p) ((i) & (~ Pow2Mask(p)))
+#define CeilPow2Mult(i, p) FloorPow2Mult((i) + Pow2Mask(p), (p))
+ /* warning - CeilPow2Mult evaluates p twice */
+
+GLOBALOSGLUPROC ReserveAllocOneBlock(ui3p *p, uimr n,
+ ui3r align, blnr FillOnes)
+{
+ ReserveAllocOffset = CeilPow2Mult(ReserveAllocOffset, align);
+ if (nullpr == ReserveAllocBigBlock) {
+ *p = nullpr;
+ } else {
+ *p = ReserveAllocBigBlock + ReserveAllocOffset;
+ if (FillOnes) {
+ SetLongs((ui5b *)*p, n / 4);
+ }
+ }
+ ReserveAllocOffset += n;
+}
+
+/* --- sending debugging info to file --- */
+
+#if dbglog_HAVE
+
+#define dbglog_bufsz PowOf2(dbglog_buflnsz)
+LOCALVAR uimr dbglog_bufpos = 0;
+
+LOCALVAR char *dbglog_bufp = nullpr;
+
+LOCALPROC dbglog_ReserveAlloc(void)
+{
+ ReserveAllocOneBlock((ui3p *)&dbglog_bufp, dbglog_bufsz,
+ 5, falseblnr);
+}
+
+#define dbglog_open dbglog_open0
+
+LOCALPROC dbglog_close(void)
+{
+ uimr n = ModPow2(dbglog_bufpos, dbglog_buflnsz);
+ if (n != 0) {
+ dbglog_write0(dbglog_bufp, n);
+ }
+
+ dbglog_close0();
+}
+
+LOCALPROC dbglog_write(char *p, uimr L)
+{
+ uimr r;
+ uimr bufposmod;
+ uimr curbufdiv;
+ uimr newbufpos = dbglog_bufpos + L;
+ uimr newbufdiv = FloorDivPow2(newbufpos, dbglog_buflnsz);
+
+label_retry:
+ curbufdiv = FloorDivPow2(dbglog_bufpos, dbglog_buflnsz);
+ bufposmod = ModPow2(dbglog_bufpos, dbglog_buflnsz);
+ if (newbufdiv != curbufdiv) {
+ r = dbglog_bufsz - bufposmod;
+ MyMoveBytes((anyp)p, (anyp)(dbglog_bufp + bufposmod), r);
+ dbglog_write0(dbglog_bufp, dbglog_bufsz);
+ L -= r;
+ p += r;
+ dbglog_bufpos += r;
+ goto label_retry;
+ }
+ MyMoveBytes((anyp)p, (anyp)dbglog_bufp + bufposmod, L);
+ dbglog_bufpos = newbufpos;
+}
+
+LOCALFUNC uimr CStrLength(char *s)
+{
+ char *p = s;
+
+ while (*p++ != 0) {
+ }
+ return p - s - 1;
+}
+
+GLOBALOSGLUPROC dbglog_writeCStr(char *s)
+{
+ /* fprintf(DumpFile, "%s", s); */
+ dbglog_write(s, CStrLength(s));
+}
+
+GLOBALOSGLUPROC dbglog_writeReturn(void)
+{
+ dbglog_writeCStr("\n");
+ /* fprintf(DumpFile, "\n"); */
+}
+
+GLOBALOSGLUPROC dbglog_writeHex(uimr x)
+{
+ ui3r v;
+ char s[16];
+ char *p = s + 16;
+ uimr n = 0;
+
+ do {
+ v = x & 0x0F;
+ if (v < 10) {
+ *--p = '0' + v;
+ } else {
+ *--p = 'A' + v - 10;
+ }
+ x >>= 4;
+ ++n;
+ } while (x != 0);
+
+ dbglog_write(p, n);
+ /* fprintf(DumpFile, "%d", (int)x); */
+}
+
+GLOBALOSGLUPROC dbglog_writeNum(uimr x)
+{
+ uimr newx;
+ char s[16];
+ char *p = s + 16;
+ uimr n = 0;
+
+ do {
+ newx = x / (uimr)10;
+ *--p = '0' + (x - newx * 10);
+ x = newx;
+ ++n;
+ } while (x != 0);
+
+ dbglog_write(p, n);
+ /* fprintf(DumpFile, "%d", (int)x); */
+}
+
+GLOBALOSGLUPROC dbglog_writeMacChar(ui3r x)
+{
+ char s;
+
+ if ((x > 32) && (x < 127)) {
+ s = x;
+ } else {
+ s = '?';
+ }
+
+ dbglog_write(&s, 1);
+}
+
+LOCALPROC dbglog_writeSpace(void)
+{
+ dbglog_writeCStr(" ");
+}
+
+GLOBALOSGLUPROC dbglog_writeln(char *s)
+{
+ dbglog_writeCStr(s);
+ dbglog_writeReturn();
+}
+
+GLOBALOSGLUPROC dbglog_writelnNum(char *s, simr v)
+{
+ dbglog_writeCStr(s);
+ dbglog_writeSpace();
+ dbglog_writeNum(v);
+ dbglog_writeReturn();
+}
+
+#endif
+
+/* my event queue */
+
+#define MyEvtQLg2Sz 4
+#define MyEvtQSz (1 << MyEvtQLg2Sz)
+#define MyEvtQIMask (MyEvtQSz - 1)
+
+LOCALVAR MyEvtQEl MyEvtQA[MyEvtQSz];
+LOCALVAR ui4r MyEvtQIn = 0;
+LOCALVAR ui4r MyEvtQOut = 0;
+
+GLOBALOSGLUFUNC MyEvtQEl * MyEvtQOutP(void)
+{
+ MyEvtQEl *p = nullpr;
+ if (MyEvtQIn != MyEvtQOut) {
+ p = &MyEvtQA[MyEvtQOut & MyEvtQIMask];
+ }
+ return p;
+}
+
+GLOBALOSGLUPROC MyEvtQOutDone(void)
+{
+ ++MyEvtQOut;
+}
+
+LOCALVAR blnr MyEvtQNeedRecover = falseblnr;
+ /* events lost because of full queue */
+
+LOCALFUNC MyEvtQEl * MyEvtQElPreviousIn(void)
+{
+ MyEvtQEl *p = NULL;
+ if (MyEvtQIn - MyEvtQOut != 0) {
+ p = &MyEvtQA[(MyEvtQIn - 1) & MyEvtQIMask];
+ }
+
+ return p;
+}
+
+LOCALFUNC MyEvtQEl * MyEvtQElAlloc(void)
+{
+ MyEvtQEl *p = NULL;
+ if (MyEvtQIn - MyEvtQOut >= MyEvtQSz) {
+ MyEvtQNeedRecover = trueblnr;
+ } else {
+ p = &MyEvtQA[MyEvtQIn & MyEvtQIMask];
+
+ ++MyEvtQIn;
+ }
+
+ return p;
+}
+
+LOCALVAR ui5b theKeys[4];
+
+LOCALPROC Keyboard_UpdateKeyMap(ui3r key, blnr down)
+{
+ ui3r k = key & 127; /* just for safety */
+ ui3r bit = 1 << (k & 7);
+ ui3b *kp = (ui3b *)theKeys;
+ ui3b *kpi = &kp[k / 8];
+ blnr CurDown = ((*kpi & bit) != 0);
+ if (CurDown != down) {
+ MyEvtQEl *p = MyEvtQElAlloc();
+ if (NULL != p) {
+ p->kind = MyEvtQElKindKey;
+ p->u.press.key = k;
+ p->u.press.down = down;
+
+ if (down) {
+ *kpi |= bit;
+ } else {
+ *kpi &= ~ bit;
+ }
+ }
+
+ QuietEnds();
+ }
+}
+
+LOCALVAR blnr MyMouseButtonState = falseblnr;
+
+LOCALPROC MyMouseButtonSet(blnr down)
+{
+ if (MyMouseButtonState != down) {
+ MyEvtQEl *p = MyEvtQElAlloc();
+ if (NULL != p) {
+ p->kind = MyEvtQElKindMouseButton;
+ p->u.press.down = down;
+
+ MyMouseButtonState = down;
+ }
+
+ QuietEnds();
+ }
+}
+
+#if EnableFSMouseMotion
+LOCALPROC MyMousePositionSetDelta(ui4r dh, ui4r dv)
+{
+ if ((dh != 0) || (dv != 0)) {
+ MyEvtQEl *p = MyEvtQElPreviousIn();
+ if ((NULL != p) && (MyEvtQElKindMouseDelta == p->kind)) {
+ p->u.pos.h += dh;
+ p->u.pos.v += dv;
+ } else {
+ p = MyEvtQElAlloc();
+ if (NULL != p) {
+ p->kind = MyEvtQElKindMouseDelta;
+ p->u.pos.h = dh;
+ p->u.pos.v = dv;
+ }
+ }
+
+ QuietEnds();
+ }
+}
+#endif
+
+LOCALVAR ui4b MyMousePosCurV = 0;
+LOCALVAR ui4b MyMousePosCurH = 0;
+
+LOCALPROC MyMousePositionSet(ui4r h, ui4r v)
+{
+ if ((h != MyMousePosCurH) || (v != MyMousePosCurV)) {
+ MyEvtQEl *p = MyEvtQElPreviousIn();
+ if ((NULL == p) || (MyEvtQElKindMousePos != p->kind)) {
+ p = MyEvtQElAlloc();
+ }
+ if (NULL != p) {
+ p->kind = MyEvtQElKindMousePos;
+ p->u.pos.h = h;
+ p->u.pos.v = v;
+
+ MyMousePosCurH = h;
+ MyMousePosCurV = v;
+ }
+
+ QuietEnds();
+ }
+}
+
+#if 0
+#define Keyboard_TestKeyMap(key) \
+ ((((ui3b *)theKeys)[(key) / 8] & (1 << ((key) & 7))) != 0)
+#endif
+
+LOCALPROC InitKeyCodes(void)
+{
+ theKeys[0] = 0;
+ theKeys[1] = 0;
+ theKeys[2] = 0;
+ theKeys[3] = 0;
+}
+
+#define kKeepMaskControl (1 << 0)
+#define kKeepMaskCapsLock (1 << 1)
+#define kKeepMaskCommand (1 << 2)
+#define kKeepMaskOption (1 << 3)
+#define kKeepMaskShift (1 << 4)
+
+LOCALPROC DisconnectKeyCodes(ui5b KeepMask)
+{
+ /*
+ Called when may miss key ups,
+ so act is if all pressed keys have been released,
+ except maybe for control, caps lock, command,
+ option and shift.
+ */
+
+ int j;
+ int b;
+ int key;
+ ui5b m;
+
+ for (j = 0; j < 16; ++j) {
+ ui3b k1 = ((ui3b *)theKeys)[j];
+ if (0 != k1) {
+ ui3b bit = 1;
+ for (b = 0; b < 8; ++b) {
+ if (0 != (k1 & bit)) {
+ key = j * 8 + b;
+ switch (key) {
+ case MKC_Control: m = kKeepMaskControl; break;
+ case MKC_CapsLock: m = kKeepMaskCapsLock; break;
+ case MKC_Command: m = kKeepMaskCommand; break;
+ case MKC_Option: m = kKeepMaskOption; break;
+ case MKC_Shift: m = kKeepMaskShift; break;
+ default: m = 0; break;
+ }
+ if (0 == (KeepMask & m)) {
+ Keyboard_UpdateKeyMap(key, falseblnr);
+ }
+ }
+ bit <<= 1;
+ }
+ }
+ }
+}
+
+LOCALPROC MyEvtQTryRecoverFromFull(void)
+{
+ MyMouseButtonSet(falseblnr);
+ DisconnectKeyCodes(0);
+}
+
+/* MacMsg */
+
+LOCALVAR char *SavedBriefMsg = nullpr;
+LOCALVAR char *SavedLongMsg;
+#if WantAbnormalReports
+LOCALVAR ui4r SavedIDMsg = 0;
+#endif
+LOCALVAR blnr SavedFatalMsg;
+
+LOCALPROC MacMsg(char *briefMsg, char *longMsg, blnr fatal)
+{
+ if (nullpr != SavedBriefMsg) {
+ /*
+ ignore the new message, only display the
+ first error.
+ */
+ } else {
+ SavedBriefMsg = briefMsg;
+ SavedLongMsg = longMsg;
+ SavedFatalMsg = fatal;
+ }
+}
+
+#if WantAbnormalReports
+GLOBALOSGLUPROC WarnMsgAbnormalID(ui4r id)
+{
+ MacMsg(kStrReportAbnormalTitle,
+ kStrReportAbnormalMessage, falseblnr);
+
+ if (0 != SavedIDMsg) {
+ /*
+ ignore the new message, only display the
+ first error.
+ */
+ } else {
+ SavedIDMsg = id;
+ }
+}
+#endif
--- /dev/null
+++ b/src/CONTROLM.h
@@ -1,0 +1,1395 @@
+/*
+ CONTROLM.h
+
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ CONTROL Mode
+*/
+
+#ifdef CONTROLM_H
+#error "header already included"
+#else
+#define CONTROLM_H
+#endif
+
+enum {
+#if EnableDemoMsg
+ SpclModeDemo,
+#endif
+#if EnableAltKeysMode
+ SpclModeAltKeyText,
+#endif
+#if UseActvCode
+ SpclModeActvCode,
+#endif
+ SpclModeNoRom,
+ SpclModeMessage,
+#if UseControlKeys
+ SpclModeControl,
+#endif
+
+ kNumSpclModes
+};
+
+LOCALVAR uimr SpecialModes = 0;
+
+LOCALVAR blnr NeedWholeScreenDraw = falseblnr;
+
+#define SpecialModeSet(i) SpecialModes |= (1 << (i))
+#define SpecialModeClr(i) SpecialModes &= ~ (1 << (i))
+#define SpecialModeTst(i) (0 != (SpecialModes & (1 << (i))))
+
+#define MacMsgDisplayed SpecialModeTst(SpclModeMessage)
+
+LOCALVAR ui3p CntrlDisplayBuff = nullpr;
+
+LOCALPROC DrawCell(unsigned int h, unsigned int v, int x)
+{
+#if 1
+ /* safety check */
+ if ((h < ((long)vMacScreenWidth / 8 - 2))
+ && (v < (vMacScreenHeight / 16 - 1)))
+#endif
+ {
+ int i;
+ ui3p p0 = ((ui3p)CellData) + 16 * x;
+
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+ ui3p p = CntrlDisplayBuff
+ + ((h + 1) << vMacScreenDepth)
+ + (v * 16 + 11) * vMacScreenByteWidth;
+
+ for (i = 16; --i >= 0; ) {
+#if 1 == vMacScreenDepth
+ int k;
+ ui3b t0 = *p0;
+ ui3p p2 = p;
+ for (k = 2; --k >= 0; ) {
+ *p2++ = (((t0) & 0x80) ? 0xC0 : 0x00)
+ | (((t0) & 0x40) ? 0x30 : 0x00)
+ | (((t0) & 0x20) ? 0x0C : 0x00)
+ | (((t0) & 0x10) ? 0x03 : 0x00);
+ /* black RRGGBBAA, white RRGGBBAA */
+ t0 <<= 4;
+ }
+#elif 2 == vMacScreenDepth
+ int k;
+ ui3b t0 = *p0;
+ ui3p p2 = p;
+ for (k = 4; --k >= 0; ) {
+ *p2++ = (((t0) & 0x40) ? 0x0F : 0x00)
+ | (((t0) & 0x80) ? 0xF0 : 0x00);
+ /* black RRGGBBAA, white RRGGBBAA */
+ t0 <<= 2;
+ }
+#elif 3 == vMacScreenDepth
+ int k;
+ ui3b t0 = *p0;
+ ui3p p2 = p;
+ for (k = 8; --k >= 0; ) {
+ *p2++ = ((t0 >> k) & 0x01) ? 0xFF : 0x00;
+ /* black RRGGBBAA, white RRGGBBAA */
+ }
+#elif 4 == vMacScreenDepth
+ int k;
+ ui4r v;
+ ui3b t0 = *p0;
+ ui3p p2 = p;
+ for (k = 8; --k >= 0; ) {
+ v = ((t0 >> k) & 0x01) ? 0x0000 : 0x7FFF;
+ /* black RRGGBBAA, white RRGGBBAA */
+ /* *((ui4b *)p2)++ = v; need big endian, so : */
+ *p2++ = v >> 8;
+ *p2++ = v;
+ }
+#elif 5 == vMacScreenDepth
+ int k;
+ ui5r v;
+ ui3b t0 = *p0;
+ ui3p p2 = p;
+ for (k = 8; --k >= 0; ) {
+ v = ((t0 >> k) & 0x01) ? 0x00000000 : 0x00FFFFFF;
+ /* black RRGGBBAA, white RRGGBBAA */
+ /* *((ui5b *)p2)++ = v; need big endian, so : */
+ *p2++ = v >> 24;
+ *p2++ = v >> 16;
+ *p2++ = v >> 8;
+ *p2++ = v;
+ }
+#endif
+ p += vMacScreenByteWidth;
+ p0 ++;
+ }
+ } else
+#endif
+ {
+ ui3p p = CntrlDisplayBuff + (h + 1)
+ + (v * 16 + 11) * vMacScreenMonoByteWidth;
+
+ for (i = 16; --i >= 0; ) {
+ *p = *p0;
+ p += vMacScreenMonoByteWidth;
+ p0 ++;
+ }
+ }
+ }
+}
+
+#define ControlBoxh0 0
+#define ControlBoxw 62
+#define ControlBoxv0 0
+
+#define hLimit (ControlBoxh0 + ControlBoxw - 1)
+#define hStart (ControlBoxh0 + 1)
+
+
+LOCALVAR int CurCellh0;
+LOCALVAR int CurCellv0;
+
+LOCALPROC DrawCellsBeginLine(void)
+{
+ DrawCell(ControlBoxh0, CurCellv0, kCellMiddleLeft);
+ CurCellh0 = hStart;
+}
+
+LOCALPROC DrawCellsEndLine(void)
+{
+ int i;
+
+ for (i = CurCellh0; i < hLimit; ++i) {
+ DrawCell(i, CurCellv0, kCellSpace);
+ }
+ DrawCell(hLimit, CurCellv0, kCellMiddleRight);
+ CurCellv0++;
+}
+
+LOCALPROC DrawCellsBottomLine(void)
+{
+ int i;
+
+ DrawCell(ControlBoxh0 + 0, CurCellv0, kCellLowerLeft);
+ for (i = hStart; i < hLimit; ++i) {
+ DrawCell(i, CurCellv0, kCellLowerMiddle);
+ }
+ DrawCell(hLimit, CurCellv0, kCellLowerRight);
+}
+
+LOCALPROC DrawCellAdvance(int x)
+{
+ DrawCell(CurCellh0, CurCellv0, x);
+ CurCellh0++;
+}
+
+LOCALPROC DrawCellsBlankLine(void)
+{
+ DrawCellsBeginLine();
+ DrawCellsEndLine();
+}
+
+LOCALPROC DrawCellsFromStr(char *s)
+{
+ ui3b ps[ClStrMaxLength];
+ ui3b cs;
+ int L;
+ int i;
+ int j;
+ int w;
+
+ ClStrFromSubstCStr(&L, ps, s);
+
+ i = 0;
+
+ while (i < L) {
+ cs = ps[i];
+ i++;
+ if (CurCellh0 < hLimit) {
+ DrawCellAdvance(cs);
+ } else {
+ /* line is too wide, wrap */
+ if (kCellSpace != cs) {
+ --i; /* back up one char, at least */
+
+ /* now try backing up to beginning of word */
+ j = i;
+ w = CurCellh0 - hStart;
+
+ while ((w > 0) && (j > 0)
+ && (ps[j - 1] != kCellSpace))
+ {
+ --j;
+ --w;
+ }
+ if (w != 0) {
+ i = j;
+ CurCellh0 = hStart + w;
+ }
+ /*
+ else if w == 0, then have backed up to
+ beginning of line, so just let the word
+ be split.
+ */
+ }
+ /*
+ else if cs == kCellSpace, just lose the space.
+ */
+ DrawCellsEndLine();
+ /*
+ draw white space over the part of
+ the word that have already drawn
+ */
+ DrawCellsBeginLine();
+ }
+ }
+}
+
+LOCALPROC DrawCellsOneLineStr(char *s)
+{
+ DrawCellsBeginLine();
+ DrawCellsFromStr(s);
+ DrawCellsEndLine();
+}
+
+LOCALPROC DrawCellsKeyCommand(char *k, char *s)
+{
+ DrawCellsBeginLine();
+ DrawCellsFromStr(" ");
+ DrawCellsFromStr(k);
+ DrawCellsFromStr(" - ");
+ DrawCellsFromStr(s);
+ DrawCellsEndLine();
+}
+
+typedef void (*SpclModeBody) (void);
+
+LOCALPROC DrawSpclMode0(char *Title, SpclModeBody Body)
+{
+ int i;
+ int k;
+
+ CurCellv0 = ControlBoxv0 + 0;
+ DrawCell(ControlBoxh0 + 0, CurCellv0, kCellUpperLeft);
+ k = kCellIcon00;
+ for (i = hStart; i < hStart + 4; ++i) {
+ DrawCell(i, CurCellv0, k);
+ k++;
+ }
+ for (i = hStart + 4; i < hLimit; ++i) {
+ DrawCell(i, CurCellv0, kCellUpperMiddle);
+ }
+ DrawCell(hLimit, CurCellv0, kCellUpperRight);
+ ++CurCellv0;
+
+ DrawCellsBeginLine();
+ for (i = hStart; i < hStart + 4; ++i) {
+ DrawCellAdvance(k);
+ k++;
+ }
+ DrawCellAdvance(kCellSpace);
+ DrawCellsFromStr(Title);
+ DrawCellsEndLine();
+
+ DrawCellsBeginLine();
+ for (i = hStart; i < hStart + 4; ++i) {
+ DrawCellAdvance(k);
+ k++;
+ }
+ for (i = hStart + 4; i < hLimit; ++i) {
+ DrawCellAdvance(kCellGraySep);
+ }
+ DrawCellsEndLine();
+
+ if (nullpr != Body) {
+ Body();
+ }
+
+ DrawCellsBottomLine();
+}
+
+#if EnableAltKeysMode
+#include "ALTKEYSM.h"
+#else
+#define Keyboard_UpdateKeyMap1 Keyboard_UpdateKeyMap
+#define DisconnectKeyCodes1 DisconnectKeyCodes
+#endif
+
+#if WantAbnormalReports || UseActvFile
+LOCALPROC ClStrAppendHexNib(int *L0, ui3b *r, ui3r v)
+{
+ if (v < 10) {
+ ClStrAppendChar(L0, r, kCellDigit0 + v);
+ } else {
+ ClStrAppendChar(L0, r, kCellUpA + (v - 10));
+ }
+}
+#endif
+
+#if WantAbnormalReports || UseActvFile
+LOCALPROC ClStrAppendHexByte(int *L0, ui3b *r, ui3r v)
+{
+ ClStrAppendHexNib(L0, r, (v >> 4) & 0x0F);
+ ClStrAppendHexNib(L0, r, v & 0x0F);
+}
+#endif
+
+#if WantAbnormalReports || UseActvFile
+LOCALPROC ClStrAppendHexWord(int *L0, ui3b *r, ui4r v)
+{
+ ClStrAppendHexByte(L0, r, (v >> 8) & 0xFF);
+ ClStrAppendHexByte(L0, r, v & 0xFF);
+}
+#endif
+
+#if WantAbnormalReports
+LOCALPROC DrawCellsOneLineHexWord(ui4r v)
+{
+ ui3b ps[ClStrMaxLength];
+ int L = 0;
+ int i;
+
+ ClStrAppendHexWord(&L, ps, v);
+
+ DrawCellsBeginLine();
+ for (i = 0; i < L; ++i) {
+ DrawCellAdvance(ps[i]);
+ }
+ DrawCellsEndLine();
+}
+#endif
+
+LOCALPROC DrawCellsMessageModeBody(void)
+{
+ DrawCellsOneLineStr(SavedBriefMsg);
+ DrawCellsBlankLine();
+ DrawCellsOneLineStr(SavedLongMsg);
+#if WantAbnormalReports
+ if (0 != SavedIDMsg) {
+ DrawCellsBlankLine();
+ DrawCellsOneLineHexWord(SavedIDMsg);
+ }
+#endif
+}
+
+LOCALPROC DrawMessageMode(void)
+{
+ DrawSpclMode0(kStrModeMessage, DrawCellsMessageModeBody);
+}
+
+LOCALPROC MacMsgDisplayOff(void)
+{
+ SpecialModeClr(SpclModeMessage);
+ SavedBriefMsg = nullpr;
+#if WantAbnormalReports
+ SavedIDMsg = 0;
+#endif
+ NeedWholeScreenDraw = trueblnr;
+}
+
+LOCALPROC MacMsgDisplayOn(void)
+{
+ NeedWholeScreenDraw = trueblnr;
+ DisconnectKeyCodes1(kKeepMaskControl | kKeepMaskCapsLock);
+ /* command */
+ SpecialModeSet(SpclModeMessage);
+}
+
+LOCALPROC DoMessageModeKey(ui3r key)
+{
+ if (MKC_C == key) {
+ MacMsgDisplayOff();
+ }
+}
+
+LOCALPROC MacMsgOverride(char *briefMsg, char *longMsg)
+{
+ if (MacMsgDisplayed) {
+ MacMsgDisplayOff();
+ }
+ MacMsg(briefMsg, longMsg, falseblnr);
+}
+
+#if NeedDoMoreCommandsMsg
+LOCALPROC DoMoreCommandsMsg(void)
+{
+ MacMsgOverride(kStrMoreCommandsTitle,
+ kStrMoreCommandsMessage);
+}
+#endif
+
+#if NeedDoAboutMsg
+LOCALPROC DoAboutMsg(void)
+{
+ MacMsgOverride(kStrAboutTitle,
+ kStrAboutMessage);
+}
+#endif
+
+LOCALPROC NoRomMsgDisplayOff(void)
+{
+ SpecialModeClr(SpclModeNoRom);
+ NeedWholeScreenDraw = trueblnr;
+}
+
+LOCALPROC NoRomMsgDisplayOn(void)
+{
+ NeedWholeScreenDraw = trueblnr;
+ SpecialModeSet(SpclModeNoRom);
+}
+
+LOCALPROC DrawCellsNoRomModeBody(void)
+{
+ DrawCellsOneLineStr(kStrNoROMMessage);
+}
+
+LOCALPROC DrawNoRomMode(void)
+{
+ DrawSpclMode0(kStrNoROMTitle, DrawCellsNoRomModeBody);
+}
+
+#if UseControlKeys
+
+LOCALVAR blnr LastControlKey = falseblnr;
+LOCALVAR int CurControlMode = 0;
+LOCALVAR int ControlMessage = 0;
+
+enum {
+ kCntrlModeOff,
+ kCntrlModeBase,
+#if WantEnblCtrlRst
+ kCntrlModeConfirmReset,
+#endif
+#if WantEnblCtrlInt
+ kCntrlModeConfirmInterrupt,
+#endif
+ kCntrlModeConfirmQuit,
+ kCntrlModeSpeedControl,
+
+ kNumCntrlModes
+};
+
+enum {
+ kCntrlMsgBaseStart,
+#if EnableMagnify
+ kCntrlMsgMagnify,
+#endif
+#if VarFullScreen
+ kCntrlMsgFullScreen,
+#endif
+#if WantEnblCtrlRst
+ kCntrlMsgConfirmResetStart,
+ kCntrlMsgHaveReset,
+ kCntrlMsgResetCancelled,
+#endif
+#if WantEnblCtrlInt
+ kCntrlMsgConfirmInterruptStart,
+ kCntrlMsgHaveInterrupted,
+ kCntrlMsgInterruptCancelled,
+#endif
+ kCntrlMsgConfirmQuitStart,
+ kCntrlMsgQuitCancelled,
+#if WantEnblCtrlKtg
+ kCntrlMsgEmCntrl,
+#endif
+ kCntrlMsgSpeedControlStart,
+ kCntrlMsgNewSpeed,
+ kCntrlMsgNewStopped,
+ kCntrlMsgNewRunInBack,
+#if EnableAutoSlow
+ kCntrlMsgNewAutoSlow,
+#endif
+ kCntrlMsgAbout,
+ kCntrlMsgHelp,
+#if IncludePbufs
+ kCntrlMsgOptionsStrCopied,
+#endif
+#if 0 && (UseActvCode || EnableDemoMsg)
+ kCntrlMsgRegStrCopied,
+#endif
+
+ kNumCntrlMsgs
+};
+
+LOCALPROC DoEnterControlMode(void)
+{
+ CurControlMode = kCntrlModeBase;
+ ControlMessage = kCntrlMsgBaseStart;
+ NeedWholeScreenDraw = trueblnr;
+ DisconnectKeyCodes1(kKeepMaskControl | kKeepMaskCapsLock);
+ SpecialModeSet(SpclModeControl);
+}
+
+LOCALPROC DoLeaveControlMode(void)
+{
+ SpecialModeClr(SpclModeControl);
+ CurControlMode = kCntrlModeOff;
+ NeedWholeScreenDraw = trueblnr;
+}
+
+LOCALPROC Keyboard_UpdateControlKey(blnr down)
+{
+ if (down != LastControlKey) {
+ LastControlKey = down;
+ if (down) {
+ DoEnterControlMode();
+ } else {
+ DoLeaveControlMode();
+ }
+ }
+}
+
+LOCALPROC SetSpeedValue(ui3b i)
+{
+ SpeedValue = i;
+ CurControlMode = kCntrlModeBase;
+ ControlMessage = kCntrlMsgNewSpeed;
+}
+
+#if VarFullScreen
+FORWARDPROC ToggleWantFullScreen(void);
+#endif
+
+#if IncludeHostTextClipExchange
+LOCALPROC HTCEexportSubstCStr(char *s)
+{
+ int i;
+ int L;
+ tPbuf j;
+#ifdef PbufHaveLock
+ int n = ClStrSizeSubstCStr(s);
+
+ if (mnvm_noErr == PbufNew(n, &j)) {
+ blnr IsOk = falseblnr;
+ ui3p p = PbufLock(j);
+
+ if (nullpr != p) {
+ L = 0;
+ ClStrAppendSubstCStr(&L, p, s);
+
+ if (L == n) {
+ for (i = 0; i < n; ++i) {
+ p[i] = Cell2MacAsciiMap[p[i]];
+ }
+ IsOk = trueblnr;
+ }
+
+ PbufUnlock(j);
+ }
+
+ if (IsOk) {
+ HTCEexport(j);
+ } else {
+ PbufDispose(j);
+ }
+ }
+#else
+ ui3b ps[ClStrMaxLength];
+
+ ClStrFromSubstCStr(&L, ps, s);
+
+ for (i = 0; i < L; ++i) {
+ ps[i] = Cell2MacAsciiMap[ps[i]];
+ }
+
+ if (mnvm_noErr == PbufNew(L, &j)) {
+ PbufTransfer(ps, j, 0, L, trueblnr);
+ HTCEexport(j);
+ }
+#endif
+}
+#endif
+
+#if IncludeHostTextClipExchange
+LOCALPROC CopyOptionsStr(void)
+{
+ HTCEexportSubstCStr(kBldOpts);
+}
+#endif
+
+#if 0
+#if UseActvCode
+FORWARDPROC CopyRegistrationStr(void);
+#elif EnableDemoMsg
+LOCALPROC CopyRegistrationStr(void)
+{
+ HTCEexportSubstCStr("^v");
+}
+#endif
+#endif
+
+
+LOCALPROC DoControlModeKey(ui3r key)
+{
+ switch (CurControlMode) {
+ case kCntrlModeBase:
+ switch (key) {
+#if WantEnblCtrlKtg
+ case MKC_K:
+ ControlKeyPressed = ! ControlKeyPressed;
+ ControlMessage = kCntrlMsgEmCntrl;
+ Keyboard_UpdateKeyMap1(MKC_UnMappedKey,
+ ControlKeyPressed);
+ break;
+#endif
+ case MKC_S:
+ CurControlMode = kCntrlModeSpeedControl;
+ ControlMessage = kCntrlMsgSpeedControlStart;
+ break;
+#if WantEnblCtrlInt
+ case MKC_I:
+ CurControlMode = kCntrlModeConfirmInterrupt;
+ ControlMessage = kCntrlMsgConfirmInterruptStart;
+ break;
+#endif
+#if WantEnblCtrlRst
+ case MKC_R:
+ if (! AnyDiskInserted()) {
+ WantMacReset = trueblnr;
+ ControlMessage = kCntrlMsgHaveReset;
+ } else {
+ CurControlMode = kCntrlModeConfirmReset;
+ ControlMessage = kCntrlMsgConfirmResetStart;
+ }
+ break;
+#endif
+ case MKC_Q:
+ if (! AnyDiskInserted()) {
+ ForceMacOff = trueblnr;
+ } else {
+ CurControlMode = kCntrlModeConfirmQuit;
+ ControlMessage = kCntrlMsgConfirmQuitStart;
+ }
+ break;
+ case MKC_A:
+ ControlMessage = kCntrlMsgAbout;
+ break;
+ case MKC_H:
+ ControlMessage = kCntrlMsgHelp;
+ break;
+#if NeedRequestInsertDisk
+ case MKC_O:
+ RequestInsertDisk = trueblnr;
+ break;
+#endif
+#if EnableMagnify
+ case MKC_M:
+ WantMagnify = ! WantMagnify;
+ ControlMessage = kCntrlMsgMagnify;
+ break;
+#endif
+#if VarFullScreen
+ case MKC_F:
+ ToggleWantFullScreen();
+ ControlMessage = kCntrlMsgFullScreen;
+ break;
+#endif
+#if IncludeHostTextClipExchange
+ case MKC_P:
+ CopyOptionsStr();
+ ControlMessage = kCntrlMsgOptionsStrCopied;
+ break;
+#endif
+#if 0 && (UseActvCode || EnableDemoMsg)
+ case MKC_P:
+ CopyRegistrationStr();
+ ControlMessage = kCntrlMsgRegStrCopied;
+ break;
+#endif
+#if NeedRequestIthDisk
+ case MKC_1:
+ RequestIthDisk = 1;
+ break;
+ case MKC_2:
+ RequestIthDisk = 2;
+ break;
+ case MKC_3:
+ RequestIthDisk = 3;
+ break;
+ case MKC_4:
+ RequestIthDisk = 4;
+ break;
+ case MKC_5:
+ RequestIthDisk = 5;
+ break;
+ case MKC_6:
+ RequestIthDisk = 6;
+ break;
+ case MKC_7:
+ RequestIthDisk = 7;
+ break;
+ case MKC_8:
+ RequestIthDisk = 8;
+ break;
+ case MKC_9:
+ RequestIthDisk = 9;
+ break;
+#endif
+ }
+ break;
+#if WantEnblCtrlRst
+ case kCntrlModeConfirmReset:
+ switch (key) {
+ case MKC_Y:
+ WantMacReset = trueblnr;
+ CurControlMode = kCntrlModeBase;
+ ControlMessage = kCntrlMsgHaveReset;
+ break;
+ case MKC_R:
+ /* ignore, in case of repeat */
+ break;
+ case MKC_N:
+ default:
+ CurControlMode = kCntrlModeBase;
+ ControlMessage = kCntrlMsgResetCancelled;
+ break;
+ }
+ break;
+#endif
+#if WantEnblCtrlInt
+ case kCntrlModeConfirmInterrupt:
+ switch (key) {
+ case MKC_Y:
+ WantMacInterrupt = trueblnr;
+ CurControlMode = kCntrlModeBase;
+ ControlMessage = kCntrlMsgHaveInterrupted;
+ break;
+ case MKC_I:
+ /* ignore, in case of repeat */
+ break;
+ case MKC_N:
+ default:
+ CurControlMode = kCntrlModeBase;
+ ControlMessage = kCntrlMsgInterruptCancelled;
+ break;
+ }
+ break;
+#endif
+ case kCntrlModeConfirmQuit:
+ switch (key) {
+ case MKC_Y:
+ ForceMacOff = trueblnr;
+ CurControlMode = kCntrlModeBase;
+ ControlMessage = kCntrlMsgBaseStart;
+ /* shouldn't see this message since quitting */
+ break;
+ case MKC_Q:
+ /* ignore, in case of repeat */
+ break;
+ case MKC_N:
+ default:
+ CurControlMode = kCntrlModeBase;
+ ControlMessage = kCntrlMsgQuitCancelled;
+ break;
+ }
+ break;
+ case kCntrlModeSpeedControl:
+ switch (key) {
+ case MKC_E:
+ CurControlMode = kCntrlModeBase;
+ ControlMessage = kCntrlMsgBaseStart;
+ break;
+ case MKC_B:
+ RunInBackground = ! RunInBackground;
+ CurControlMode = kCntrlModeBase;
+ ControlMessage = kCntrlMsgNewRunInBack;
+ break;
+ case MKC_D:
+ if (ROM_loaded) {
+ SpeedStopped = ! SpeedStopped;
+ CurControlMode = kCntrlModeBase;
+ ControlMessage = kCntrlMsgNewStopped;
+ }
+ break;
+#if EnableAutoSlow
+ case MKC_W:
+ WantNotAutoSlow = ! WantNotAutoSlow;
+ CurControlMode = kCntrlModeBase;
+ ControlMessage = kCntrlMsgNewAutoSlow;
+ break;
+#endif
+ case MKC_Z:
+ SetSpeedValue(0);
+ break;
+ case MKC_1:
+ SetSpeedValue(1);
+ break;
+ case MKC_2:
+ SetSpeedValue(2);
+ break;
+ case MKC_3:
+ SetSpeedValue(3);
+ break;
+ case MKC_4:
+ SetSpeedValue(4);
+ break;
+ case MKC_5:
+ SetSpeedValue(5);
+ break;
+ case MKC_A:
+ SetSpeedValue((ui3b) -1);
+ break;
+ }
+ break;
+ }
+ NeedWholeScreenDraw = trueblnr;
+}
+
+LOCALFUNC char * ControlMode2TitleStr(void)
+{
+ char *s;
+
+ switch (CurControlMode) {
+#if WantEnblCtrlRst
+ case kCntrlModeConfirmReset:
+ s = kStrModeConfirmReset;
+ break;
+#endif
+#if WantEnblCtrlInt
+ case kCntrlModeConfirmInterrupt:
+ s = kStrModeConfirmInterrupt;
+ break;
+#endif
+ case kCntrlModeConfirmQuit:
+ s = kStrModeConfirmQuit;
+ break;
+ case kCntrlModeSpeedControl:
+ s = kStrModeSpeedControl;
+ break;
+ case kCntrlModeBase:
+ default:
+ if (kCntrlMsgHelp == ControlMessage) {
+ s = kStrModeControlHelp;
+ } else {
+ s = kStrModeControlBase;
+ }
+ break;
+ }
+
+ return s;
+}
+
+LOCALPROC DrawCellsControlModeBody(void)
+{
+ switch (ControlMessage) {
+ case kCntrlMsgAbout:
+ DrawCellsOneLineStr(kStrProgramInfo);
+
+ DrawCellsBlankLine();
+
+ DrawCellsOneLineStr(kStrWorkOfMany);
+ DrawCellsOneLineStr(kMaintainerName);
+ DrawCellsOneLineStr(kStrForMoreInfo);
+ DrawCellsOneLineStr("^w");
+
+ DrawCellsBlankLine();
+
+ DrawCellsBeginLine();
+ DrawCellsFromStr(kStrLicense);
+ DrawCellsFromStr(kStrDisclaimer);
+ DrawCellsEndLine();
+
+ break;
+
+ case kCntrlMsgHelp:
+ DrawCellsOneLineStr(kStrHowToLeaveControl);
+ DrawCellsOneLineStr(kStrHowToPickACommand);
+ DrawCellsBlankLine();
+ DrawCellsKeyCommand("A", kStrCmdAbout);
+#if NeedRequestInsertDisk
+ DrawCellsKeyCommand("O", kStrCmdOpenDiskImage);
+#endif
+ DrawCellsKeyCommand("Q", kStrCmdQuit);
+ DrawCellsKeyCommand("S", kStrCmdSpeedControl);
+#if EnableMagnify
+ DrawCellsKeyCommand("M", kStrCmdMagnifyToggle);
+#endif
+#if VarFullScreen
+ DrawCellsKeyCommand("F", kStrCmdFullScrnToggle);
+#endif
+#if WantEnblCtrlKtg
+ DrawCellsKeyCommand("K", kStrCmdCtrlKeyToggle);
+#endif
+#if WantEnblCtrlRst
+ DrawCellsKeyCommand("R", kStrCmdReset);
+#endif
+#if WantEnblCtrlInt
+ DrawCellsKeyCommand("I", kStrCmdInterrupt);
+#endif
+ DrawCellsKeyCommand("P", kStrCmdCopyOptions);
+ DrawCellsKeyCommand("H", kStrCmdHelp);
+ break;
+ case kCntrlMsgSpeedControlStart:
+ DrawCellsOneLineStr(kStrCurrentSpeed);
+ DrawCellsKeyCommand("Z", "1x");
+ DrawCellsKeyCommand("1", "2x");
+ DrawCellsKeyCommand("2", "4x");
+ DrawCellsKeyCommand("3", "8x");
+ DrawCellsKeyCommand("4", "16x");
+ DrawCellsKeyCommand("5", "32x");
+ DrawCellsKeyCommand("A", kStrSpeedAllOut);
+ DrawCellsBlankLine();
+ DrawCellsKeyCommand("D", kStrSpeedStopped);
+ DrawCellsKeyCommand("B", kStrSpeedBackToggle);
+#if EnableAutoSlow
+ DrawCellsKeyCommand("W", kStrSpeedAutoSlowToggle);
+#endif
+ DrawCellsBlankLine();
+ DrawCellsKeyCommand("E", kStrSpeedExit);
+ break;
+ case kCntrlMsgNewSpeed:
+ DrawCellsOneLineStr(kStrNewSpeed);
+ break;
+ case kCntrlMsgNewRunInBack:
+ DrawCellsOneLineStr(kStrNewRunInBack);
+ break;
+ case kCntrlMsgNewStopped:
+ DrawCellsOneLineStr(kStrNewStopped);
+ break;
+#if EnableAutoSlow
+ case kCntrlMsgNewAutoSlow:
+ DrawCellsOneLineStr(kStrNewAutoSlow);
+ break;
+#endif
+#if EnableMagnify
+ case kCntrlMsgMagnify:
+ DrawCellsOneLineStr(kStrNewMagnify);
+ break;
+#endif
+#if VarFullScreen
+ case kCntrlMsgFullScreen:
+ DrawCellsOneLineStr(kStrNewFullScreen);
+ break;
+#endif
+#if IncludeHostTextClipExchange
+ case kCntrlMsgOptionsStrCopied:
+ DrawCellsOneLineStr(kStrHaveCopiedOptions);
+ break;
+#endif
+#if 0
+#if UseActvCode
+ case kCntrlMsgRegStrCopied:
+ DrawCellsOneLineStr("Registration String copied.");
+ break;
+#elif EnableDemoMsg
+ case kCntrlMsgRegStrCopied:
+ DrawCellsOneLineStr("Variation name copied.");
+ break;
+#endif
+#endif
+#if WantEnblCtrlRst
+ case kCntrlMsgConfirmResetStart:
+ DrawCellsOneLineStr(kStrConfirmReset);
+ DrawCellsBlankLine();
+ DrawCellsKeyCommand("Y", kStrResetDo);
+ DrawCellsKeyCommand("N", kStrResetNo);
+ break;
+ case kCntrlMsgHaveReset:
+ DrawCellsOneLineStr(kStrHaveReset);
+ break;
+ case kCntrlMsgResetCancelled:
+ DrawCellsOneLineStr(kStrCancelledReset);
+ break;
+#endif
+#if WantEnblCtrlInt
+ case kCntrlMsgConfirmInterruptStart:
+ DrawCellsOneLineStr(kStrConfirmInterrupt);
+ DrawCellsBlankLine();
+ DrawCellsKeyCommand("Y", kStrInterruptDo);
+ DrawCellsKeyCommand("N", kStrInterruptNo);
+ break;
+ case kCntrlMsgHaveInterrupted:
+ DrawCellsOneLineStr(kStrHaveInterrupted);
+ break;
+ case kCntrlMsgInterruptCancelled:
+ DrawCellsOneLineStr(kStrCancelledInterrupt);
+ break;
+#endif
+ case kCntrlMsgConfirmQuitStart:
+ DrawCellsOneLineStr(kStrConfirmQuit);
+ DrawCellsBlankLine();
+ DrawCellsKeyCommand("Y", kStrQuitDo);
+ DrawCellsKeyCommand("N", kStrQuitNo);
+ break;
+ case kCntrlMsgQuitCancelled:
+ DrawCellsOneLineStr(kStrCancelledQuit);
+ break;
+#if WantEnblCtrlKtg
+ case kCntrlMsgEmCntrl:
+ DrawCellsOneLineStr(kStrNewCntrlKey);
+ break;
+#endif
+ case kCntrlMsgBaseStart:
+ default:
+ DrawCellsOneLineStr(kStrHowToLeaveControl);
+ break;
+ }
+}
+
+LOCALPROC DrawControlMode(void)
+{
+ DrawSpclMode0(ControlMode2TitleStr(), DrawCellsControlModeBody);
+}
+
+#endif /* UseControlKeys */
+
+#if EnableDemoMsg
+
+LOCALPROC DrawDemoMode(void)
+{
+ CurCellv0 = ControlBoxv0 + ((9 * CurMacDateInSeconds) & 0x0F);
+ CurCellh0 = ControlBoxh0 + ((15 * CurMacDateInSeconds) & 0x1F);
+
+ DrawCellAdvance(kCellDemo0);
+ DrawCellAdvance(kCellDemo6);
+ DrawCellAdvance(kCellDemo6);
+ DrawCellAdvance(kCellDemo7);
+ DrawCellAdvance(kCellDemo1);
+ DrawCellAdvance(kCellDemo2);
+ DrawCellAdvance(kCellDemo3);
+ DrawCellAdvance(kCellDemo4);
+ DrawCellAdvance(kCellDemo7);
+ DrawCellAdvance(kCellDemo6);
+ DrawCellAdvance(kCellDemo6);
+ DrawCellAdvance(kCellDemo5);
+}
+
+LOCALPROC DemoModeSecondNotify(void)
+{
+ NeedWholeScreenDraw = trueblnr;
+ SpecialModeSet(SpclModeDemo);
+}
+
+#endif /* EnableDemoMsg */
+
+#if UseActvCode
+#include "ACTVCODE.h"
+#endif
+
+LOCALPROC DrawSpclMode(void)
+{
+#if UseControlKeys
+ if (SpecialModeTst(SpclModeControl)) {
+ DrawControlMode();
+ } else
+#endif
+ if (SpecialModeTst(SpclModeMessage)) {
+ DrawMessageMode();
+ } else
+ if (SpecialModeTst(SpclModeNoRom)) {
+ DrawNoRomMode();
+ } else
+#if UseActvCode
+ if (SpecialModeTst(SpclModeActvCode)) {
+ DrawActvCodeMode();
+ } else
+#endif
+#if EnableAltKeysMode
+ if (SpecialModeTst(SpclModeAltKeyText)) {
+ DrawAltKeyMode();
+ } else
+#endif
+#if EnableDemoMsg
+ if (SpecialModeTst(SpclModeDemo)) {
+ DrawDemoMode();
+ } else
+#endif
+ {
+ /* should not get here */
+ }
+}
+
+LOCALFUNC ui3p GetCurDrawBuff(void)
+{
+ ui3p p = screencomparebuff;
+
+ if (0 != SpecialModes) {
+ MyMoveBytes((anyp)p, (anyp)CntrlDisplayBuff,
+#if 0 != vMacScreenDepth
+ UseColorMode ? vMacScreenNumBytes :
+#endif
+ vMacScreenMonoNumBytes
+ );
+ p = CntrlDisplayBuff;
+
+ DrawSpclMode();
+ }
+
+ return p;
+}
+
+#ifdef WantKeyboard_RemapMac
+LOCALFUNC ui3r Keyboard_RemapMac(ui3r key)
+{
+ switch (key) {
+#if MKC_formac_Control != MKC_Control
+ case MKC_Control:
+ key = MKC_formac_Control;
+ break;
+#endif
+#if MKC_formac_Command != MKC_Command
+ case MKC_Command:
+ key = MKC_formac_Command;
+ break;
+#endif
+#if MKC_formac_Option != MKC_Option
+ case MKC_Option:
+ key = MKC_formac_Option;
+ break;
+#endif
+#if MKC_formac_Shift != MKC_Shift
+ case MKC_Shift:
+ key = MKC_formac_Shift;
+ break;
+#endif
+#if MKC_formac_CapsLock != MKC_CapsLock
+ case MKC_CapsLock:
+ key = MKC_formac_CapsLock;
+ break;
+#endif
+#if MKC_formac_F1 != MKC_F1
+ case MKC_F1:
+ key = MKC_formac_F1;
+ break;
+#endif
+#if MKC_formac_F2 != MKC_F2
+ case MKC_F2:
+ key = MKC_formac_F2;
+ break;
+#endif
+#if MKC_formac_F3 != MKC_F3
+ case MKC_F3:
+ key = MKC_formac_F3;
+ break;
+#endif
+#if MKC_formac_F4 != MKC_F4
+ case MKC_F4:
+ key = MKC_formac_F4;
+ break;
+#endif
+#if MKC_formac_F5 != MKC_F5
+ case MKC_F5:
+ key = MKC_formac_F5;
+ break;
+#endif
+#if MKC_formac_Escape != MKC_Escape
+ case MKC_Escape:
+ key = MKC_formac_Escape;
+ break;
+#endif
+#if MKC_formac_BackSlash != MKC_BackSlash
+ case MKC_BackSlash:
+ key = MKC_formac_BackSlash;
+ break;
+#endif
+#if MKC_formac_Slash != MKC_Slash
+ case MKC_Slash:
+ key = MKC_formac_Slash;
+ break;
+#endif
+#if MKC_formac_Grave != MKC_Grave
+ case MKC_Grave:
+ key = MKC_formac_Grave;
+ break;
+#endif
+#if MKC_formac_Enter != MKC_Enter
+ case MKC_Enter:
+ key = MKC_formac_Enter;
+ break;
+#endif
+#if MKC_formac_PageUp != MKC_PageUp
+ case MKC_PageUp:
+ key = MKC_formac_PageUp;
+ break;
+#endif
+#if MKC_formac_PageDown != MKC_PageDown
+ case MKC_PageDown:
+ key = MKC_formac_PageDown;
+ break;
+#endif
+#if MKC_formac_Home != MKC_Home
+ case MKC_Home:
+ key = MKC_formac_Home;
+ break;
+#endif
+#if MKC_formac_End != MKC_End
+ case MKC_End:
+ key = MKC_formac_End;
+ break;
+#endif
+#if MKC_formac_Help != MKC_Help
+ case MKC_Help:
+ key = MKC_formac_Help;
+ break;
+#endif
+#if MKC_formac_ForwardDel != MKC_ForwardDel
+ case MKC_ForwardDel:
+ key = MKC_formac_ForwardDel;
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return key;
+}
+#endif /* WantKeyboard_RemapMac */
+
+LOCALPROC Keyboard_UpdateKeyMap2(ui3r key, blnr down)
+{
+#if UseControlKeys
+ if (MKC_CM == key) {
+ Keyboard_UpdateControlKey(down);
+ } else
+#endif
+ if ((0 == SpecialModes)
+#if EnableAltKeysMode || EnableDemoMsg
+ || (0 == (SpecialModes & ~ (
+ 0
+#if EnableAltKeysMode
+ | (1 << SpclModeAltKeyText)
+#endif
+#if EnableDemoMsg
+ | (1 << SpclModeDemo)
+#endif
+ )))
+#endif
+ || (MKC_CapsLock == key)
+ )
+ {
+ /* pass through */
+ Keyboard_UpdateKeyMap1(key, down);
+ } else {
+ if (down) {
+#if UseControlKeys
+ if (SpecialModeTst(SpclModeControl)) {
+ DoControlModeKey(key);
+ } else
+#endif
+ if (SpecialModeTst(SpclModeMessage)) {
+ DoMessageModeKey(key);
+ } else
+#if UseActvCode
+ if (SpecialModeTst(SpclModeActvCode)) {
+ DoActvCodeModeKey(key);
+ } else
+#endif
+ {
+ }
+ } /* else if not down ignore */
+ }
+}
+
+LOCALPROC DisconnectKeyCodes2(void)
+{
+ DisconnectKeyCodes1(kKeepMaskControl | kKeepMaskCapsLock);
+#if UseControlKeys
+ Keyboard_UpdateControlKey(falseblnr);
+#endif
+}
+
+#ifndef CheckRomCheckSum
+#define CheckRomCheckSum 1
+#endif
+
+#if CheckRomCheckSum
+LOCALFUNC ui5r Calc_Checksum(void)
+{
+ long int i;
+ ui5b CheckSum = 0;
+ ui3p p = 4 + ROM;
+
+ for (i = (kCheckSumRom_Size - 4) >> 1; --i >= 0; ) {
+ CheckSum += do_get_mem_word(p);
+ p += 2;
+ }
+
+ return CheckSum;
+}
+#endif
+
+#if CheckRomCheckSum && RomStartCheckSum
+LOCALPROC WarnMsgCorruptedROM(void)
+{
+ MacMsgOverride(kStrCorruptedROMTitle, kStrCorruptedROMMessage);
+}
+#endif
+
+#if CheckRomCheckSum
+LOCALPROC WarnMsgUnsupportedROM(void)
+{
+ MacMsgOverride(kStrUnsupportedROMTitle,
+ kStrUnsupportedROMMessage);
+}
+#endif
+
+LOCALFUNC tMacErr ROM_IsValid(void)
+{
+#if CheckRomCheckSum
+ ui5r CheckSum = Calc_Checksum();
+
+#if RomStartCheckSum
+ if (CheckSum != do_get_mem_long(ROM)) {
+ WarnMsgCorruptedROM();
+ return mnvm_miscErr;
+ } else
+#endif
+#ifdef kRomCheckSum1
+ if (CheckSum == kRomCheckSum1) {
+ } else
+#endif
+#ifdef kRomCheckSum2
+ if (CheckSum == kRomCheckSum2) {
+ } else
+#endif
+#ifdef kRomCheckSum3
+ if (CheckSum == kRomCheckSum3) {
+ } else
+#endif
+ {
+ WarnMsgUnsupportedROM();
+ return mnvm_miscErr;
+ }
+ /*
+ Even if ROM is corrupt or unsupported, go ahead and
+ try to run anyway. It shouldn't do any harm.
+ [update: no, don't]
+ */
+
+#endif /* CheckRomCheckSum */
+
+ ROM_loaded = trueblnr;
+ SpeedStopped = falseblnr;
+
+ return mnvm_noErr;
+}
+
+LOCALFUNC blnr WaitForRom(void)
+{
+ if (! ROM_loaded) {
+ NoRomMsgDisplayOn();
+
+ SpeedStopped = trueblnr;
+ do {
+ WaitForNextTick();
+
+ if (ForceMacOff) {
+ return falseblnr;
+ }
+ } while (SpeedStopped);
+
+ NoRomMsgDisplayOff();
+ }
+
+ return trueblnr;
+}
--- /dev/null
+++ b/src/DATE2SEC.h
@@ -1,0 +1,117 @@
+/*
+ DATE2SEC.h
+ Copyright (C) 2003 Bradford L. Barrett, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ DATE 2(to) SEConds
+
+ convert year/month/day/hour/minute/second
+ to number of seconds since the beginning
+ of 1904, the format for storing dates
+ on the Macintosh.
+
+ The function jdate is from the program Webalizer
+ by Bradford L. Barrett.
+*/
+
+#ifdef DATE2SEC_H
+#error "header already included"
+#else
+#define DATE2SEC_H
+#endif
+
+/*
+ The function jdate was found at the end of the file
+ webalizer.c in the program webalizer at
+ "www.mrunix.net/webalizer/".
+ Here is copyright info from the top of that file:
+
+ webalizer - a web server log analysis program
+
+ Copyright (C) 1997-2000 Bradford L. Barrett ([email protected])
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version, and provided that the above
+ copyright and permission notice is included with all distributed
+ copies of this or derived software.
+*/
+
+/* ************************************************************* */
+/* */
+/* JDATE - Julian date calculator */
+/* */
+/* Calculates the number of days since Jan 1, 0000. */
+/* */
+/* Originally written by Bradford L. Barrett (03/17/1988) */
+/* Returns an unsigned long value representing the number of */
+/* days since January 1, 0000. */
+/* */
+/* Note: Due to the changes made by Pope Gregory XIII in the */
+/* 16th Centyry (Feb 24, 1582), dates before 1583 will */
+/* not return a truely accurate number (will be at least */
+/* 10 days off). Somehow, I don't think this will */
+/* present much of a problem for most situations :) */
+/* */
+/* Usage: days = jdate(day, month, year) */
+/* */
+/* The number returned is adjusted by 5 to facilitate day of */
+/* week calculations. The mod of the returned value gives the */
+/* day of the week the date is. (ie: dow = days % 7) where */
+/* dow will return 0=Sunday, 1=Monday, 2=Tuesday, etc... */
+/* */
+/* ************************************************************* */
+
+LOCALFUNC ui5b jdate(int day, int month, int year)
+{
+ ui5b days; /* value returned */
+ int mtable[] = {
+ 0, 31, 59, 90, 120, 151,
+ 181, 212, 243, 273, 304, 334
+ };
+
+ /*
+ First, calculate base number including leap
+ and Centenial year stuff
+ */
+
+ days = (((ui5b)year * 365) + day + mtable[month - 1]
+ + ((year + 4) / 4) - ((year / 100) - (year / 400)));
+
+ /* now adjust for leap year before March 1st */
+
+ if ((year % 4 == 0)
+ && (! ((year % 100 == 0) && (year % 400 != 0)))
+ && (month < 3))
+ {
+ --days;
+ }
+
+ /* done, return with calculated value */
+
+ return (days + 5);
+}
+
+LOCALFUNC ui5b Date2MacSeconds(int second, int minute, int hour,
+ int day, int month, int year)
+{
+ ui5b curjdate;
+ ui5b basejdate;
+
+ curjdate = jdate(day, month, year);
+ basejdate = jdate(1, 1, 1904);
+ return (((curjdate - basejdate) * 24 + hour) * 60
+ + minute) * 60 + second;
+}
--- /dev/null
+++ b/src/DISAM68K.c
@@ -1,0 +1,2940 @@
+/*
+ DISAM68K.c
+
+ Copyright (C) 2010 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ DISAssemble Motorola 68K instructions.
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+
+#include "ENDIANAC.h"
+#include "MYOSGLUE.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+
+#include "M68KITAB.h"
+#endif
+
+#include "DISAM68K.h"
+
+LOCALVAR ui5r Disasm_pc;
+
+/*
+ don't use get_vm_byte/get_vm_word/get_vm_long
+ so as to be sure of no side effects
+ (if pc points to memory mapped device)
+*/
+
+LOCALVAR ui3p Disasm_pcp;
+LOCALVAR ui5r Disasm_pc_blockmask;
+LOCALVAR ui3b Disasm_pcp_dummy[2] = {
+ 0, 0
+};
+
+IMPORTFUNC ATTep FindATTel(CPTR addr);
+
+LOCALPROC Disasm_Find_pcp(void)
+{
+ ATTep p;
+
+ p = FindATTel(Disasm_pc);
+ if (0 == (p->Access & kATTA_readreadymask)) {
+ Disasm_pcp = Disasm_pcp_dummy;
+ Disasm_pc_blockmask = 0;
+ } else {
+ Disasm_pc_blockmask = p->usemask & ~ p->cmpmask;
+ Disasm_pc_blockmask = Disasm_pc_blockmask
+ & ~ (Disasm_pc_blockmask + 1);
+ Disasm_pcp = p->usebase + (Disasm_pc & p->usemask);
+ }
+}
+
+LOCALFUNC ui4r Disasm_nextiword(void)
+/* NOT sign extended */
+{
+ ui4r r = do_get_mem_word(Disasm_pcp);
+ Disasm_pcp += 2;
+ Disasm_pc += 2;
+ if (0 == (Disasm_pc_blockmask & Disasm_pc)) {
+ Disasm_Find_pcp();
+ }
+ return r;
+}
+
+LOCALINLINEFUNC ui3r Disasm_nextibyte(void)
+{
+ return (ui3b) Disasm_nextiword();
+}
+
+LOCALFUNC ui5r Disasm_nextilong(void)
+{
+ ui5r hi = Disasm_nextiword();
+ ui5r lo = Disasm_nextiword();
+ ui5r r = ((hi << 16) & 0xFFFF0000)
+ | (lo & 0x0000FFFF);
+
+ return r;
+}
+
+LOCALPROC Disasm_setpc(CPTR newpc)
+{
+ if (newpc != Disasm_pc) {
+ Disasm_pc = newpc;
+
+ Disasm_Find_pcp();
+ }
+}
+
+LOCALVAR ui5b Disasm_opcode;
+
+LOCALVAR ui5b Disasm_opsize;
+
+#define Disasm_b76 ((Disasm_opcode >> 6) & 3)
+#define Disasm_b8 ((Disasm_opcode >> 8) & 1)
+#define Disasm_mode ((Disasm_opcode >> 3) & 7)
+#define Disasm_reg (Disasm_opcode & 7)
+#define Disasm_md6 ((Disasm_opcode >> 6) & 7)
+#define Disasm_rg9 ((Disasm_opcode >> 9) & 7)
+
+LOCALPROC DisasmOpSizeFromb76(void)
+{
+ Disasm_opsize = 1 << Disasm_b76;
+ switch (Disasm_opsize) {
+ case 1 :
+ dbglog_writeCStr(".B");
+ break;
+ case 2 :
+ dbglog_writeCStr(".W");
+ break;
+ case 4 :
+ dbglog_writeCStr(".L");
+ break;
+ }
+}
+
+LOCALPROC DisasmModeRegister(ui5b themode, ui5b thereg)
+{
+ switch (themode) {
+ case 0 :
+ dbglog_writeCStr("D");
+ dbglog_writeHex(thereg);
+ break;
+ case 1 :
+ dbglog_writeCStr("A");
+ dbglog_writeHex(thereg);
+ break;
+ case 2 :
+ dbglog_writeCStr("(A");
+ dbglog_writeHex(thereg);
+ dbglog_writeCStr(")");
+ break;
+ case 3 :
+ dbglog_writeCStr("(A");
+ dbglog_writeHex(thereg);
+ dbglog_writeCStr(")+");
+ break;
+ case 4 :
+ dbglog_writeCStr("-(A");
+ dbglog_writeHex(thereg);
+ dbglog_writeCStr(")");
+ break;
+ case 5 :
+ dbglog_writeHex(Disasm_nextiword());
+ dbglog_writeCStr("(A");
+ dbglog_writeHex(thereg);
+ dbglog_writeCStr(")");
+ break;
+ case 6 :
+ dbglog_writeCStr("???");
+#if 0
+ ArgKind = AKMemory;
+ ArgAddr.mem = get_disp_ea(m68k_areg(thereg));
+#endif
+ break;
+ case 7 :
+ switch (thereg) {
+ case 0 :
+ dbglog_writeCStr("(");
+ dbglog_writeHex(Disasm_nextiword());
+ dbglog_writeCStr(")");
+ break;
+ case 1 :
+ dbglog_writeCStr("(");
+ dbglog_writeHex(Disasm_nextilong());
+ dbglog_writeCStr(")");
+ break;
+ case 2 :
+ {
+ ui5r s = Disasm_pc;
+ s += ui5r_FromSWord(Disasm_nextiword());
+ dbglog_writeCStr("(");
+ dbglog_writeHex(s);
+ dbglog_writeCStr(")");
+ }
+ break;
+ case 3 :
+ dbglog_writeCStr("???");
+#if 0
+ ArgKind = AKMemory;
+ s = get_disp_ea(Disasm_pc);
+#endif
+ break;
+ case 4 :
+ dbglog_writeCStr("#");
+ if (Disasm_opsize == 2) {
+ dbglog_writeHex(Disasm_nextiword());
+ } else if (Disasm_opsize < 2) {
+ dbglog_writeHex(Disasm_nextibyte());
+ } else {
+ dbglog_writeHex(Disasm_nextilong());
+ }
+ break;
+ }
+ break;
+ case 8 :
+ dbglog_writeCStr("#");
+ dbglog_writeHex(thereg);
+ break;
+ }
+}
+
+LOCALPROC DisasmStartOne(char *s)
+{
+ dbglog_writeCStr(s);
+}
+
+LOCALPROC Disasm_xxxxxxxxssmmmrrr(char *s)
+{
+ DisasmStartOne(s);
+ DisasmOpSizeFromb76();
+ dbglog_writeCStr(" ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROC DisasmEaD_xxxxdddxssmmmrrr(char *s)
+{
+ DisasmStartOne(s);
+ DisasmOpSizeFromb76();
+ dbglog_writeCStr(" ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeCStr(", ");
+ dbglog_writeCStr("D");
+ dbglog_writeHex(Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROC DisasmI_xxxxxxxxssmmmrrr(char *s)
+{
+ DisasmStartOne(s);
+ DisasmOpSizeFromb76();
+ dbglog_writeCStr(" #");
+ if (Disasm_opsize == 2) {
+ dbglog_writeHex(ui5r_FromSWord(Disasm_nextiword()));
+ } else if (Disasm_opsize < 2) {
+ dbglog_writeHex(ui5r_FromSByte(Disasm_nextibyte()));
+ } else {
+ dbglog_writeHex(ui5r_FromSLong(Disasm_nextilong()));
+ }
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROC DisasmsAA_xxxxdddxssxxxrrr(char *s)
+{
+ DisasmStartOne(s);
+ DisasmOpSizeFromb76();
+ DisasmModeRegister(3, Disasm_reg);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(3, Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALFUNC ui5r Disasm_octdat(ui5r x)
+{
+ if (x == 0) {
+ return 8;
+ } else {
+ return x;
+ }
+}
+
+LOCALPROC Disasm_xxxxnnnxssmmmrrr(char *s)
+{
+ DisasmStartOne(s);
+ DisasmOpSizeFromb76();
+ dbglog_writeCStr(" #");
+
+ dbglog_writeHex(Disasm_octdat(Disasm_rg9));
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROC DisasmDEa_xxxxdddxssmmmrrr(char *s)
+{
+ DisasmStartOne(s);
+ DisasmOpSizeFromb76();
+ dbglog_writeCStr(" D");
+ dbglog_writeHex(Disasm_rg9);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROC DisasmEaA_xxxxdddsxxmmmrrr(char *s)
+{
+ DisasmStartOne(s);
+
+ Disasm_opsize = Disasm_b8 * 2 + 2;
+ if (Disasm_opsize == 2) {
+ dbglog_writeCStr(".W");
+ } else {
+ dbglog_writeCStr(".L");
+ }
+ dbglog_writeCStr(" ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeCStr(", A");
+ dbglog_writeHex(Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROC DisasmDD_xxxxdddxssxxxrrr(char *s)
+{
+ DisasmStartOne(s);
+ DisasmOpSizeFromb76();
+ dbglog_writeCStr(" ");
+ DisasmModeRegister(0, Disasm_reg);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(0, Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROC DisasmAAs_xxxxdddxssxxxrrr(char *s)
+{
+ DisasmStartOne(s);
+ DisasmOpSizeFromb76();
+ dbglog_writeCStr(" ");
+ DisasmModeRegister(4, Disasm_reg);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(4, Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmTst(void)
+{
+ /* Tst 01001010ssmmmrrr */
+ Disasm_xxxxxxxxssmmmrrr("TST");
+}
+
+LOCALPROCUSEDONCE DisasmCompare(void)
+{
+ /* Cmp 1011ddd0ssmmmrrr */
+ DisasmEaD_xxxxdddxssmmmrrr("CMP");
+}
+
+LOCALPROCUSEDONCE DisasmCmpI(void)
+{
+ /* CMPI 00001100ssmmmrrr */
+ DisasmI_xxxxxxxxssmmmrrr("CMP");
+}
+
+LOCALPROCUSEDONCE DisasmCmpM(void)
+{
+ /* CmpM 1011ddd1ss001rrr */
+ DisasmsAA_xxxxdddxssxxxrrr("CMP");
+}
+
+LOCALPROC DisasmCC(void)
+{
+ switch ((Disasm_opcode >> 8) & 15) {
+ case 0: dbglog_writeCStr("T"); break;
+ case 1: dbglog_writeCStr("F"); break;
+ case 2: dbglog_writeCStr("HI"); break;
+ case 3: dbglog_writeCStr("LS"); break;
+ case 4: dbglog_writeCStr("CC"); break;
+ case 5: dbglog_writeCStr("CS"); break;
+ case 6: dbglog_writeCStr("NE"); break;
+ case 7: dbglog_writeCStr("EQ"); break;
+ case 8: dbglog_writeCStr("VC"); break;
+ case 9: dbglog_writeCStr("VS"); break;
+ case 10: dbglog_writeCStr("P"); break;
+ case 11: dbglog_writeCStr("MI"); break;
+ case 12: dbglog_writeCStr("GE"); break;
+ case 13: dbglog_writeCStr("LT"); break;
+ case 14: dbglog_writeCStr("GT"); break;
+ case 15: dbglog_writeCStr("LE"); break;
+ default: break; /* shouldn't get here */
+ }
+}
+
+LOCALPROCUSEDONCE DisasmBcc(void)
+{
+ /* Bcc 0110ccccnnnnnnnn */
+ ui5b src = ((ui5b)Disasm_opcode) & 255;
+ ui5r s = Disasm_pc;
+
+ if (0 == ((Disasm_opcode >> 8) & 15)) {
+ DisasmStartOne("BRA");
+ } else {
+ DisasmStartOne("B");
+ DisasmCC();
+ }
+ dbglog_writeCStr(" ");
+
+ if (src == 0) {
+ s += ui5r_FromSWord(Disasm_nextiword());
+ } else
+#if Use68020
+ if (src == 255) {
+ s += ui5r_FromSLong(Disasm_nextilong());
+ /* ReportAbnormal("long branch in DoCode6"); */
+ /* Used by various Apps */
+ } else
+#endif
+ {
+ s += ui5r_FromSByte(src);
+ }
+ dbglog_writeHex(s);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmDBcc(void)
+{
+ /* DBcc 0101cccc11001ddd */
+
+ ui5r s = Disasm_pc;
+
+ DisasmStartOne("DB");
+ DisasmCC();
+
+ dbglog_writeCStr(" D");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeCStr(", ");
+
+ s += (si5b)(si4b)Disasm_nextiword();
+ dbglog_writeHex(s);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmSwap(void)
+{
+ /* Swap 0100100001000rrr */
+
+ DisasmStartOne("SWAP D");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROC DisasmMove(void) /* MOVE */
+{
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(Disasm_md6, Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmMoveL(void)
+{
+ DisasmStartOne("MOVE.L ");
+ Disasm_opsize = 4;
+ DisasmMove();
+}
+
+LOCALPROCUSEDONCE DisasmMoveW(void)
+{
+ DisasmStartOne("MOVE.W ");
+ Disasm_opsize = 2;
+ DisasmMove();
+}
+
+LOCALPROCUSEDONCE DisasmMoveB(void)
+{
+ DisasmStartOne("MOVE.B ");
+ Disasm_opsize = 1;
+ DisasmMove();
+}
+
+LOCALPROCUSEDONCE DisasmMoveAL(void)
+{
+ DisasmStartOne("MOVEA.L ");
+ Disasm_opsize = 4;
+ DisasmMove();
+}
+
+LOCALPROCUSEDONCE DisasmMoveAW(void)
+{
+ DisasmStartOne("MOVEA.W ");
+ Disasm_opsize = 2;
+ DisasmMove();
+}
+
+LOCALPROCUSEDONCE DisasmMoveQ(void)
+{
+ /* MoveQ 0111ddd0nnnnnnnn */
+ DisasmStartOne("MOVEQ #");
+ dbglog_writeHex(ui5r_FromSByte(Disasm_opcode));
+ dbglog_writeCStr(", D");
+ dbglog_writeHex(Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmAddEaR(void)
+{
+ DisasmEaD_xxxxdddxssmmmrrr("ADD");
+}
+
+LOCALPROCUSEDONCE DisasmAddQ(void)
+{
+ /* AddQ 0101nnn0ssmmmrrr */
+ Disasm_xxxxnnnxssmmmrrr("ADDQ");
+}
+
+LOCALPROCUSEDONCE DisasmAddI(void)
+{
+ DisasmI_xxxxxxxxssmmmrrr("ADDI");
+}
+
+LOCALPROCUSEDONCE DisasmAddREa(void)
+{
+ DisasmDEa_xxxxdddxssmmmrrr("ADD");
+}
+
+LOCALPROCUSEDONCE DisasmSubEaR(void)
+{
+ DisasmEaD_xxxxdddxssmmmrrr("SUB");
+}
+
+LOCALPROCUSEDONCE DisasmSubQ(void)
+{
+ /* SubQ 0101nnn1ssmmmrrr */
+ Disasm_xxxxnnnxssmmmrrr("SUBQ");
+}
+
+LOCALPROCUSEDONCE DisasmSubI(void)
+{
+ DisasmI_xxxxxxxxssmmmrrr("SUBI");
+}
+
+LOCALPROCUSEDONCE DisasmSubREa(void)
+{
+ DisasmDEa_xxxxdddxssmmmrrr("SUB");
+}
+
+LOCALPROCUSEDONCE DisasmLea(void)
+{
+ /* Lea 0100aaa111mmmrrr */
+ DisasmStartOne("LEA ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeCStr(", A");
+ dbglog_writeHex(Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmPEA(void)
+{
+ /* PEA 0100100001mmmrrr */
+ DisasmStartOne("PEA ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmALine(void)
+{
+ DisasmStartOne("$");
+ dbglog_writeHex(Disasm_opcode);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmBsr(void)
+{
+ ui5b src = ((ui5b)Disasm_opcode) & 255;
+ ui5r s = Disasm_pc;
+
+ DisasmStartOne("BSR ");
+ if (src == 0) {
+ s += (si5b)(si4b)Disasm_nextiword();
+ } else
+#if Use68020
+ if (src == 255) {
+ s += (si5b)Disasm_nextilong();
+ /* ReportAbnormal("long branch in DoCode6"); */
+ /* Used by various Apps */
+ } else
+#endif
+ {
+ s += (si5b)(si3b)src;
+ }
+ dbglog_writeHex(s);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmJsr(void)
+{
+ /* Jsr 0100111010mmmrrr */
+ DisasmStartOne("JSR ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmLinkA6(void)
+{
+ DisasmStartOne("LINK A6, ");
+ dbglog_writeHex(Disasm_nextiword());
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmMOVEMRmM(void)
+{
+ /* MOVEM reg to mem 0100100011s100rrr */
+ si4b z;
+ ui5r regmask;
+
+ DisasmStartOne("MOVEM");
+ if (Disasm_b76 == 2) {
+ dbglog_writeCStr(".W");
+ } else {
+ dbglog_writeCStr(".L");
+ }
+ dbglog_writeCStr(" ");
+ regmask = Disasm_nextiword();
+
+ for (z = 16; --z >= 0; ) {
+ if ((regmask & (1 << (15 - z))) != 0) {
+ if (z >= 8) {
+ dbglog_writeCStr("A");
+ dbglog_writeHex(z - 8);
+ } else {
+ dbglog_writeCStr("D");
+ dbglog_writeHex(z);
+ }
+ }
+ }
+ dbglog_writeCStr(", -(A");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeCStr(")");
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmMOVEMApR(void)
+{
+ /* MOVEM mem to reg 0100110011s011rrr */
+ si4b z;
+ ui5r regmask;
+
+ regmask = Disasm_nextiword();
+
+ DisasmStartOne("MOVEM");
+ if (Disasm_b76 == 2) {
+ dbglog_writeCStr(".W");
+ } else {
+ dbglog_writeCStr(".L");
+ }
+ dbglog_writeCStr(" (A");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeCStr(")+, ");
+
+ for (z = 0; z < 16; ++z) {
+ if ((regmask & (1 << z)) != 0) {
+ if (z >= 8) {
+ dbglog_writeCStr("A");
+ dbglog_writeHex(z - 8);
+ } else {
+ dbglog_writeCStr("D");
+ dbglog_writeHex(z);
+ }
+ }
+ }
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmUnlkA6(void)
+{
+ DisasmStartOne("UNLINK A6");
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmRts(void)
+{
+ /* Rts 0100111001110101 */
+ DisasmStartOne("RTS");
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmJmp(void)
+{
+ /* JMP 0100111011mmmrrr */
+ DisasmStartOne("JMP ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmClr(void)
+{
+ /* Clr 01000010ssmmmrrr */
+ Disasm_xxxxxxxxssmmmrrr("CLR");
+}
+
+LOCALPROCUSEDONCE DisasmAddA(void)
+{
+ /* ADDA 1101dddm11mmmrrr */
+ DisasmEaA_xxxxdddsxxmmmrrr("ADDA");
+}
+
+LOCALPROCUSEDONCE DisasmAddQA(void)
+{
+ /* 0101nnn0ss001rrr */
+ DisasmStartOne("ADDQA #");
+ dbglog_writeHex(Disasm_octdat(Disasm_rg9));
+ dbglog_writeCStr(", A");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmSubQA(void)
+{
+ /* 0101nnn1ss001rrr */
+ DisasmStartOne("SUBQA #");
+ dbglog_writeHex(Disasm_octdat(Disasm_rg9));
+ dbglog_writeCStr(", A");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmSubA(void)
+{
+ /* SUBA 1001dddm11mmmrrr */
+ DisasmEaA_xxxxdddsxxmmmrrr("SUBA");
+}
+
+LOCALPROCUSEDONCE DisasmCmpA(void)
+{
+ DisasmStartOne("CMPA ");
+ Disasm_opsize = Disasm_b8 * 2 + 2;
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeCStr(", A");
+ dbglog_writeHex(Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmAddXd(void)
+{
+ DisasmDD_xxxxdddxssxxxrrr("ADDX");
+}
+
+LOCALPROCUSEDONCE DisasmAddXm(void)
+{
+ DisasmAAs_xxxxdddxssxxxrrr("ADDX");
+}
+
+LOCALPROCUSEDONCE DisasmSubXd(void)
+{
+ DisasmDD_xxxxdddxssxxxrrr("SUBX");
+}
+
+LOCALPROCUSEDONCE DisasmSubXm(void)
+{
+ DisasmAAs_xxxxdddxssxxxrrr("SUBX");
+}
+
+LOCALPROC DisasmBinOp1(ui5r x)
+{
+ if (! Disasm_b8) {
+ switch (x) {
+ case 0:
+ DisasmStartOne("ASR");
+ break;
+ case 1:
+ DisasmStartOne("LSR");
+ break;
+ case 2:
+ DisasmStartOne("RXR");
+ break;
+ case 3:
+ DisasmStartOne("ROR");
+ break;
+ default:
+ /* should not get here */
+ break;
+ }
+ } else {
+ switch (x) {
+ case 0:
+ DisasmStartOne("ASL");
+ break;
+ case 1:
+ DisasmStartOne("LSL");
+ break;
+ case 2:
+ DisasmStartOne("RXL");
+ break;
+ case 3:
+ DisasmStartOne("ROL");
+ break;
+ default:
+ /* should not get here */
+ break;
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DisasmRolopNM(void)
+{
+ DisasmBinOp1(Disasm_rg9);
+ dbglog_writeCStr(" ");
+ Disasm_opsize = 2;
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmRolopND(void)
+{
+ /* 1110cccdss0ttddd */
+ DisasmBinOp1(Disasm_mode & 3);
+ DisasmOpSizeFromb76();
+ dbglog_writeCStr(" #");
+ dbglog_writeHex(Disasm_octdat(Disasm_rg9));
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(0, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmRolopDD(void)
+{
+ /* 1110rrrdss1ttddd */
+ DisasmBinOp1(Disasm_mode & 3);
+ DisasmOpSizeFromb76();
+ dbglog_writeCStr(" ");
+ DisasmModeRegister(0, Disasm_rg9);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(0, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROC DisasmBinBitOp1(void)
+{
+ switch (Disasm_b76) {
+ case 0:
+ DisasmStartOne("BTST");
+ break;
+ case 1:
+ DisasmStartOne("BCHG");
+ break;
+ case 2:
+ DisasmStartOne("BCLR");
+ break;
+ case 3:
+ DisasmStartOne("BSET");
+ break;
+ default:
+ /* should not get here */
+ break;
+ }
+}
+
+LOCALPROCUSEDONCE DisasmBitOpDD(void)
+{
+ /* dynamic bit, Opcode = 0000ddd1tt000rrr */
+ DisasmBinBitOp1();
+ Disasm_opsize = 4;
+ dbglog_writeCStr(" ");
+ DisasmModeRegister(0, Disasm_rg9);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(0, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmBitOpDM(void)
+{
+ /* dynamic bit, Opcode = 0000ddd1ttmmmrrr */
+ DisasmBinBitOp1();
+ Disasm_opsize = 1;
+ dbglog_writeCStr(" ");
+ DisasmModeRegister(0, Disasm_rg9);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(Disasm_mode, Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmBitOpND(void)
+{
+ /* static bit 00001010tt000rrr */
+ DisasmBinBitOp1();
+ Disasm_opsize = 4;
+ dbglog_writeCStr(" #");
+ dbglog_writeHex(ui5r_FromSByte(Disasm_nextibyte()));
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(0, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmBitOpNM(void)
+{
+ /* static bit 00001010ttmmmrrr */
+ DisasmBinBitOp1();
+ Disasm_opsize = 1;
+ dbglog_writeCStr(" #");
+ dbglog_writeHex(ui5r_FromSByte(Disasm_nextibyte()));
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(Disasm_mode, Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmAndI(void)
+{
+ DisasmI_xxxxxxxxssmmmrrr("ANDI");
+}
+
+LOCALPROCUSEDONCE DisasmAndDEa(void)
+{
+ /* And 1100ddd1ssmmmrrr */
+ DisasmDEa_xxxxdddxssmmmrrr("AND");
+}
+
+LOCALPROCUSEDONCE DisasmAndEaD(void)
+{
+ /* And 1100ddd0ssmmmrrr */
+ DisasmEaD_xxxxdddxssmmmrrr("AND");
+}
+
+LOCALPROCUSEDONCE DisasmOrI(void)
+{
+ DisasmI_xxxxxxxxssmmmrrr("ORI");
+}
+
+LOCALPROCUSEDONCE DisasmOrDEa(void)
+{
+ /* OR 1000ddd1ssmmmrrr */
+ DisasmDEa_xxxxdddxssmmmrrr("OR");
+}
+
+LOCALPROCUSEDONCE DisasmOrEaD(void)
+{
+ /* OR 1000ddd0ssmmmrrr */
+ DisasmEaD_xxxxdddxssmmmrrr("OR");
+}
+
+LOCALPROCUSEDONCE DisasmEorI(void)
+{
+ DisasmI_xxxxxxxxssmmmrrr("EORI");
+}
+
+LOCALPROCUSEDONCE DisasmEor(void)
+{
+ /* Eor 1011ddd1ssmmmrrr */
+ DisasmDEa_xxxxdddxssmmmrrr("EOR");
+}
+
+LOCALPROCUSEDONCE DisasmNot(void)
+{
+ /* Not 01000110ssmmmrrr */
+ Disasm_xxxxxxxxssmmmrrr("NOT");
+}
+
+LOCALPROCUSEDONCE DisasmScc(void)
+{
+ /* Scc 0101cccc11mmmrrr */
+ Disasm_opsize = 1;
+ DisasmStartOne("S");
+ DisasmCC();
+ dbglog_writeCStr(" ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmEXTL(void)
+{
+ DisasmStartOne("EXT.L D");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmEXTW(void)
+{
+ DisasmStartOne("EXT.W D");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmNeg(void)
+{
+ /* Neg 01000100ssmmmrrr */
+ Disasm_xxxxxxxxssmmmrrr("NEG");
+}
+
+LOCALPROCUSEDONCE DisasmNegX(void)
+{
+ /* NegX 01000000ssmmmrrr */
+ Disasm_xxxxxxxxssmmmrrr("NEGX");
+}
+
+LOCALPROCUSEDONCE DisasmMulU(void)
+{
+ /* MulU 1100ddd011mmmrrr */
+ Disasm_opsize = 2;
+ DisasmStartOne("MULU ");
+
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(0, Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmMulS(void)
+{
+ /* MulS 1100ddd111mmmrrr */
+ Disasm_opsize = 2;
+ DisasmStartOne("MULS ");
+
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(0, Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmDivU(void)
+{
+ /* DivU 1000ddd011mmmrrr */
+
+ Disasm_opsize = 2;
+ DisasmStartOne("DIVU ");
+
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(0, Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmDivS(void)
+{
+ /* DivS 1000ddd111mmmrrr */
+
+ Disasm_opsize = 2;
+ DisasmStartOne("DIVS ");
+
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(0, Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmExgdd(void)
+{
+ /* Exg 1100ddd101000rrr */
+
+ Disasm_opsize = 4;
+ DisasmStartOne("EXG ");
+ DisasmModeRegister(0, Disasm_rg9);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(0, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmExgaa(void)
+{
+ /* Exg 1100ddd101001rrr */
+
+ Disasm_opsize = 4;
+ DisasmStartOne("EXG ");
+ DisasmModeRegister(1, Disasm_rg9);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(1, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmExgda(void)
+{
+ /* Exg 1100ddd110001rrr */
+
+ Disasm_opsize = 4;
+ DisasmStartOne("EXG ");
+ DisasmModeRegister(0, Disasm_rg9);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(1, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmMoveCCREa(void)
+{
+ /* Move from CCR 0100001011mmmrrr */
+ Disasm_opsize = 2;
+ DisasmStartOne("MOVE CCR, ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmMoveEaCR(void)
+{
+ /* 0100010011mmmrrr */
+ Disasm_opsize = 2;
+ DisasmStartOne("MOVE ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeCStr(", CCR");
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmMoveSREa(void)
+{
+ /* Move from SR 0100000011mmmrrr */
+ Disasm_opsize = 2;
+ DisasmStartOne("MOVE SR, ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmMoveEaSR(void)
+{
+ /* 0100011011mmmrrr */
+ Disasm_opsize = 2;
+ DisasmStartOne("MOVE ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeCStr(", SR");
+ dbglog_writeReturn();
+}
+
+LOCALPROC DisasmBinOpStatusCCR(void)
+{
+ switch (Disasm_rg9) {
+ case 0 :
+ DisasmStartOne("OR");
+ break;
+ case 1 :
+ DisasmStartOne("AND");
+ break;
+ case 5 :
+ DisasmStartOne("EOR");
+ break;
+ default: /* should not happen */
+ break;
+ }
+ DisasmOpSizeFromb76();
+ dbglog_writeCStr(" #");
+ dbglog_writeHex(ui5r_FromSWord(Disasm_nextiword()));
+ if (Disasm_b76 != 0) {
+ dbglog_writeCStr(", SR");
+ } else {
+ dbglog_writeCStr(", CCR");
+ }
+ dbglog_writeReturn();
+}
+
+LOCALPROC disasmreglist(si4b direction, ui5b m1, ui5b r1)
+{
+ si4b z;
+ ui5r regmask;
+
+ DisasmStartOne("MOVEM");
+
+ regmask = Disasm_nextiword();
+ Disasm_opsize = 2 * Disasm_b76 - 2;
+
+ if (Disasm_opsize == 2) {
+ dbglog_writeCStr(".W");
+ } else {
+ dbglog_writeCStr(".L");
+ }
+
+ dbglog_writeCStr(" ");
+
+ if (direction != 0) {
+ DisasmModeRegister(m1, r1);
+ dbglog_writeCStr(", ");
+ }
+
+ for (z = 0; z < 16; ++z) {
+ if ((regmask & (1 << z)) != 0) {
+ if (z >= 8) {
+ dbglog_writeCStr("A");
+ dbglog_writeHex(z - 8);
+ } else {
+ dbglog_writeCStr("D");
+ dbglog_writeHex(z);
+ }
+ }
+ }
+
+ if (direction == 0) {
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(m1, r1);
+ }
+
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmMOVEMrm(void)
+{
+ /* MOVEM reg to mem 010010001ssmmmrrr */
+ disasmreglist(0, Disasm_mode, Disasm_reg);
+}
+
+LOCALPROCUSEDONCE DisasmMOVEMmr(void)
+{
+ /* MOVEM mem to reg 0100110011smmmrrr */
+ disasmreglist(1, Disasm_mode, Disasm_reg);
+}
+
+LOCALPROC DisasmByteBinOp(char *s, ui5b m1, ui5b r1, ui5b m2, ui5b r2)
+{
+ DisasmStartOne(s);
+ dbglog_writeCStr(" ");
+ DisasmOpSizeFromb76();
+ DisasmModeRegister(m1, r1);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(m2, r2);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmAbcdr(void)
+{
+ /* ABCD 1100ddd100000rrr */
+ DisasmByteBinOp("ABCD", 0, Disasm_reg, 0, Disasm_rg9);
+}
+
+LOCALPROCUSEDONCE DisasmAbcdm(void)
+{
+ /* ABCD 1100ddd100001rrr */
+ DisasmByteBinOp("ABCD", 4, Disasm_reg, 4, Disasm_rg9);
+}
+
+LOCALPROCUSEDONCE DisasmSbcdr(void)
+{
+ /* SBCD 1000xxx100000xxx */
+ DisasmByteBinOp("ABCD", 0, Disasm_reg, 0, Disasm_rg9);
+}
+
+LOCALPROCUSEDONCE DisasmSbcdm(void)
+{
+ /* SBCD 1000xxx100001xxx */
+ DisasmByteBinOp("ABCD", 4, Disasm_reg, 4, Disasm_rg9);
+}
+
+LOCALPROCUSEDONCE DisasmNbcd(void)
+{
+ /* Nbcd 0100100000mmmrrr */
+ Disasm_xxxxxxxxssmmmrrr("NBCD");
+}
+
+LOCALPROCUSEDONCE DisasmRte(void)
+{
+ /* Rte 0100111001110011 */
+ DisasmStartOne("RTE");
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmNop(void)
+{
+ /* Nop 0100111001110001 */
+ DisasmStartOne("NOP");
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmMoveP(void)
+{
+ /* MoveP 0000ddd1mm001aaa */
+
+ DisasmStartOne("MOVEP");
+ if (0 == (Disasm_b76 & 1)) {
+ Disasm_opsize = 2;
+ dbglog_writeCStr(".W");
+ } else {
+ Disasm_opsize = 4;
+ dbglog_writeCStr(".L");
+ }
+ dbglog_writeCStr(" ");
+ if (Disasm_b76 < 2) {
+ DisasmModeRegister(5, Disasm_reg);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(0, Disasm_rg9);
+ } else {
+ DisasmModeRegister(0, Disasm_rg9);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(5, Disasm_reg);
+ }
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmIllegal(void)
+{
+ DisasmStartOne("ILLEGAL");
+ dbglog_writeReturn();
+}
+
+LOCALPROC DisasmCheck(void)
+{
+ DisasmStartOne("CHK");
+ if (2 == Disasm_opsize) {
+ dbglog_writeCStr(".W");
+ } else {
+ dbglog_writeCStr(".L");
+ }
+ dbglog_writeCStr(" ");
+
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(0, Disasm_rg9);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmChkW(void)
+{
+ /* Chk.W 0100ddd110mmmrrr */
+ Disasm_opsize = 2;
+ DisasmCheck();
+}
+
+LOCALPROCUSEDONCE DisasmTrap(void)
+{
+ /* Trap 010011100100vvvv */
+ DisasmStartOne("TRAP ");
+ dbglog_writeHex(Disasm_opcode & 15);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmTrapV(void)
+{
+ /* TrapV 0100111001110110 */
+ DisasmStartOne("TRAPV");
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmRtr(void)
+{
+ /* Rtr 0100111001110111 */
+ DisasmStartOne("RTR");
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmLink(void)
+{
+ DisasmStartOne("LINK A");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeCStr(", ");
+ dbglog_writeHex(Disasm_nextiword());
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmUnlk(void)
+{
+ DisasmStartOne("UNLINK A");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmMoveRUSP(void)
+{
+ /* MOVE USP 0100111001100aaa */
+ DisasmStartOne("MOVE A");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeCStr(", USP");
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmMoveUSPR(void)
+{
+ /* MOVE USP 0100111001101aaa */
+ DisasmStartOne("MOVE USP, A");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmTas(void)
+{
+ /* Tas 0100101011mmmrrr */
+ Disasm_opsize = 1;
+ DisasmStartOne("TAS");
+ dbglog_writeCStr(" ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmFLine(void)
+{
+ DisasmStartOne("$");
+ dbglog_writeHex(Disasm_opcode);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmCallMorRtm(void)
+{
+ DisasmStartOne("CALLM #");
+ dbglog_writeHex(Disasm_nextibyte());
+ dbglog_writeCStr(", ");
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmStop(void)
+{
+ /* Stop 0100111001110010 */
+ DisasmStartOne("STOP #");
+ dbglog_writeHex(Disasm_nextiword());
+ dbglog_writeReturn();
+}
+
+LOCALPROCUSEDONCE DisasmReset(void)
+{
+ /* Reset 0100111001100000 */
+ DisasmStartOne("RESET");
+ dbglog_writeReturn();
+}
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmEXTBL(void)
+{
+ /* EXTB.L */
+ DisasmStartOne("EXTB.L D");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeReturn();
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmTRAPcc(void)
+{
+ /* TRAPcc 0101cccc11111sss */
+
+ DisasmStartOne("TRAP");
+ DisasmCC();
+
+ switch (Disasm_reg) {
+ case 2:
+ dbglog_writeCStr(" ");
+ dbglog_writeHex(Disasm_nextiword());
+ break;
+ case 3:
+ dbglog_writeCStr(" ");
+ dbglog_writeHex(Disasm_nextilong());
+ break;
+ case 4:
+ /* no optional data */
+ break;
+ default:
+ /* illegal format */
+ break;
+ }
+
+ dbglog_writeReturn();
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmChkL(void)
+{
+ /* Chk.L 0100ddd100mmmrrr */
+ Disasm_opsize = 4;
+ DisasmCheck();
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmBkpt(void)
+{
+ /* BKPT 0100100001001rrr */
+ DisasmStartOne("BKPT #");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeReturn();
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmDivL(void)
+{
+ /* DIVU 0100110001mmmrrr 0rrr0s0000000rrr */
+ /* DIVS 0100110001mmmrrr 0rrr1s0000000rrr */
+ Disasm_opsize = 4;
+ DisasmStartOne("DIV");
+
+ {
+ ui4b extra = Disasm_nextiword();
+ ui5b rDr = extra & 7;
+ ui5b rDq = (extra >> 12) & 7;
+
+ if (extra & 0x0800) {
+ dbglog_writeCStr("S");
+ } else {
+ dbglog_writeCStr("U");
+ }
+ if (extra & 0x0400) {
+ dbglog_writeCStr("L");
+ }
+ dbglog_writeCStr(".L ");
+
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+
+ dbglog_writeCStr(", ");
+
+ if (rDr != rDq) {
+ dbglog_writeCStr("D");
+ dbglog_writeHex(rDr);
+ dbglog_writeCStr(":");
+ }
+ dbglog_writeCStr("D");
+ dbglog_writeHex(rDq);
+ }
+
+ dbglog_writeReturn();
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmMulL(void)
+{
+ /* MULU 0100110000mmmrrr 0rrr0s0000000rrr */
+ /* MULS 0100110000mmmrrr 0rrr1s0000000rrr */
+
+ Disasm_opsize = 4;
+ DisasmStartOne("MUL");
+
+ {
+ ui4b extra = Disasm_nextiword();
+ ui5b rhi = extra & 7;
+ ui5b rlo = (extra >> 12) & 7;
+
+ if (extra & 0x0800) {
+ dbglog_writeCStr("S");
+ } else {
+ dbglog_writeCStr("U");
+ }
+
+ dbglog_writeCStr(".L ");
+
+ DisasmModeRegister(Disasm_mode, Disasm_reg);
+
+ dbglog_writeCStr(", ");
+
+ if (extra & 0x400) {
+ dbglog_writeCStr("D");
+ dbglog_writeHex(rhi);
+ dbglog_writeCStr(":");
+ }
+ dbglog_writeCStr("D");
+ dbglog_writeHex(rlo);
+ }
+
+ dbglog_writeReturn();
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmRtd(void)
+{
+ /* Rtd 0100111001110100 */
+ DisasmStartOne("RTD #");
+ dbglog_writeHex((si5b)(si4b)Disasm_nextiword());
+ dbglog_writeReturn();
+}
+#endif
+
+#if Use68020
+LOCALPROC DisasmControlReg(ui4r i)
+{
+ switch (i) {
+ case 0x0000:
+ dbglog_writeCStr("SFC");
+ break;
+ case 0x0001:
+ dbglog_writeCStr("DFC");
+ break;
+ case 0x0002:
+ dbglog_writeCStr("CACR");
+ break;
+ case 0x0800:
+ dbglog_writeCStr("USP");
+ break;
+ case 0x0801:
+ dbglog_writeCStr("VBR");
+ break;
+ case 0x0802:
+ dbglog_writeCStr("CAAR");
+ break;
+ case 0x0803:
+ dbglog_writeCStr("MSP");
+ break;
+ case 0x0804:
+ dbglog_writeCStr("ISP");
+ break;
+ default:
+ dbglog_writeCStr("???");
+ break;
+ }
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmMoveC(void)
+{
+ /* MOVEC 010011100111101m */
+ DisasmStartOne("MOVEC ");
+
+ {
+ ui4b src = Disasm_nextiword();
+ int regno = (src >> 12) & 0x0F;
+ switch (Disasm_reg) {
+ case 2:
+ DisasmControlReg(src & 0x0FFF);
+ dbglog_writeCStr(", ");
+ if (regno < 8) {
+ dbglog_writeCStr("D");
+ } else {
+ dbglog_writeCStr("A");
+ }
+ dbglog_writeHex(regno & 7);
+ break;
+ case 3:
+ if (regno < 8) {
+ dbglog_writeCStr("D");
+ } else {
+ dbglog_writeCStr("A");
+ }
+ dbglog_writeHex(regno & 7);
+
+ dbglog_writeCStr(", ");
+
+ DisasmControlReg(src & 0x0FFF);
+ break;
+ default:
+ /* illegal */
+ break;
+ }
+ }
+
+ dbglog_writeReturn();
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmLinkL(void)
+{
+ /* Link.L 0100100000001rrr */
+ DisasmStartOne("LINK.L A");
+ dbglog_writeHex(Disasm_reg);
+ dbglog_writeCStr(", ");
+ dbglog_writeHex(Disasm_nextilong());
+ dbglog_writeReturn();
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmPack(void)
+{
+ DisasmStartOne("PACK ???");
+ dbglog_writeReturn();
+ /* DoCodePack */
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmUnpk(void)
+{
+ DisasmStartOne("UNPK ???");
+ dbglog_writeReturn();
+ /* DoCodeUnpk */
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmCHK2orCMP2(void)
+{
+ DisasmStartOne("CHK2/CMP2 ???");
+ dbglog_writeReturn();
+ /* DoCHK2orCMP2 */
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmCAS2(void)
+{
+ DisasmStartOne("CAS2 ???");
+ dbglog_writeReturn();
+ /* DoCAS2 */
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmCAS(void)
+{
+ DisasmStartOne("CAS ???");
+ dbglog_writeReturn();
+ /* DoDoCAS */
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmMOVES(void)
+{
+ DisasmStartOne("MOVES ???");
+ dbglog_writeReturn();
+ /* DoMOVES */
+}
+#endif
+
+#if Use68020
+LOCALPROCUSEDONCE DisasmBitField(void)
+{
+ DisasmStartOne("BitField ???");
+ dbglog_writeReturn();
+ /* DoBitField */
+}
+#endif
+
+LOCALFUNC blnr IsValidAddrMode(void)
+{
+ return (Disasm_mode != 7) || (Disasm_reg < 5);
+}
+
+LOCALFUNC blnr IsValidDstAddrMode(void)
+{
+ return (Disasm_md6 != 7) || (Disasm_rg9 < 2);
+}
+
+LOCALFUNC blnr IsValidDataAltAddrMode(void)
+{
+ blnr IsOk;
+
+ switch (Disasm_mode) {
+ case 1:
+ default: /* keep compiler happy */
+ IsOk = falseblnr;
+ break;
+ case 0:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ IsOk = trueblnr;
+ break;
+ case 7:
+ IsOk = Disasm_reg < 2;
+ break;
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr IsValidDataAddrMode(void)
+{
+ blnr IsOk;
+
+ switch (Disasm_mode) {
+ case 1:
+ default: /* keep compiler happy */
+ IsOk = falseblnr;
+ break;
+ case 0:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ IsOk = trueblnr;
+ break;
+ case 7:
+ IsOk = Disasm_reg < 5;
+ break;
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr IsValidControlAddrMode(void)
+{
+ blnr IsOk;
+
+ switch (Disasm_mode) {
+ case 0:
+ case 1:
+ case 3:
+ case 4:
+ default: /* keep compiler happy */
+ IsOk = falseblnr;
+ break;
+ case 2:
+ case 5:
+ case 6:
+ IsOk = trueblnr;
+ break;
+ case 7:
+ IsOk = Disasm_reg < 4;
+ break;
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr IsValidControlAltAddrMode(void)
+{
+ blnr IsOk;
+
+ switch (Disasm_mode) {
+ case 0:
+ case 1:
+ case 3:
+ case 4:
+ default: /* keep compiler happy */
+ IsOk = falseblnr;
+ break;
+ case 2:
+ case 5:
+ case 6:
+ IsOk = trueblnr;
+ break;
+ case 7:
+ IsOk = Disasm_reg < 2;
+ break;
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr IsValidAltMemAddrMode(void)
+{
+ blnr IsOk;
+
+ switch (Disasm_mode) {
+ case 0:
+ case 1:
+ default: /* keep compiler happy */
+ IsOk = falseblnr;
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ IsOk = trueblnr;
+ break;
+ case 7:
+ IsOk = Disasm_reg < 2;
+ break;
+ }
+
+ return IsOk;
+}
+
+LOCALPROCUSEDONCE DisasmCode0(void)
+{
+ if (Disasm_b8 == 1) {
+ if (Disasm_mode == 1) {
+ /* MoveP 0000ddd1mm001aaa */
+ DisasmMoveP();
+ } else {
+ /* dynamic bit, Opcode = 0000ddd1ttmmmrrr */
+ if (Disasm_mode == 0) {
+ DisasmBitOpDD();
+ } else {
+ if (Disasm_b76 == 0) {
+ if (IsValidDataAddrMode()) {
+ DisasmBitOpDM();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+ if (IsValidDataAltAddrMode()) {
+ DisasmBitOpDM();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ }
+ }
+ } else {
+ if (Disasm_rg9 == 4) {
+ /* static bit 00001010ssmmmrrr */
+ if (Disasm_mode == 0) {
+ DisasmBitOpND();
+ } else {
+ if (Disasm_b76 == 0) {
+ if ((Disasm_mode == 7) && (Disasm_reg == 4)) {
+ DisasmIllegal();
+ } else {
+ if (IsValidDataAddrMode()) {
+ DisasmBitOpNM();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ } else {
+ if (IsValidDataAltAddrMode()) {
+ DisasmBitOpNM();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ }
+ } else
+ if (Disasm_b76 == 3) {
+#if Use68020
+ if (Disasm_rg9 < 3) {
+ /* CHK2 or CMP2 00000ss011mmmrrr */
+ if (IsValidControlAddrMode()) {
+ DisasmCHK2orCMP2();
+ } else {
+ DisasmIllegal();
+ }
+ } else
+ if (Disasm_rg9 >= 5) {
+ if ((Disasm_mode == 7) && (Disasm_reg == 4)) {
+ /* CAS2 00001ss011111100 */
+ DisasmCAS2();
+ } else {
+ /* CAS 00001ss011mmmrrr */
+ DisasmCAS2();
+ }
+ } else
+ if (Disasm_rg9 == 3) {
+ /* CALLM or RTM 0000011011mmmrrr */
+ DisasmCallMorRtm();
+ } else
+#endif
+ {
+ DisasmIllegal();
+ }
+ } else
+ if (Disasm_rg9 == 6) {
+ /* CMPI 00001100ssmmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmCmpI();
+ } else {
+ DisasmIllegal();
+ }
+ } else if (Disasm_rg9 == 7) {
+#if Use68020
+ /* MoveS 00001110ssmmmrrr */
+ if (IsValidAltMemAddrMode()) {
+ DisasmMoveSREa();
+ } else {
+ DisasmIllegal();
+ }
+#else
+ DisasmIllegal();
+#endif
+ } else {
+ if ((Disasm_mode == 7) && (Disasm_reg == 4)) {
+ switch (Disasm_rg9) {
+ case 0:
+ case 1:
+ case 5:
+ DisasmBinOpStatusCCR();
+ break;
+ default:
+ DisasmIllegal();
+ break;
+ }
+ } else {
+ if (! IsValidDataAltAddrMode()) {
+ DisasmIllegal();
+ } else {
+ switch (Disasm_rg9) {
+ case 0:
+ DisasmOrI();
+ break;
+ case 1:
+ DisasmAndI();
+ break;
+ case 2:
+ DisasmSubI();
+ break;
+ case 3:
+ DisasmAddI();
+ break;
+ case 5:
+ DisasmEorI();
+ break;
+ default:
+ /*
+ for compiler.
+ should be 0, 1, 2, 3, or 5
+ */
+ DisasmIllegal();
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCode1(void)
+{
+ if ((Disasm_mode == 1) || ! IsValidAddrMode()) {
+ DisasmIllegal();
+ } else if (Disasm_md6 == 1) { /* MOVEA */
+ DisasmIllegal();
+ } else if (! IsValidDstAddrMode()) {
+ DisasmIllegal();
+ } else {
+ DisasmMoveB();
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCode2(void)
+{
+ if (Disasm_md6 == 1) { /* MOVEA */
+ if (IsValidAddrMode()) {
+ DisasmMoveAL();
+ } else {
+ DisasmIllegal();
+ }
+ } else if (! IsValidAddrMode()) {
+ DisasmIllegal();
+ } else if (! IsValidDstAddrMode()) {
+ DisasmIllegal();
+ } else {
+ DisasmMoveL();
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCode3(void)
+{
+ if (Disasm_md6 == 1) { /* MOVEA */
+ if (IsValidAddrMode()) {
+ DisasmMoveAW();
+ } else {
+ DisasmIllegal();
+ }
+ } else if (! IsValidAddrMode()) {
+ DisasmIllegal();
+ } else if (! IsValidDstAddrMode()) {
+ DisasmIllegal();
+ } else {
+ DisasmMoveW();
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCode4(void)
+{
+ if (Disasm_b8 != 0) {
+ switch (Disasm_b76) {
+ case 0:
+#if Use68020
+ /* Chk.L 0100ddd100mmmrrr */
+ if (IsValidDataAddrMode()) {
+ DisasmChkL();
+ } else {
+ DisasmIllegal();
+ }
+#else
+ DisasmIllegal();
+#endif
+ break;
+ case 1:
+ DisasmIllegal();
+ break;
+ case 2:
+ /* Chk.W 0100ddd110mmmrrr */
+ if (IsValidDataAddrMode()) {
+ DisasmChkW();
+ } else {
+ DisasmIllegal();
+ }
+ break;
+ case 3:
+ default: /* keep compiler happy */
+#if Use68020
+ if ((0 == Disasm_mode) && (4 == Disasm_rg9)) {
+ DisasmEXTBL();
+ } else
+#endif
+ {
+ /* Lea 0100aaa111mmmrrr */
+ if (IsValidControlAddrMode()) {
+ DisasmLea();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ break;
+ }
+ } else {
+ switch (Disasm_rg9) {
+ case 0:
+ if (Disasm_b76 != 3) {
+ /* NegX 01000000ssmmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmNegX();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+#if Use68020
+/* reference seems incorrect to say not for 68000 */
+#endif
+ /* Move from SR 0100000011mmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmMoveSREa();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ break;
+ case 1:
+ if (Disasm_b76 != 3) {
+ /* Clr 01000010ssmmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmClr();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+#if Use68020
+ /* Move from CCR 0100001011mmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmMoveCCREa();
+ } else {
+ DisasmIllegal();
+ }
+#else
+ DisasmIllegal();
+#endif
+ }
+ break;
+ case 2:
+ if (Disasm_b76 != 3) {
+ /* Neg 01000100ssmmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmNeg();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+ /* Move to CCR 0100010011mmmrrr */
+ if (IsValidDataAddrMode()) {
+ DisasmMoveEaCR();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ break;
+ case 3:
+ if (Disasm_b76 != 3) {
+ /* Not 01000110ssmmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmNot();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+ /* Move from SR 0100011011mmmrrr */
+ if (IsValidDataAddrMode()) {
+ DisasmMoveEaSR();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ break;
+ case 4:
+ switch (Disasm_b76) {
+ case 0:
+#if Use68020
+ if (Disasm_mode == 1) {
+ /* Link.L 0100100000001rrr */
+ DisasmLinkL();
+ } else
+#endif
+ {
+ /* Nbcd 0100100000mmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmNbcd();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ break;
+ case 1:
+ if (Disasm_mode == 0) {
+ /* Swap 0100100001000rrr */
+ DisasmSwap();
+ } else
+#if Use68020
+ if (Disasm_mode == 1) {
+ DisasmBkpt();
+ } else
+#endif
+ {
+ /* PEA 0100100001mmmrrr */
+ if (IsValidControlAddrMode()) {
+ DisasmPEA();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ break;
+ case 2:
+ if (Disasm_mode == 0) {
+ /* EXT.W */
+ DisasmEXTW();
+ } else {
+ /*
+ MOVEM Disasm_reg
+ to mem 01001d001ssmmmrrr
+ */
+ if (Disasm_mode == 4) {
+ DisasmMOVEMRmM();
+ } else {
+ if (IsValidControlAltAddrMode()) {
+ DisasmMOVEMrm();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ }
+ break;
+ case 3:
+ default: /* keep compiler happy */
+ if (Disasm_mode == 0) {
+ /* EXT.L */
+ DisasmEXTL();
+ } else {
+ /*
+ MOVEM Disasm_reg
+ to mem 01001d001ssmmmrrr
+ */
+ if (Disasm_mode == 4) {
+ DisasmMOVEMRmM();
+ } else {
+ if (IsValidControlAltAddrMode()) {
+ DisasmMOVEMrm();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ }
+ break;
+ }
+ break;
+ case 5:
+ if (Disasm_b76 == 3) {
+ if ((Disasm_mode == 7) && (Disasm_reg == 4)) {
+ /* the ILLEGAL instruction */
+ DisasmIllegal();
+ } else {
+ /* Tas 0100101011mmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmTas();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ } else {
+ /* Tst 01001010ssmmmrrr */
+ if (Disasm_b76 == 0) {
+ if (IsValidDataAltAddrMode()) {
+ DisasmTst();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+ if (IsValidAddrMode()) {
+ DisasmTst();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ }
+ break;
+ case 6:
+ if (((Disasm_opcode >> 7) & 1) == 1) {
+ /* MOVEM mem to Disasm_reg 0100110011smmmrrr */
+ if (Disasm_mode == 3) {
+ DisasmMOVEMApR();
+ } else {
+ if (IsValidControlAddrMode()) {
+ DisasmMOVEMmr();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ } else {
+#if Use68020
+ if (((Disasm_opcode >> 6) & 1) == 1) {
+ /* DIVU 0100110001mmmrrr 0rrr0s0000000rrr */
+ /* DIVS 0100110001mmmrrr 0rrr1s0000000rrr */
+ DisasmDivL();
+ } else {
+ /* MULU 0100110000mmmrrr 0rrr0s0000000rrr */
+ /* MULS 0100110000mmmrrr 0rrr1s0000000rrr */
+ DisasmMulL();
+ }
+#else
+ DisasmIllegal();
+#endif
+ }
+ break;
+ case 7:
+ default: /* keep compiler happy */
+ switch (Disasm_b76) {
+ case 0:
+ DisasmIllegal();
+ break;
+ case 1:
+ switch (Disasm_mode) {
+ case 0:
+ case 1:
+ /* Trap 010011100100vvvv */
+ DisasmTrap();
+ break;
+ case 2:
+ /* Link */
+ if (Disasm_reg == 6) {
+ DisasmLinkA6();
+ } else {
+ DisasmLink();
+ }
+ break;
+ case 3:
+ /* Unlk */
+ if (Disasm_reg == 6) {
+ DisasmUnlkA6();
+ } else {
+ DisasmUnlk();
+ }
+ break;
+ case 4:
+ /* MOVE USP 0100111001100aaa */
+ DisasmMoveRUSP();
+ break;
+ case 5:
+ /* MOVE USP 0100111001101aaa */
+ DisasmMoveUSPR();
+ break;
+ case 6:
+ switch (Disasm_reg) {
+ case 0:
+ /* Reset 0100111001100000 */
+ DisasmReset();
+ break;
+ case 1:
+ /*
+ Nop Opcode
+ = 0100111001110001
+ */
+ DisasmNop();
+ break;
+ case 2:
+ /* Stop 0100111001110010 */
+ DisasmStop();
+ break;
+ case 3:
+ /* Rte 0100111001110011 */
+ DisasmRte();
+ break;
+ case 4:
+ /* Rtd 0100111001110100 */
+#if Use68020
+ DisasmRtd();
+#else
+ DisasmIllegal();
+#endif
+ break;
+ case 5:
+ /* Rts 0100111001110101 */
+ DisasmRts();
+ break;
+ case 6:
+ /* TrapV 0100111001110110 */
+ DisasmTrapV();
+ break;
+ case 7:
+ default: /* keep compiler happy */
+ /* Rtr 0100111001110111 */
+ DisasmRtr();
+ break;
+ }
+ break;
+ case 7:
+ default: /* keep compiler happy */
+#if Use68020
+ /* MOVEC 010011100111101m */
+ DisasmMoveC();
+#else
+ DisasmIllegal();
+#endif
+ break;
+ }
+ break;
+ case 2:
+ /* Jsr 0100111010mmmrrr */
+ if (IsValidControlAddrMode()) {
+ DisasmJsr();
+ } else {
+ DisasmIllegal();
+ }
+ break;
+ case 3:
+ default: /* keep compiler happy */
+ /* JMP 0100111011mmmrrr */
+ if (IsValidControlAddrMode()) {
+ DisasmJmp();
+ } else {
+ DisasmIllegal();
+ }
+ break;
+ }
+ break;
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCode5(void)
+{
+ if (Disasm_b76 == 3) {
+ if (Disasm_mode == 1) {
+ /* DBcc 0101cccc11001ddd */
+ DisasmDBcc();
+ } else {
+#if Use68020
+ if ((Disasm_mode == 7) && (Disasm_reg >= 2)) {
+ /* TRAPcc 0101cccc11111sss */
+ DisasmTRAPcc();
+ } else
+#endif
+ {
+ /* Scc 0101cccc11mmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmScc();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ }
+ } else {
+ if (Disasm_mode == 1) {
+ if (Disasm_b8 == 0) {
+ DisasmAddQA(); /* AddQA 0101nnn0ss001rrr */
+ } else {
+ DisasmSubQA(); /* SubQA 0101nnn1ss001rrr */
+ }
+ } else {
+ if (Disasm_b8 == 0) {
+ /* AddQ 0101nnn0ssmmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmAddQ();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+ /* SubQ 0101nnn1ssmmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmSubQ();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCode6(void)
+{
+ ui5b cond = (Disasm_opcode >> 8) & 15;
+
+ if (cond == 1) {
+ /* Bsr 01100001nnnnnnnn */
+ DisasmBsr();
+ } else if (cond == 0) {
+ /* Bra 01100000nnnnnnnn */
+ DisasmBcc();
+ } else {
+ /* Bcc 0110ccccnnnnnnnn */
+ DisasmBcc();
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCode7(void)
+{
+ if (Disasm_b8 == 0) {
+ DisasmMoveQ();
+ } else {
+ DisasmIllegal();
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCode8(void)
+{
+ if (Disasm_b76 == 3) {
+ if (Disasm_b8 == 0) {
+ /* DivU 1000ddd011mmmrrr */
+ if (IsValidDataAddrMode()) {
+ DisasmDivU();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+ /* DivS 1000ddd111mmmrrr */
+ if (IsValidDataAddrMode()) {
+ DisasmDivS();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ } else {
+ if (Disasm_b8 == 0) {
+ /* OR 1000ddd0ssmmmrrr */
+ if (IsValidDataAddrMode()) {
+ DisasmOrEaD();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+ if (Disasm_mode < 2) {
+ switch (Disasm_b76) {
+ case 0:
+ /* SBCD 1000xxx10000mxxx */
+ if (Disasm_mode == 0) {
+ DisasmSbcdr();
+ } else {
+ DisasmSbcdm();
+ }
+ break;
+#if Use68020
+ case 1:
+ /* PACK 1000rrr10100mrrr */
+ DisasmPack();
+ break;
+ case 2:
+ /* UNPK 1000rrr11000mrrr */
+ DisasmUnpk();
+ break;
+#endif
+ default:
+ DisasmIllegal();
+ break;
+ }
+ } else {
+ /* OR 1000ddd1ssmmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmOrDEa();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCode9(void)
+{
+ if (Disasm_b76 == 3) {
+ /* SUBA 1001dddm11mmmrrr */
+ if (IsValidAddrMode()) {
+ DisasmSubA();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+ if (Disasm_b8 == 0) {
+ /* SUB 1001ddd0ssmmmrrr */
+ if (IsValidAddrMode()) {
+ DisasmSubEaR();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+ if (Disasm_mode == 0) {
+ /* SUBX 1001ddd1ss000rrr */
+ DisasmSubXd();
+ } else if (Disasm_mode == 1) {
+ /* SUBX 1001ddd1ss001rrr */
+ DisasmSubXm();
+ } else {
+ /* SUB 1001ddd1ssmmmrrr */
+ if (IsValidAltMemAddrMode()) {
+ DisasmSubREa();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCodeA(void)
+{
+ DisasmALine();
+}
+
+LOCALPROCUSEDONCE DisasmCodeB(void)
+{
+ if (Disasm_b76 == 3) {
+ /* CMPA 1011ddds11mmmrrr */
+ if (IsValidAddrMode()) {
+ DisasmCmpA();
+ } else {
+ DisasmIllegal();
+ }
+ } else if (Disasm_b8 == 1) {
+ if (Disasm_mode == 1) {
+ /* CmpM 1011ddd1ss001rrr */
+ DisasmCmpM();
+ } else {
+ /* Eor 1011ddd1ssmmmrrr */
+ if (IsValidDataAltAddrMode()) {
+ DisasmEor();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ } else {
+ /* Cmp 1011ddd0ssmmmrrr */
+ if (IsValidAddrMode()) {
+ DisasmCompare();
+ } else {
+ DisasmIllegal();
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCodeC(void)
+{
+ if (Disasm_b76 == 3) {
+ if (Disasm_b8 == 0) {
+ /* MulU 1100ddd011mmmrrr */
+ if (IsValidDataAddrMode()) {
+ DisasmMulU();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+ /* MulS 1100ddd111mmmrrr */
+ if (IsValidDataAddrMode()) {
+ DisasmMulS();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ } else {
+ if (Disasm_b8 == 0) {
+ /* And 1100ddd0ssmmmrrr */
+ if (IsValidDataAddrMode()) {
+ DisasmAndEaD();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+ if (Disasm_mode < 2) {
+ switch (Disasm_b76) {
+ case 0:
+ /* ABCD 1100ddd10000mrrr */
+ if (Disasm_mode == 0) {
+ DisasmAbcdr();
+ } else {
+ DisasmAbcdm();
+ }
+ break;
+ case 1:
+ /* Exg 1100ddd10100trrr */
+ if (Disasm_mode == 0) {
+ DisasmExgdd();
+ } else {
+ DisasmExgaa();
+ }
+ break;
+ case 2:
+ default: /* keep compiler happy */
+ if (Disasm_mode == 0) {
+ DisasmIllegal();
+ } else {
+ /* Exg 1100ddd110001rrr */
+ DisasmExgda();
+ }
+ break;
+ }
+ } else {
+ /* And 1100ddd1ssmmmrrr */
+ if (IsValidAltMemAddrMode()) {
+ DisasmAndDEa();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCodeD(void)
+{
+ if (Disasm_b76 == 3) {
+ /* ADDA 1101dddm11mmmrrr */
+ if (IsValidAddrMode()) {
+ DisasmAddA();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+ if (Disasm_b8 == 0) {
+ /* ADD 1101ddd0ssmmmrrr */
+ if (IsValidAddrMode()) {
+ DisasmAddEaR();
+ } else {
+ DisasmIllegal();
+ }
+ } else {
+ if (Disasm_mode == 0) {
+ DisasmAddXd();
+ } else if (Disasm_mode == 1) {
+ DisasmAddXm();
+ } else {
+ /* ADD 1101ddd1ssmmmrrr */
+ if (IsValidAltMemAddrMode()) {
+ DisasmAddREa();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCodeE(void)
+{
+ if (Disasm_b76 == 3) {
+ if ((Disasm_opcode & 0x0800) != 0) {
+#if Use68020
+ /* 11101???11mmmrrr */
+ switch (Disasm_mode) {
+ case 1:
+ case 3:
+ case 4:
+ default: /* keep compiler happy */
+ DisasmIllegal();
+ break;
+ case 0:
+ case 2:
+ case 5:
+ case 6:
+ DisasmBitField();
+ break;
+ case 7:
+ switch (Disasm_reg) {
+ case 0:
+ case 1:
+ DisasmBitField();
+ break;
+ case 2:
+ case 3:
+ switch ((Disasm_opcode >> 8) & 7) {
+ case 0: /* BFTST */
+ case 1: /* BFEXTU */
+ case 3: /* BFEXTS */
+ case 5: /* BFFFO */
+ DisasmBitField();
+ break;
+ default:
+ DisasmIllegal();
+ break;
+ }
+ break;
+ default:
+ DisasmIllegal();
+ break;
+ }
+ break;
+ }
+#else
+ DisasmIllegal();
+#endif
+ } else {
+ /* 11100ttd11mmmddd */
+ if (IsValidAltMemAddrMode()) {
+ DisasmRolopNM();
+ } else {
+ DisasmIllegal();
+ }
+ }
+ } else {
+ if (Disasm_mode < 4) {
+ /* 1110cccdss0ttddd */
+ DisasmRolopND();
+ } else {
+ /* 1110rrrdss1ttddd */
+ DisasmRolopDD();
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DisasmCodeF(void)
+{
+ DisasmFLine();
+}
+
+LOCALPROC m68k_Disasm_one(void)
+{
+ Disasm_opcode = Disasm_nextiword();
+
+ switch (Disasm_opcode >> 12) {
+ case 0x0:
+ DisasmCode0();
+ break;
+ case 0x1:
+ DisasmCode1();
+ break;
+ case 0x2:
+ DisasmCode2();
+ break;
+ case 0x3:
+ DisasmCode3();
+ break;
+ case 0x4:
+ DisasmCode4();
+ break;
+ case 0x5:
+ DisasmCode5();
+ break;
+ case 0x6:
+ DisasmCode6();
+ break;
+ case 0x7:
+ DisasmCode7();
+ break;
+ case 0x8:
+ DisasmCode8();
+ break;
+ case 0x9:
+ DisasmCode9();
+ break;
+ case 0xA:
+ DisasmCodeA();
+ break;
+ case 0xB:
+ DisasmCodeB();
+ break;
+ case 0xC:
+ DisasmCodeC();
+ break;
+ case 0xD:
+ DisasmCodeD();
+ break;
+ case 0xE:
+ DisasmCodeE();
+ break;
+ case 0xF:
+ default: /* keep compiler happy */
+ DisasmCodeF();
+ break;
+ }
+}
+
+#define Ln2SavedPCs 4
+#define NumSavedPCs (1 << Ln2SavedPCs)
+#define SavedPCsMask (NumSavedPCs - 1)
+LOCALVAR ui5r SavedPCs[NumSavedPCs];
+LOCALVAR ui5r SavedPCsIn = 0;
+LOCALVAR ui5r SavedPCsOut = 0;
+
+#define DisasmIncludeCycles 0
+
+LOCALPROCUSEDONCE DisasmOneAndBack(ui5r pc)
+{
+#if DisasmIncludeCycles
+ dbglog_writeHex(GetCuriCount());
+ dbglog_writeCStr(" ");
+#endif
+ dbglog_writeHex(pc);
+ dbglog_writeCStr(" ");
+ Disasm_setpc(pc);
+ m68k_Disasm_one();
+}
+
+LOCALPROCUSEDONCE DisasmSavedPCs(void)
+{
+ ui5r n = SavedPCsIn - SavedPCsOut;
+
+ if (n != 0) {
+ ui5r pc;
+#if DisasmIncludeCycles
+ ui5r i;
+#endif
+#if 0
+ blnr Skipped = falseblnr;
+#endif
+ ui5r j = SavedPCsOut;
+
+ SavedPCsOut = SavedPCsIn;
+ /*
+ do first, prevent recursion
+ in case of error while disassembling.
+ (i.e. failure to read emulated memory.)
+ */
+
+#if DisasmIncludeCycles
+ i = GetCuriCount();
+#endif
+
+ if (n > NumSavedPCs) {
+ n = NumSavedPCs;
+ j = SavedPCsIn - NumSavedPCs;
+ dbglog_writeReturn();
+#if 0
+ Skipped = trueblnr;
+#endif
+ }
+
+ do {
+ --n;
+ pc = SavedPCs[j & SavedPCsMask];
+#if DisasmIncludeCycles
+ dbglog_writeHex(i /* - n */);
+ dbglog_writeCStr("-? ");
+#endif
+ dbglog_writeHex(pc);
+ dbglog_writeCStr(" ");
+ Disasm_setpc(pc);
+ m68k_Disasm_one();
+ ++j;
+ } while (n != 0);
+
+#if 0
+ if (Skipped) {
+ si4b z;
+
+ for (z = 0; z < 16; ++z) {
+ if (z >= 8) {
+ dbglog_writeCStr(" A");
+ dbglog_writeHex(z - 8);
+ } else {
+ dbglog_writeCStr(" D");
+ dbglog_writeHex(z);
+ }
+ dbglog_writeCStr(" = ");
+ dbglog_writeHex(regs.regs[z]);
+ dbglog_writeReturn();
+ }
+ }
+#endif
+ }
+}
+
+LOCALVAR ui5r DisasmCounter = 0;
+
+GLOBALPROC DisasmOneOrSave(ui5r pc)
+{
+ if (0 != DisasmCounter) {
+ DisasmOneAndBack(pc);
+ --DisasmCounter;
+ } else {
+ SavedPCs[SavedPCsIn & SavedPCsMask] = pc;
+ ++SavedPCsIn;
+ }
+}
+
+GLOBALPROC m68k_WantDisasmContext(void)
+{
+ DisasmSavedPCs();
+ DisasmCounter = /* 256 */ 128;
+}
--- /dev/null
+++ b/src/DISAM68K.h
@@ -1,0 +1,29 @@
+/*
+ DISAM68K.h
+
+ Copyright (C) 2010 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ DISAssemble Motorola 68K instructions.
+*/
+
+#ifdef DIS1M68K_H
+#error "header already included"
+#else
+#define DIS1M68K_H
+#endif
+
+EXPORTPROC DisasmOneOrSave(ui5r pc);
+
+EXPORTPROC m68k_WantDisasmContext(void);
--- /dev/null
+++ b/src/ENDIANAC.h
@@ -1,0 +1,135 @@
+/*
+ ENDIANAC.h
+
+ Copyright (C) 2006 Bernd Schmidt, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ ENDIAN ACcess
+
+ Deals with endian issues in memory access.
+
+ This code is adapted from code in the Un*x Amiga Emulator by
+ Bernd Schmidt, as found in vMac by Philip Cummins.
+*/
+
+#ifdef ENDIANAC_H
+#ifndef AllFiles
+#error "header already included"
+#endif
+#else
+#define ENDIANAC_H
+#endif
+
+
+#define do_get_mem_byte(a) ((ui3r)*((ui3b *)(a)))
+
+#if BigEndianUnaligned
+#define do_get_mem_word(a) ((ui4r)*((ui4b *)(a)))
+#else
+LOCALINLINEFUNC ui4r do_get_mem_word(ui3p a)
+{
+#if LittleEndianUnaligned
+ ui4b b = (*((ui4b *)(a)));
+
+ return ((b & 0x00FF) << 8) | ((b >> 8) & 0x00FF);
+#else
+ return (((ui4r)*a) << 8) | ((ui4r)*(a + 1));
+#endif
+}
+#endif
+
+#if BigEndianUnaligned
+#define do_get_mem_long(a) ((ui5r)*((ui5b *)(a)))
+#elif HaveMySwapUi5r && LittleEndianUnaligned
+#define do_get_mem_long(a) (MySwapUi5r((ui5r)*((ui5b *)(a))))
+#else
+LOCALINLINEFUNC ui5r do_get_mem_long(ui3p a)
+{
+#if LittleEndianUnaligned
+#if 0
+ ui5b b = (*((ui5b *)(a)));
+ return ((b & 0x000000FF) << 24)
+ | ((b & 0x0000FF00) << 8)
+ | ((b & 0x00FF0000) >> 8)
+ | ((b & 0xFF000000) >> 24);
+#endif
+#if 0
+ ui5b b = (*((ui5b *)(a)));
+ return ((b << 24) & 0xFF000000)
+ | ((b << 8) & 0x00FF0000)
+ | ((b >> 8) & 0x0000FF00)
+ | ((b >> 24) & 0x000000FF);
+ /*
+ no, this doesn't do well with apple tools,
+ instead try combining two 16 bit swaps.
+ */
+#endif
+ ui5b b = (*((ui5b *)(a)));
+ ui4b b1 = b;
+ ui4b b2 = b >> 16;
+ ui4b c1 = ((b1 & 0x00FF) << 8) | ((b1 >> 8) & 0x00FF);
+ ui4b c2 = ((b2 & 0x00FF) << 8) | ((b2 >> 8) & 0x00FF);
+
+ return (((ui5r)c1) << 16) | ((ui5r)c2);
+ /*
+ better, though still doesn't use BSWAP
+ instruction with apple tools for intel.
+ */
+#else
+ return (((ui5r)*a) << 24) | (((ui5r)*(a + 1)) << 16)
+ | (((ui5r)*(a + 2)) << 8) | ((ui5r)*(a + 3));
+#endif
+}
+#endif
+
+#define do_put_mem_byte(a, v) ((*((ui3b *)(a))) = (v))
+
+#if BigEndianUnaligned
+#define do_put_mem_word(a, v) ((*((ui4b *)(a))) = (v))
+#else
+LOCALINLINEFUNC void do_put_mem_word(ui3p a, ui4r v)
+{
+#if LittleEndianUnaligned
+ ui4b b = ((v & 0x00FF) << 8) | ((v >> 8) & 0x00FF);
+
+ *(ui4b *)a = b;
+#else
+ *a = v >> 8;
+ *(a + 1) = v;
+#endif
+}
+#endif
+
+#if BigEndianUnaligned
+#define do_put_mem_long(a, v) ((*((ui5b *)(a))) = (v))
+#elif HaveMySwapUi5r && LittleEndianUnaligned
+#define do_put_mem_long(a, v) ((*((ui5b *)(a))) = MySwapUi5r(v))
+#else
+LOCALINLINEFUNC void do_put_mem_long(ui3p a, ui5r v)
+{
+#if LittleEndianUnaligned
+ ui4b b1 = v;
+ ui4b b2 = v >> 16;
+ ui4b c1 = ((b1 & 0x00FF) << 8) | ((b1 >> 8) & 0x00FF);
+ ui4b c2 = ((b2 & 0x00FF) << 8) | ((b2 >> 8) & 0x00FF);
+
+ *(ui5b *)a = (c1 << 16) | c2;
+#else
+ *a = v >> 24;
+ *(a + 1) = v >> 16;
+ *(a + 2) = v >> 8;
+ *(a + 3) = v;
+#endif
+}
+#endif
--- /dev/null
+++ b/src/FPCPEMDV.h
@@ -1,0 +1,1218 @@
+/*
+ FPCPEMDV.h
+
+ Copyright (C) 2007 Ross Martin, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Floating Point CoProcessor Emulated Device
+ (included by MINEM68K.c)
+*/
+
+/*
+ ReportAbnormalID unused 0x0306 - 0x03FF
+*/
+
+
+LOCALVAR struct fpustruct
+{
+ myfpr fp[8];
+ CPTR FPIAR; /* Floating point instruction address register */
+} fpu_dat;
+
+LOCALPROC myfp_SetFPIAR(ui5r v)
+{
+ fpu_dat.FPIAR = v;
+}
+
+LOCALFUNC ui5r myfp_GetFPIAR(void)
+{
+ return fpu_dat.FPIAR;
+}
+
+LOCALFUNC blnr DecodeAddrModeRegister(ui5b sz)
+{
+ ui4r Dat = V_regs.CurDecOpY.v[0].ArgDat;
+ ui4r themode = (Dat >> 3) & 7;
+ ui4r thereg = Dat & 7;
+
+ switch (themode) {
+ case 2 :
+ case 3 :
+ case 4 :
+ case 5 :
+ case 6 :
+ return DecodeModeRegister(sz);
+ break;
+ case 7 :
+ switch (thereg) {
+ case 0 :
+ case 1 :
+ case 2 :
+ case 3 :
+ case 4 :
+ return DecodeModeRegister(sz);
+ break;
+ default :
+ return falseblnr;
+ break;
+ }
+ break;
+ default :
+ return falseblnr;
+ break;
+ }
+}
+
+LOCALPROC read_long_double(ui5r addr, myfpr *r)
+{
+ ui4r v2;
+ ui5r v1;
+ ui5r v0;
+
+ v2 = get_word(addr + 0);
+ /* ignore word at offset 2 */
+ v1 = get_long(addr + 4);
+ v0 = get_long(addr + 8);
+
+ myfp_FromExtendedFormat(r, v2, v1, v0);
+}
+
+LOCALPROC write_long_double(ui5r addr, myfpr *xx)
+{
+ ui4r v2;
+ ui5r v1;
+ ui5r v0;
+
+ myfp_ToExtendedFormat(xx, &v2, &v1, &v0);
+
+ put_word(addr + 0, v2);
+ put_word(addr + 2, 0);
+ put_long(addr + 4, v1);
+ put_long(addr + 8, v0);
+}
+
+LOCALPROC read_double(ui5r addr, myfpr *r)
+{
+ ui5r v1;
+ ui5r v0;
+
+ v1 = get_long(addr + 0);
+ v0 = get_long(addr + 4);
+
+ myfp_FromDoubleFormat(r, v1, v0);
+}
+
+LOCALPROC write_double(ui5r addr, myfpr *dd)
+{
+ ui5r v1;
+ ui5r v0;
+
+ myfp_ToDoubleFormat(dd, &v1, &v0);
+
+ put_long(addr + 0, v1);
+ put_long(addr + 4, v0);
+}
+
+#if 0
+LOCALPROC read_single(ui5r addr, myfpr *r)
+{
+ myfp_FromSingleFormat(r, get_long(addr));
+}
+
+LOCALPROC write_single(ui5r addr, myfpr *ff)
+{
+ put_long(addr, myfp_ToSingleFormat(ff));
+}
+#endif
+
+
+LOCALFUNC int CheckFPCondition(ui4b predicate)
+{
+ int condition_true = 0;
+
+ ui3r cc = myfp_GetConditionCodeByte();
+
+ int c_nan = (cc) & 1;
+ /* int c_inf = (cc >> 1) & 1; */
+ int c_zero = (cc >> 2) & 1;
+ int c_neg = (cc >> 3) & 1;
+
+ /*
+ printf(
+ "FPSR Checked: c_nan=%d, c_zero=%d, c_neg=%d,"
+ " predicate=0x%04x\n",
+ c_nan, c_zero, c_neg, predicate);
+ */
+
+ switch (predicate) {
+ case 0x11: /* SEQ */
+ case 0x01: /* EQ */
+ condition_true = c_zero;
+ break;
+ case 0x1E: /* SNE */
+ case 0x0E: /* NE */
+ condition_true = ! c_zero;
+ break;
+ case 0x02: /* OGT */
+ case 0x12: /* GT */
+ condition_true = (! c_neg) && (! c_zero) && (! c_nan);
+ break;
+ case 0x0D: /* ULE */
+ case 0x1D: /* NGT */
+ condition_true = c_neg || c_zero || c_nan;
+ break;
+ case 0x03: /* OGE */
+ case 0x13: /* GE */
+ condition_true = c_zero || ((! c_neg) && (! c_nan));
+ break;
+ case 0x0C: /* ULT */
+ case 0x1C: /* NGE */
+ condition_true = c_nan || ((! c_zero) && c_neg) ;
+ break;
+ case 0x04: /* OLT */
+ case 0x14: /* LT */
+ condition_true = c_neg && (! c_nan) && (! c_zero);
+ break;
+ case 0x0B: /* UGE */
+ case 0x1B: /* NLT */
+ condition_true = c_nan || c_zero || (! c_neg);
+ break;
+ case 0x05: /* OLE */
+ case 0x15: /* LE */
+ condition_true = ((! c_nan) && c_neg) || c_zero;
+ break;
+ case 0x0A: /* UGT */
+ case 0x1A: /* NLE */
+ condition_true = c_nan || ((! c_neg) && (! c_zero));
+ break;
+ case 0x06: /* OGL */
+ case 0x16: /* GL */
+ condition_true = (! c_nan) && (! c_zero);
+ break;
+ case 0x09: /* UEQ */
+ case 0x19: /* NGL */
+ condition_true = c_nan || c_zero;
+ break;
+ case 0x07: /* OR */
+ case 0x17: /* GLE */
+ condition_true = ! c_nan;
+ break;
+ case 0x08: /* NGLE */
+ case 0x18: /* NGLE */
+ condition_true = c_nan;
+ break;
+ case 0x00: /* SFALSE */
+ case 0x10: /* FALSE */
+ condition_true = 0;
+ break;
+ case 0x0F: /* STRUE */
+ case 0x1F: /* TRUE */
+ condition_true = 1;
+ break;
+ }
+
+ /* printf("condition_true=%d\n", condition_true); */
+
+ return condition_true;
+}
+
+LOCALIPROC DoCodeFPU_dflt(void)
+{
+ ReportAbnormalID(0x0301,
+ "unimplemented Floating Point Instruction");
+#if dbglog_HAVE
+ {
+ ui4r opcode = ((ui4r)(V_regs.CurDecOpY.v[0].AMd) << 8)
+ | V_regs.CurDecOpY.v[0].ArgDat;
+
+ dbglog_writelnNum("opcode", opcode);
+ }
+#endif
+ DoCodeFdefault();
+}
+
+LOCALIPROC DoCodeFPU_Save(void)
+{
+ ui4r opcode = ((ui4r)(V_regs.CurDecOpY.v[0].AMd) << 8)
+ | V_regs.CurDecOpY.v[0].ArgDat;
+ if ((opcode == 0xF327) || (opcode == 0xF32D)) {
+#if 0
+ DecodeModeRegister(4);
+ SetArgValueL(0); /* for now, try null state frame */
+#endif
+ /* 28 byte 68881 IDLE frame */
+
+ if (! DecodeAddrModeRegister(28)) {
+ DoCodeFPU_dflt();
+#if dbglog_HAVE
+ dbglog_writeln(
+ "DecodeAddrModeRegister fails in DoCodeFPU_Save");
+#endif
+ } else {
+ put_long(V_regs.ArgAddr.mem, 0x1f180000);
+ put_long(V_regs.ArgAddr.mem + 4, 0);
+ put_long(V_regs.ArgAddr.mem + 8, 0);
+ put_long(V_regs.ArgAddr.mem + 12, 0);
+ put_long(V_regs.ArgAddr.mem + 16, 0);
+ put_long(V_regs.ArgAddr.mem + 20, 0);
+ put_long(V_regs.ArgAddr.mem + 24, 0x70000000);
+ }
+
+ } else {
+ DoCodeFPU_dflt();
+#if dbglog_HAVE
+ dbglog_writeln("unimplemented FPU Save");
+#endif
+ }
+}
+
+LOCALIPROC DoCodeFPU_Restore(void)
+{
+ ui4r opcode = ((ui4r)(V_regs.CurDecOpY.v[0].AMd) << 8)
+ | V_regs.CurDecOpY.v[0].ArgDat;
+ ui4r themode = (opcode >> 3) & 7;
+ ui4r thereg = opcode & 7;
+ if ((opcode == 0xF35F) || (opcode == 0xF36D)) {
+ ui5r dstvalue;
+
+ if (! DecodeAddrModeRegister(4)) {
+ DoCodeFPU_dflt();
+#if dbglog_HAVE
+ dbglog_writeln(
+ "DecodeAddrModeRegister fails in DoCodeFPU_Restore");
+#endif
+ } else {
+ dstvalue = get_long(V_regs.ArgAddr.mem);
+ if (dstvalue != 0) {
+ if (0x1f180000 == dstvalue) {
+ if (3 == themode) {
+ m68k_areg(thereg) = V_regs.ArgAddr.mem + 28;
+ }
+ } else {
+ DoCodeFPU_dflt();
+#if dbglog_HAVE
+ dbglog_writeln("unknown restore");
+ /* not a null state we saved */
+#endif
+ }
+ }
+ }
+ } else {
+ DoCodeFPU_dflt();
+#if dbglog_HAVE
+ dbglog_writeln("unimplemented FPU Restore");
+#endif
+ }
+}
+
+LOCALIPROC DoCodeFPU_FBccW(void)
+{
+ /*
+ Also get here for a NOP instruction (opcode 0xF280),
+ which is simply a FBF.w with offset 0
+ */
+ ui4r Dat = V_regs.CurDecOpY.v[0].ArgDat;
+
+ if (CheckFPCondition(Dat & 0x3F)) {
+ DoCodeBraW();
+ } else {
+ SkipiWord();
+ }
+
+ /* printf("pc_p set to 0x%p in FBcc (32bit)\n", V_pc_p); */
+}
+
+LOCALIPROC DoCodeFPU_FBccL(void)
+{
+ ui4r Dat = V_regs.CurDecOpY.v[0].ArgDat;
+
+ if (CheckFPCondition(Dat & 0x3F)) {
+ DoCodeBraL();
+ } else {
+ SkipiLong();
+ }
+}
+
+LOCALIPROC DoCodeFPU_DBcc(void)
+{
+ ui4r Dat = V_regs.CurDecOpY.v[0].ArgDat;
+ ui4r thereg = Dat & 7;
+ ui4b word2 = (int)nextiword();
+
+ ui4b predicate = word2 & 0x3F;
+
+ int condition_true = CheckFPCondition(predicate);
+
+ if (! condition_true) {
+ ui5b fdb_count = ui5r_FromSWord(m68k_dreg(thereg)) - 1;
+
+ m68k_dreg(thereg) =
+ (m68k_dreg(thereg) & ~ 0xFFFF) | (fdb_count & 0xFFFF);
+ if ((si5b)fdb_count == -1) {
+ SkipiWord();
+ } else {
+ DoCodeBraW();
+ }
+ } else {
+ SkipiWord();
+ }
+}
+
+LOCALIPROC DoCodeFPU_Trapcc(void)
+{
+ ui4r Dat = V_regs.CurDecOpY.v[0].ArgDat;
+ ui4r thereg = Dat & 7;
+
+ ui4b word2 = (int)nextiword();
+
+ ui4b predicate = word2 & 0x3F;
+
+ int condition_true = CheckFPCondition(predicate);
+
+ if (thereg == 2) {
+ (void) nextiword();
+ } else if (thereg == 3) {
+ (void) nextilong();
+ } else if (thereg == 4) {
+ } else {
+ ReportAbnormalID(0x0302, "Invalid FTRAPcc (?");
+ }
+
+ if (condition_true) {
+ ReportAbnormalID(0x0303, "FTRAPcc trapping");
+ Exception(7);
+ }
+}
+
+LOCALIPROC DoCodeFPU_Scc(void)
+{
+ ui4b word2 = (int)nextiword();
+
+ if (! DecodeModeRegister(1)) {
+ DoCodeFPU_dflt();
+#if dbglog_HAVE
+ dbglog_writeln("bad mode/reg in DoCodeFPU_Scc");
+#endif
+ } else {
+ if (CheckFPCondition(word2 & 0x3F)) {
+ SetArgValueB(0xFFFF);
+ } else {
+ SetArgValueB(0x0000);
+ }
+ }
+}
+
+LOCALPROC DoCodeF_InvalidPlusWord(void)
+{
+ BackupPC();
+ DoCodeFPU_dflt();
+}
+
+LOCALFUNC int CountCSIAlist(ui4b word2)
+{
+ ui4b regselect = (word2 >> 10) & 0x7;
+ int num = 0;
+
+ if (regselect & 1) {
+ num++;
+ }
+ if (regselect & 2) {
+ num++;
+ }
+ if (regselect & 4) {
+ num++;
+ }
+
+ return num;
+}
+
+LOCALPROC DoCodeFPU_Move_EA_CSIA(ui4b word2)
+{
+ int n;
+ ui5b ea_value[3];
+ ui4b regselect = (word2 >> 10) & 0x7;
+ int num = CountCSIAlist(word2);
+
+ if (regselect == 0) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("Invalid FMOVE instruction");
+#endif
+ return;
+ }
+
+ /* FMOVEM.L <EA>, <FP CR,SR,IAR list> */
+
+ if (! DecodeModeRegister(4 * num)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("bad mode/reg in DoCodeFPU_Move_EA_CSIA");
+#endif
+ } else {
+ ea_value[0] = GetArgValueL();
+ if (num > 1) {
+ ea_value[1] = get_long(V_regs.ArgAddr.mem + 4);
+ }
+ if (num > 2) {
+ ea_value[2] = get_long(V_regs.ArgAddr.mem + 8);
+ }
+
+ n = 0;
+ if (regselect & (1 << 2)) {
+ myfp_SetFPCR(ea_value[n++]);
+ }
+ if (regselect & (1 << 1)) {
+ myfp_SetFPSR(ea_value[n++]);
+ }
+ if (regselect & (1 << 0)) {
+ myfp_SetFPIAR(ea_value[n++]);
+ }
+ }
+}
+
+LOCALPROC DoCodeFPU_MoveM_CSIA_EA(ui4b word2)
+{
+ int n;
+ ui5b ea_value[3];
+ int num = CountCSIAlist(word2);
+
+ ui4b regselect = (word2 >> 10) & 0x7;
+
+ /* FMOVEM.L <FP CR,SR,IAR list>, <EA> */
+
+ if (0 == regselect) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("Invalid FMOVE instruction");
+#endif
+ } else
+ if (! DecodeModeRegister(4 * num)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("bad mode/reg in DoCodeFPU_MoveM_CSIA_EA");
+#endif
+ } else
+ {
+ n = 0;
+ if (regselect & (1 << 2)) {
+ ea_value[n++] = myfp_GetFPCR();
+ }
+ if (regselect & (1 << 1)) {
+ ea_value[n++] = myfp_GetFPSR();
+ }
+ if (regselect & (1 << 0)) {
+ ea_value[n++] = myfp_GetFPIAR();
+ }
+
+ SetArgValueL(ea_value[0]);
+ if (num > 1) {
+ put_long(V_regs.ArgAddr.mem + 4, ea_value[1]);
+ }
+ if (num > 2) {
+ put_long(V_regs.ArgAddr.mem + 8, ea_value[2]);
+ }
+ }
+}
+
+LOCALPROC DoCodeFPU_MoveM_EA_list(ui4b word2)
+{
+ int i;
+ ui5r myaddr;
+ ui5r count;
+ ui4b register_list = word2;
+
+ ui4b fmove_mode = (word2 >> 11) & 0x3;
+
+ /* FMOVEM.X <ea>, <list> */
+
+ if ((fmove_mode == 0) || (fmove_mode == 1)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("Invalid FMOVEM.X instruction");
+#endif
+ return;
+ }
+
+ if (fmove_mode == 3) {
+ /* Dynamic mode */
+ register_list = V_regs.regs[(word2 >> 4) & 7];
+ }
+
+ count = 0;
+ for (i = 0; i <= 7; i++) {
+ int j = 1 << (7 - i);
+ if (j & register_list) {
+ ++count;
+ }
+ }
+
+ if (! DecodeModeRegister(12 * count)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln(
+ "DecodeModeRegister fails DoCodeFPU_MoveM_EA_list");
+#endif
+ } else {
+ /* Postincrement mode or Control mode */
+
+ myaddr = V_regs.ArgAddr.mem;
+
+ for (i = 0; i <= 7; i++) {
+ int j = 1 << (7 - i);
+ if (j & register_list) {
+ read_long_double(myaddr, &fpu_dat.fp[i]);
+ myaddr += 12;
+ }
+ }
+ }
+}
+
+LOCALPROC DoCodeFPU_MoveM_list_EA(ui4b word2)
+{
+ /* FMOVEM.X <list>, <ea> */
+
+ int i;
+ ui5r myaddr;
+ ui5r count;
+ ui4b register_list = word2;
+ ui4r Dat = V_regs.CurDecOpY.v[0].ArgDat;
+ ui4r themode = (Dat >> 3) & 7;
+
+ ui4b fmove_mode = (word2 >> 11) & 0x3;
+
+ if ((fmove_mode == 1) || (fmove_mode == 3)) {
+ /* Dynamic mode */
+ register_list = V_regs.regs[(word2 >> 4) & 7];
+ }
+
+ count = 0;
+ for (i = 7; i >= 0; i--) {
+ int j = 1 << i;
+ if (j & register_list) {
+ ++count;
+ }
+ }
+
+ if (! DecodeModeRegister(12 * count)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln(
+ "DecodeModeRegister fails DoCodeFPU_MoveM_list_EA");
+#endif
+ } else {
+ if (themode == 4) {
+ /* Predecrement mode */
+
+ myaddr = V_regs.ArgAddr.mem + 12 * count;
+
+ for (i = 7; i >= 0; i--) {
+ int j = 1 << i;
+ if (j & register_list) {
+ myaddr -= 12;
+ write_long_double(myaddr, &fpu_dat.fp[i]);
+ }
+ }
+ } else {
+ /* Control mode */
+
+ myaddr = V_regs.ArgAddr.mem;
+
+ for (i = 0; i <= 7; i++) {
+ int j = 1 << (7 - i);
+ if (j & register_list) {
+ write_long_double(myaddr, &fpu_dat.fp[i]);
+ myaddr += 12;
+ }
+ }
+ }
+ }
+}
+
+LOCALPROC DoCodeFPU_MoveCR(ui4b word2)
+{
+ /* FMOVECR */
+ ui4r opcode = ((ui4r)(V_regs.CurDecOpY.v[0].AMd) << 8)
+ | V_regs.CurDecOpY.v[0].ArgDat;
+
+ if (opcode != 0xF200) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("bad opcode in FMOVECR");
+#endif
+ } else {
+ ui4b RomOffset = word2 & 0x7F;
+ ui4b DestReg = (word2 >> 7) & 0x7;
+
+ if (! myfp_getCR(&fpu_dat.fp[DestReg], RomOffset)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("Invalid constant number in FMOVECR");
+#endif
+ }
+ }
+}
+
+LOCALPROC SaveResultAndFPSR(myfpr *DestReg, myfpr *result)
+{
+ *DestReg = *result;
+ myfp_SetConditionCodeByteFromResult(result);
+}
+
+LOCALPROC DoCodeFPU_GenOp(ui4b word2, myfpr *source)
+{
+ myfpr result;
+ myfpr t0;
+ myfpr *DestReg = &fpu_dat.fp[(word2 >> 7) & 0x7];
+
+ switch (word2 & 0x7F) {
+
+ case 0x00: /* FMOVE */
+ SaveResultAndFPSR(DestReg, source);
+ break;
+
+ case 0x01: /* FINT */
+ myfp_Int(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x02: /* FSINH */
+ myfp_Sinh(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x03: /* FINTRZ */
+ myfp_IntRZ(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x04: /* FSQRT */
+ myfp_Sqrt(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x06: /* FLOGNP1 */
+ myfp_LogNP1(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x08: /* FETOXM1 */
+ myfp_EToXM1(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x09: /* FTANH */
+ myfp_Tanh(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x0A: /* FATAN */
+ myfp_ATan(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x0C: /* FASIN */
+ myfp_ASin(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x0D: /* FATANH */
+ myfp_ATanh(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x0E: /* FSIN */
+ myfp_Sin(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x0F: /* FTAN */
+ myfp_Tan(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x10: /* FETOX */
+ myfp_EToX(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x11: /* FTWOTOX */
+ myfp_TwoToX(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x12: /* FTENTOX */
+ myfp_TenToX(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x14: /* FLOGN */
+ myfp_LogN(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x15: /* FLOG10 */
+ myfp_Log10(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x16: /* FLOG2 */
+ myfp_Log2(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x18: /* FABS */
+ myfp_Abs(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x19: /* FCOSH */
+ myfp_Cosh(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x1A: /* FNEG */
+ myfp_Neg(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x1C: /* FACOS */
+ myfp_ACos(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x1D: /* FCOS */
+ myfp_Cos(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x1E: /* FGETEXP */
+ myfp_GetExp(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x1F: /* FGETMAN */
+ myfp_GetMan(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x20: /* FDIV */
+ myfp_Div(&result, DestReg, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x21: /* FMOD */ /* 0x2D in some docs, 0x21 in others ? */
+ myfp_Mod(&result, DestReg, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x22: /* FADD */
+ myfp_Add(&result, DestReg, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x23: /* FMUL */
+ myfp_Mul(&result, DestReg, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x24: /* FSGLDIV */
+ myfp_Div(&t0, DestReg, source);
+ myfp_RoundToSingle(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x25: /* FREM */
+ myfp_Rem(&result, DestReg, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x26: /* FSCALE */
+ myfp_Scale(&result, DestReg, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x27: /* FSGLMUL */
+ myfp_Mul(&t0, DestReg, source);
+ myfp_RoundToSingle(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x28: /* FSUB */
+ myfp_Sub(&result, DestReg, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ /* FSINCOS */
+ myfp_SinCos(&result, &fpu_dat.fp[word2 & 0x7], source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x38: /* FCMP */
+ myfp_Sub(&result, DestReg, source);
+ /* don't save result */
+ myfp_SetConditionCodeByteFromResult(&result);
+ break;
+
+ case 0x3A: /* FTST */
+ myfp_SetConditionCodeByteFromResult(source);
+ break;
+
+ /*
+ everything after here is not in 68881/68882,
+ appears first in 68040
+ */
+
+ case 0x40: /* FSMOVE */
+ myfp_RoundToSingle(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x41: /* FSSQRT */
+ myfp_Sqrt(&t0, source);
+ myfp_RoundToSingle(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x44: /* FDMOVE */
+ myfp_RoundToDouble(&result, source);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x45: /* FDSQRT */
+ myfp_Sqrt(&t0, source);
+ myfp_RoundToDouble(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x58: /* FSABS */
+ myfp_Abs(&t0, source);
+ myfp_RoundToSingle(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x5A: /* FSNEG */
+ myfp_Neg(&t0, source);
+ myfp_RoundToSingle(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x5C: /* FDABS */
+ myfp_Abs(&t0, source);
+ myfp_RoundToDouble(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x5E: /* FDNEG */
+ myfp_Neg(&t0, source);
+ myfp_RoundToDouble(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x60: /* FSDIV */
+ myfp_Div(&t0, DestReg, source);
+ myfp_RoundToSingle(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x62: /* FSADD */
+ myfp_Add(&t0, DestReg, source);
+ myfp_RoundToSingle(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x63: /* FSMUL */
+ myfp_Mul(&t0, DestReg, source);
+ myfp_RoundToSingle(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x64: /* FDDIV */
+ myfp_Div(&t0, DestReg, source);
+ myfp_RoundToDouble(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x66: /* FDADD */
+ myfp_Add(&t0, DestReg, source);
+ myfp_RoundToDouble(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x67: /* FDMUL */
+ myfp_Mul(&t0, DestReg, source);
+ myfp_RoundToDouble(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x68: /* FSSUB */
+ myfp_Sub(&t0, DestReg, source);
+ myfp_RoundToSingle(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ case 0x6C: /* FDSUB */
+ myfp_Sub(&t0, DestReg, source);
+ myfp_RoundToDouble(&result, &t0);
+ SaveResultAndFPSR(DestReg, &result);
+ break;
+
+ default:
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("Invalid DoCodeFPU_GenOp");
+#endif
+ break;
+ }
+}
+
+LOCALPROC DoCodeFPU_GenOpReg(ui4b word2)
+{
+ ui4r regselect = (word2 >> 10) & 0x7;
+
+ DoCodeFPU_GenOp(word2, &fpu_dat.fp[regselect]);
+}
+
+LOCALPROC DoCodeFPU_GenOpEA(ui4b word2)
+{
+ myfpr source;
+
+ switch ((word2 >> 10) & 0x7) {
+ case 0: /* long-word integer */
+ if (! DecodeModeRegister(4)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln(
+ "DecodeModeRegister fails GetFPSource L");
+#endif
+ } else {
+ myfp_FromLong(&source, GetArgValueL());
+ DoCodeFPU_GenOp(word2, &source);
+ }
+ break;
+ case 1: /* Single-Precision real */
+ if (! DecodeModeRegister(4)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln(
+ "DecodeModeRegister fails GetFPSource S");
+#endif
+ } else {
+ myfp_FromSingleFormat(&source, GetArgValueL());
+ DoCodeFPU_GenOp(word2, &source);
+ }
+ break;
+ case 2: /* extended precision real */
+ if (! DecodeAddrModeRegister(12)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln(
+ "DecodeAddrModeRegister fails GetFPSource X");
+#endif
+ } else {
+ read_long_double(V_regs.ArgAddr.mem, &source);
+ DoCodeFPU_GenOp(word2, &source);
+ }
+ break;
+ case 3: /* packed-decimal real */
+ if (! DecodeAddrModeRegister(16)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln(
+ "DecodeAddrModeRegister fails GetFPSource P");
+#endif
+ } else {
+ ReportAbnormalID(0x0304,
+ "Packed Decimal in GetFPSource");
+ /* correct? just set to a constant for now */
+ /* *r = 9123456789.0; */
+ DoCodeFPU_GenOp(word2, &source);
+ }
+ break;
+ case 4: /* Word integer */
+ if (! DecodeModeRegister(2)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln(
+ "DecodeModeRegister fails GetFPSource W");
+#endif
+ } else {
+ myfp_FromLong(&source, GetArgValueW());
+ DoCodeFPU_GenOp(word2, &source);
+ }
+ break;
+ case 5: /* Double-precision real */
+ if (! DecodeAddrModeRegister(8)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln(
+ "DecodeAddrModeRegister fails GetFPSource D");
+#endif
+ } else {
+ read_double(V_regs.ArgAddr.mem, &source);
+ DoCodeFPU_GenOp(word2, &source);
+ }
+ break;
+ case 6: /* Byte Integer */
+ if (! DecodeModeRegister(1)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln(
+ "DecodeModeRegister fails GetFPSource B");
+#endif
+ } else {
+ myfp_FromLong(&source, GetArgValueB());
+ DoCodeFPU_GenOp(word2, &source);
+ }
+ break;
+ case 7: /* Not a valid source specifier */
+ DoCodeFPU_MoveCR(word2);
+ break;
+ default:
+ /* should not be able to get here */
+ break;
+ }
+}
+
+LOCALPROC DoCodeFPU_Move_FP_EA(ui4b word2)
+{
+ /* FMOVE FP?, <EA> */
+
+ ui4r SourceReg = (word2 >> 7) & 0x7;
+ myfpr *source = &fpu_dat.fp[SourceReg];
+
+ switch ((word2 >> 10) & 0x7) {
+ case 0: /* long-word integer */
+ if (! DecodeModeRegister(4)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("DecodeModeRegister fails FMOVE L");
+#endif
+ } else {
+ SetArgValueL(myfp_ToLong(source));
+ }
+ break;
+ case 1: /* Single-Precision real */
+ if (! DecodeModeRegister(4)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("DecodeModeRegister fails FMOVE S");
+#endif
+ } else {
+ SetArgValueL(myfp_ToSingleFormat(source));
+ }
+ break;
+ case 2: /* extended precision real */
+ if (! DecodeAddrModeRegister(12)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("DecodeAddrModeRegister fails FMOVE X");
+#endif
+ } else {
+ write_long_double(V_regs.ArgAddr.mem, source);
+ }
+ break;
+ case 3: /* packed-decimal real */
+ if (! DecodeAddrModeRegister(16)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("DecodeAddrModeRegister fails FMOVE P");
+#endif
+ } else {
+ ReportAbnormalID(0x0305, "Packed Decimal in FMOVE");
+ /* ? */
+ }
+ break;
+ case 4: /* Word integer */
+ if (! DecodeModeRegister(2)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("DecodeModeRegister fails FMOVE W");
+#endif
+ } else {
+ SetArgValueW(myfp_ToLong(source));
+ }
+ break;
+ case 5: /* Double-precision real */
+ if (! DecodeAddrModeRegister(8)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("DecodeAddrModeRegister fails FMOVE D");
+#endif
+ } else {
+ write_double(V_regs.ArgAddr.mem, source);
+ }
+ break;
+ case 6: /* Byte Integer */
+ if (! DecodeModeRegister(1)) {
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writeln("DecodeModeRegister fails FMOVE B");
+#endif
+ } else {
+ SetArgValueB(myfp_ToLong(source));
+ }
+ break;
+ default:
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writelnNum("Bad Source Specifier in FMOVE",
+ (word2 >> 10) & 0x7);
+#endif
+ break;
+ }
+}
+
+LOCALIPROC DoCodeFPU_md60(void)
+{
+ ui4b word2 = (int)nextiword();
+
+ switch ((word2 >> 13) & 0x7) {
+ case 0:
+ DoCodeFPU_GenOpReg(word2);
+ break;
+ case 2:
+ DoCodeFPU_GenOpEA(word2);
+ break;
+ case 3:
+ DoCodeFPU_Move_FP_EA(word2);
+ break;
+ case 4:
+ DoCodeFPU_Move_EA_CSIA(word2);
+ break;
+ case 5:
+ DoCodeFPU_MoveM_CSIA_EA(word2);
+ break;
+ case 6:
+ DoCodeFPU_MoveM_EA_list(word2);
+ break;
+ case 7:
+ DoCodeFPU_MoveM_list_EA(word2);
+ break;
+ default:
+ DoCodeF_InvalidPlusWord();
+#if dbglog_HAVE
+ dbglog_writelnNum("Invalid DoCodeFPU_md60",
+ (word2 >> 13) & 0x7);
+#endif
+ break;
+ }
+}
--- /dev/null
+++ b/src/FPMATHEM.h
@@ -1,0 +1,6262 @@
+/*
+ FPMATHEM.h
+
+ Copyright (C) 2007 John R. Hauser, Stanislav Shwartsman,
+ Ross Martin, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Floating Point MATH implemented with software EMulation
+
+ Based on the SoftFloat IEC/IEEE Floating-point Arithmetic
+ Package, Release 2b, written by John R. Hauser.
+
+ Also uses extensions to SoftFloat, written for
+ Bochs (x86 achitecture simulator), by Stanislav Shwartsman.
+*/
+
+/*
+ original SoftFloat Copyright notice:
+
+ Written by John R. Hauser. This work was made possible in part by the
+ International Computer Science Institute, located at Suite 600, 1947 Center
+ Street, Berkeley, California 94704. Funding was partially provided by the
+ National Science Foundation under grant MIP-9311980. The original version
+ of this code was written as part of a project to build a fixed-point vector
+ processor in collaboration with the University of California at Berkeley,
+ overseen by Profs. Nelson Morgan and John Wawrzynek. More information
+ is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
+ arithmetic/SoftFloat.html'.
+
+ THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
+ been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
+ RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
+ AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
+ COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
+ EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
+ INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
+ OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
+
+ Derivative works are acceptable, even for commercial purposes, so long as
+ (1) the source code for the derivative work includes prominent notice that
+ the work is derivative, and (2) the source code includes prominent notice with
+ these four paragraphs for those parts of this code that are retained.
+*/
+
+/*
+ original Stanislav Shwartsman Copyright notice:
+
+ This source file is an extension to the SoftFloat IEC/IEEE Floating-point
+ Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
+ floating point emulation.
+
+ THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
+ been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
+ RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
+ AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
+ COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
+ EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
+ INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
+ OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
+
+ Derivative works are acceptable, even for commercial purposes, so long as
+ (1) the source code for the derivative work includes prominent notice that
+ the work is derivative, and (2) the source code includes prominent notice with
+ these four paragraphs for those parts of this code that are retained.
+
+ .*============================================================================
+ * Written for Bochs (x86 achitecture simulator) by
+ * Stanislav Shwartsman [sshwarts at sourceforge net]
+ * ==========================================================================*.
+*/
+
+
+/*
+ ReportAbnormalID unused 0x0204 - 0x02FF
+*/
+
+
+/* soft float stuff */
+
+/*
+ should avoid 64 bit literals.
+*/
+
+typedef ui3r flag; /* 0/1 */
+
+/*
+ To fix: softfloat representation of
+ denormalized extended precision numbers
+ is different than on 68881.
+*/
+
+#define cIncludeFPUUnused cIncludeUnused
+
+/* ----- from original file "softfloat.h" ----- */
+
+/*======================================================================
+
+This C header file is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2b.
+
+["original SoftFloat Copyright notice" went here, included near top of
+this file.]
+
+======================================================================*/
+
+/*----------------------------------------------------------------------------
+| The macro `FLOATX80' must be defined to enable the extended double-precision
+| floating-point format `floatx80'. If this macro is not defined, the
+| `floatx80' type will not be defined, and none of the functions that either
+| input or output the `floatx80' type will be defined. The same applies to
+| the `FLOAT128' macro and the quadruple-precision format `float128'.
+*----------------------------------------------------------------------------*/
+#define FLOATX80
+#define FLOAT128
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point types.
+*----------------------------------------------------------------------------*/
+
+typedef struct {
+ ui6b low;
+ unsigned short high;
+} floatx80;
+
+#ifdef FLOAT128
+typedef struct {
+ ui6b low, high;
+} float128;
+#endif
+
+
+/* ----- end from original file "softfloat.h" ----- */
+
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point rounding mode.
+*----------------------------------------------------------------------------*/
+enum {
+ float_round_nearest_even = 0,
+ float_round_down = 1,
+ float_round_up = 2,
+ float_round_to_zero = 3
+};
+
+/*----------------------------------------------------------------------------
+| Floating-point rounding mode, extended double-precision rounding precision,
+| and exception flags.
+*----------------------------------------------------------------------------*/
+
+LOCALVAR si3r float_rounding_mode = float_round_nearest_even;
+
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point exception flags.
+*----------------------------------------------------------------------------*/
+
+enum {
+ float_flag_invalid = 1,
+ float_flag_divbyzero = 4,
+ float_flag_overflow = 8,
+ float_flag_underflow = 16,
+ float_flag_inexact = 32
+};
+LOCALVAR si3r float_exception_flags = 0;
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision rounding precision. Valid
+| values are 32, 64, and 80.
+*----------------------------------------------------------------------------*/
+
+LOCALVAR si3r floatx80_rounding_precision = 80;
+
+/*----------------------------------------------------------------------------
+| Primitive arithmetic functions, including multi-word arithmetic, and
+| division and square root approximations. (Can be specialized to target if
+| desired.)
+*----------------------------------------------------------------------------*/
+
+/* ----- from original file "softfloat-macros" ----- */
+
+/*============================================================================
+
+This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2b.
+
+["original SoftFloat Copyright notice" went here, included near top of this file.]
+
+=============================================================================*/
+
+/*----------------------------------------------------------------------------
+| Shifts `a' right by the number of bits given in `count'. If any nonzero
+| bits are shifted off, they are ``jammed'' into the least significant bit of
+| the result by setting the least significant bit to 1. The value of `count'
+| can be arbitrarily large; in particular, if `count' is greater than 32, the
+| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
+| The result is stored in the location pointed to by `zPtr'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEPROC shift32RightJamming( ui5b a, si4r count, ui5b *zPtr )
+{
+ ui5b z;
+
+ if ( count == 0 ) {
+ z = a;
+ }
+ else if ( count < 32 ) {
+ z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
+ }
+ else {
+ z = ( a != 0 );
+ }
+ *zPtr = z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Shifts `a' right by the number of bits given in `count'. If any nonzero
+| bits are shifted off, they are ``jammed'' into the least significant bit of
+| the result by setting the least significant bit to 1. The value of `count'
+| can be arbitrarily large; in particular, if `count' is greater than 64, the
+| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
+| The result is stored in the location pointed to by `zPtr'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEPROC shift64RightJamming( ui6b a, si4r count, ui6b *zPtr )
+{
+ ui6b z;
+
+ if ( count == 0 ) {
+ z = a;
+ }
+ else if ( count < 64 ) {
+ z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 );
+ }
+ else {
+ z = ( a != 0 );
+ }
+ *zPtr = z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
+| _plus_ the number of bits given in `count'. The shifted result is at most
+| 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The
+| bits shifted off form a second 64-bit result as follows: The _last_ bit
+| shifted off is the most-significant bit of the extra result, and the other
+| 63 bits of the extra result are all zero if and only if _all_but_the_last_
+| bits shifted off were all zero. This extra result is stored in the location
+| pointed to by `z1Ptr'. The value of `count' can be arbitrarily large.
+| (This routine makes more sense if `a0' and `a1' are considered to form
+| a fixed-point value with binary point between `a0' and `a1'. This fixed-
+| point value is shifted right by the number of bits given in `count', and
+| the integer part of the result is returned at the location pointed to by
+| `z0Ptr'. The fractional part of the result may be slightly corrupted as
+| described above, and is returned at the location pointed to by `z1Ptr'.)
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEPROC shift64ExtraRightJamming(
+ ui6b a0, ui6b a1, si4r count, ui6b *z0Ptr, ui6b *z1Ptr )
+{
+ ui6b z0, z1;
+ si3r negCount = ( - count ) & 63;
+
+ if ( count == 0 ) {
+ z1 = a1;
+ z0 = a0;
+ }
+ else if ( count < 64 ) {
+ z1 = ( a0<<negCount ) | ( a1 != 0 );
+ z0 = a0>>count;
+ }
+ else {
+ if ( count == 64 ) {
+ z1 = a0 | ( a1 != 0 );
+ }
+ else {
+ z1 = ( ( a0 | a1 ) != 0 );
+ }
+ z0 = 0;
+ }
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
+| number of bits given in `count'. Any bits shifted off are lost. The value
+| of `count' can be arbitrarily large; in particular, if `count' is greater
+| than 128, the result will be 0. The result is broken into two 64-bit pieces
+| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEPROC shift128Right(
+ ui6b a0, ui6b a1, si4r count, ui6b *z0Ptr, ui6b *z1Ptr )
+{
+ ui6b z0, z1;
+ si3r negCount = ( - count ) & 63;
+
+ if ( count == 0 ) {
+ z1 = a1;
+ z0 = a0;
+ }
+ else if ( count < 64 ) {
+ z1 = ( a0<<negCount ) | ( a1>>count );
+ z0 = a0>>count;
+ }
+ else {
+ z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0;
+ z0 = 0;
+ }
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
+| number of bits given in `count'. If any nonzero bits are shifted off, they
+| are ``jammed'' into the least significant bit of the result by setting the
+| least significant bit to 1. The value of `count' can be arbitrarily large;
+| in particular, if `count' is greater than 128, the result will be either
+| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or
+| nonzero. The result is broken into two 64-bit pieces which are stored at
+| the locations pointed to by `z0Ptr' and `z1Ptr'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEPROC shift128RightJamming(
+ ui6b a0, ui6b a1, si4r count, ui6b *z0Ptr, ui6b *z1Ptr )
+{
+ ui6b z0, z1;
+ si3r negCount = ( - count ) & 63;
+
+ if ( count == 0 ) {
+ z1 = a1;
+ z0 = a0;
+ }
+ else if ( count < 64 ) {
+ z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
+ z0 = a0>>count;
+ }
+ else {
+ if ( count == 64 ) {
+ z1 = a0 | ( a1 != 0 );
+ }
+ else if ( count < 128 ) {
+ z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
+ }
+ else {
+ z1 = ( ( a0 | a1 ) != 0 );
+ }
+ z0 = 0;
+ }
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
+| by 64 _plus_ the number of bits given in `count'. The shifted result is
+| at most 128 nonzero bits; these are broken into two 64-bit pieces which are
+| stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted
+| off form a third 64-bit result as follows: The _last_ bit shifted off is
+| the most-significant bit of the extra result, and the other 63 bits of the
+| extra result are all zero if and only if _all_but_the_last_ bits shifted off
+| were all zero. This extra result is stored in the location pointed to by
+| `z2Ptr'. The value of `count' can be arbitrarily large.
+| (This routine makes more sense if `a0', `a1', and `a2' are considered
+| to form a fixed-point value with binary point between `a1' and `a2'. This
+| fixed-point value is shifted right by the number of bits given in `count',
+| and the integer part of the result is returned at the locations pointed to
+| by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly
+| corrupted as described above, and is returned at the location pointed to by
+| `z2Ptr'.)
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEPROC shift128ExtraRightJamming(
+ ui6b a0,
+ ui6b a1,
+ ui6b a2,
+ si4r count,
+ ui6b *z0Ptr,
+ ui6b *z1Ptr,
+ ui6b *z2Ptr)
+{
+ ui6b z0, z1, z2;
+ si3r negCount = ( - count ) & 63;
+
+ if ( count == 0 ) {
+ z2 = a2;
+ z1 = a1;
+ z0 = a0;
+ }
+ else {
+ if ( count < 64 ) {
+ z2 = a1<<negCount;
+ z1 = ( a0<<negCount ) | ( a1>>count );
+ z0 = a0>>count;
+ }
+ else {
+ if ( count == 64 ) {
+ z2 = a1;
+ z1 = a0;
+ }
+ else {
+ a2 |= a1;
+ if ( count < 128 ) {
+ z2 = a0<<negCount;
+ z1 = a0>>( count & 63 );
+ }
+ else {
+ z2 = ( count == 128 ) ? a0 : ( a0 != 0 );
+ z1 = 0;
+ }
+ }
+ z0 = 0;
+ }
+ z2 |= ( a2 != 0 );
+ }
+ *z2Ptr = z2;
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the
+| number of bits given in `count'. Any bits shifted off are lost. The value
+| of `count' must be less than 64. The result is broken into two 64-bit
+| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEPROC shortShift128Left(
+ ui6b a0, ui6b a1, si4r count, ui6b *z0Ptr, ui6b *z1Ptr )
+{
+
+ *z1Ptr = a1<<count;
+ *z0Ptr =
+ ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) );
+
+}
+
+/*----------------------------------------------------------------------------
+| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
+| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so
+| any carry out is lost. The result is broken into two 64-bit pieces which
+| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEPROC add128(
+ ui6b a0, ui6b a1, ui6b b0, ui6b b1, ui6b *z0Ptr, ui6b *z1Ptr )
+{
+ ui6b z1;
+
+ z1 = a1 + b1;
+ *z1Ptr = z1;
+ *z0Ptr = a0 + b0 + ( z1 < a1 );
+}
+
+/*----------------------------------------------------------------------------
+| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
+| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is
+| modulo 2^192, so any carry out is lost. The result is broken into three
+| 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
+| `z1Ptr', and `z2Ptr'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEPROC add192(
+ ui6b a0,
+ ui6b a1,
+ ui6b a2,
+ ui6b b0,
+ ui6b b1,
+ ui6b b2,
+ ui6b *z0Ptr,
+ ui6b *z1Ptr,
+ ui6b *z2Ptr)
+{
+ ui6b z0, z1, z2;
+ si3r carry0, carry1;
+
+ z2 = a2 + b2;
+ carry1 = ( z2 < a2 );
+ z1 = a1 + b1;
+ carry0 = ( z1 < a1 );
+ z0 = a0 + b0;
+ z1 += carry1;
+ z0 += ( z1 < carry1 );
+ z0 += carry0;
+ *z2Ptr = z2;
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*----------------------------------------------------------------------------
+| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
+| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo
+| 2^128, so any borrow out (carry out) is lost. The result is broken into two
+| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
+| `z1Ptr'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEPROC
+ sub128(
+ ui6b a0, ui6b a1, ui6b b0, ui6b b1, ui6b *z0Ptr, ui6b *z1Ptr )
+{
+
+ *z1Ptr = a1 - b1;
+ *z0Ptr = a0 - b0 - ( a1 < b1 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
+| from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
+| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The
+| result is broken into three 64-bit pieces which are stored at the locations
+| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEPROC
+ sub192(
+ ui6b a0,
+ ui6b a1,
+ ui6b a2,
+ ui6b b0,
+ ui6b b1,
+ ui6b b2,
+ ui6b *z0Ptr,
+ ui6b *z1Ptr,
+ ui6b *z2Ptr
+ )
+{
+ ui6b z0, z1, z2;
+ si3r borrow0, borrow1;
+
+ z2 = a2 - b2;
+ borrow1 = ( a2 < b2 );
+ z1 = a1 - b1;
+ borrow0 = ( a1 < b1 );
+ z0 = a0 - b0;
+ z0 -= ( z1 < borrow1 );
+ z1 -= borrow1;
+ z0 -= borrow0;
+ *z2Ptr = z2;
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*----------------------------------------------------------------------------
+| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken
+| into two 64-bit pieces which are stored at the locations pointed to by
+| `z0Ptr' and `z1Ptr'.
+*----------------------------------------------------------------------------*/
+
+
+#ifndef HaveUi5to6Mul
+#define HaveUi5to6Mul 1
+#endif
+
+#if HaveUi5to6Mul
+LOCALINLINEPROC Ui5to6Mul( ui5b src1, ui5b src2, ui6b *z)
+{
+ *z = ((ui6b) src1) * src2;
+}
+#else
+
+LOCALINLINEPROC Ui6fromHiLo(ui5b hi, ui5b lo, ui6b *z)
+{
+ *z = (((ui6b)(hi)) << 32) + lo;
+#if 0
+ z->lo = hi;
+ z->hi = lo;
+#endif
+}
+
+LOCALPROC Ui5to6Mul( ui5b src1, ui5b src2, ui6b *z)
+{
+ ui4b src1_lo = ui5b_lo(src1);
+ ui4b src2_lo = ui5b_lo(src2);
+ ui4b src1_hi = ui5b_hi(src1);
+ ui4b src2_hi = ui5b_hi(src2);
+
+ ui5b r0 = ( (ui6b) src1_lo ) * src2_lo;
+ ui5b r1 = ( (ui6b) src1_hi ) * src2_lo;
+ ui5b r2 = ( (ui6b) src1_lo ) * src2_hi;
+ ui5b r3 = ( (ui6b) src1_hi ) * src2_hi;
+
+ ui5b ra1 = ui5b_hi(r0) + ui5b_lo(r1) + ui5b_lo(r2);
+
+ ui5b lo = (ui5b_lo(ra1) << 16) | ui5b_lo(r0);
+ ui5b hi = ui5b_hi(ra1) + ui5b_hi(r1) + ui5b_hi(r2) + r3;
+
+ Ui6fromHiLo(hi, lo, z);
+}
+
+#endif
+
+
+LOCALINLINEPROC mul64To128( ui6b a, ui6b b, ui6b *z0Ptr, ui6b *z1Ptr )
+{
+ ui5b aHigh, aLow, bHigh, bLow;
+ ui6b z0, zMiddleA, zMiddleB, z1;
+
+ aLow = a;
+ aHigh = a>>32;
+ bLow = b;
+ bHigh = b>>32;
+
+ Ui5to6Mul(aLow, bLow, &z1);
+ Ui5to6Mul(aLow, bHigh, &zMiddleA);
+ Ui5to6Mul(aHigh, bLow, &zMiddleB);
+ Ui5to6Mul(aHigh, bHigh, &z0);
+
+ zMiddleA += zMiddleB;
+ z0 += ( ( (ui6b) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 );
+ zMiddleA <<= 32;
+ z1 += zMiddleA;
+ z0 += ( z1 < zMiddleA );
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*----------------------------------------------------------------------------
+| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by
+| `b' to obtain a 192-bit product. The product is broken into three 64-bit
+| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
+| `z2Ptr'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEPROC
+ mul128By64To192(
+ ui6b a0,
+ ui6b a1,
+ ui6b b,
+ ui6b *z0Ptr,
+ ui6b *z1Ptr,
+ ui6b *z2Ptr
+ )
+{
+ ui6b z0, z1, z2, more1;
+
+ mul64To128( a1, b, &z1, &z2 );
+ mul64To128( a0, b, &z0, &more1 );
+ add128( z0, more1, 0, z1, &z0, &z1 );
+ *z2Ptr = z2;
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*----------------------------------------------------------------------------
+| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
+| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
+| product. The product is broken into four 64-bit pieces which are stored at
+| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEPROC
+ mul128To256(
+ ui6b a0,
+ ui6b a1,
+ ui6b b0,
+ ui6b b1,
+ ui6b *z0Ptr,
+ ui6b *z1Ptr,
+ ui6b *z2Ptr,
+ ui6b *z3Ptr
+ )
+{
+ ui6b z0, z1, z2, z3;
+ ui6b more1, more2;
+
+ mul64To128( a1, b1, &z2, &z3 );
+ mul64To128( a1, b0, &z1, &more2 );
+ add128( z1, more2, 0, z2, &z1, &z2 );
+ mul64To128( a0, b0, &z0, &more1 );
+ add128( z0, more1, 0, z1, &z0, &z1 );
+ mul64To128( a0, b1, &more1, &more2 );
+ add128( more1, more2, 0, z2, &more1, &z2 );
+ add128( z0, z1, 0, more1, &z0, &z1 );
+ *z3Ptr = z3;
+ *z2Ptr = z2;
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns an approximation to the 64-bit integer quotient obtained by dividing
+| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The
+| divisor `b' must be at least 2^63. If q is the exact quotient truncated
+| toward zero, the approximation returned lies between q and q + 2 inclusive.
+| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
+| unsigned integer is returned.
+*----------------------------------------------------------------------------*/
+
+#ifndef HaveUi6Div
+#define HaveUi6Div 0
+#endif
+
+#if HaveUi6Div
+#define Ui6Div(x, y) ((x) / (y))
+#else
+/*
+ Assuming other 64 bit operations available,
+ like compare, subtract, shift.
+*/
+LOCALFUNC ui6b Ui6Div(ui6b num, ui6b den)
+{
+ ui6b bit = 1;
+ ui6b res = 0;
+
+ while ((den < num) && bit && ! (den & (LIT64(1) << 63))) {
+ den <<= 1;
+ bit <<= 1;
+ }
+
+ while (bit) {
+ if (num >= den) {
+ num -= den;
+ res |= bit;
+ }
+ bit >>= 1;
+ den >>= 1;
+ }
+
+ return res;
+}
+#endif
+
+LOCALFUNC ui6b estimateDiv128To64( ui6b a0, ui6b a1, ui6b b )
+{
+ ui6b b0, b1;
+ ui6b rem0, rem1, term0, term1;
+ ui6b z;
+
+ if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
+ b0 = b>>32;
+ z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : Ui6Div(a0, b0) << 32;
+ mul64To128( b, z, &term0, &term1 );
+ sub128( a0, a1, term0, term1, &rem0, &rem1 );
+ while ( ( (si6b) rem0 ) < 0 ) {
+ z -= LIT64( 0x100000000 );
+ b1 = b<<32;
+ add128( rem0, rem1, b0, b1, &rem0, &rem1 );
+ }
+ rem0 = ( rem0<<32 ) | ( rem1>>32 );
+ z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : Ui6Div(rem0, b0);
+ return z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns an approximation to the square root of the 32-bit significand given
+| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of
+| `aExp' (the least significant bit) is 1, the integer returned approximates
+| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp'
+| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either
+| case, the approximation returned lies strictly within +/-2 of the exact
+| value.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC ui5b estimateSqrt32( si4r aExp, ui5b a )
+{
+ static const ui4b sqrtOddAdjustments[] = {
+ 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
+ 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
+ };
+ static const ui4b sqrtEvenAdjustments[] = {
+ 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
+ 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
+ };
+ si3r index;
+ ui5b z;
+
+ index = ( a>>27 ) & 15;
+ if ( aExp & 1 ) {
+ z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];
+ z = ( ( a / z )<<14 ) + ( z<<15 );
+ a >>= 1;
+ }
+ else {
+ z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];
+ z = a / z + z;
+ z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
+ if ( z <= a ) return (ui5b) ( ( (si5b) a )>>1 );
+ }
+ return ( (ui5b) Ui6Div( ( ( (ui6b) a )<<31 ), z ) ) + ( z>>1 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the number of leading 0 bits before the most-significant 1 bit of
+| `a'. If `a' is zero, 32 is returned.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC si3r countLeadingZeros32( ui5b a )
+{
+ static const si3r countLeadingZerosHigh[] = {
+ 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ si3r shiftCount;
+
+ shiftCount = 0;
+ if ( a < 0x10000 ) {
+ shiftCount += 16;
+ a <<= 16;
+ }
+ if ( a < 0x1000000 ) {
+ shiftCount += 8;
+ a <<= 8;
+ }
+ shiftCount += countLeadingZerosHigh[ a>>24 ];
+ return shiftCount;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the number of leading 0 bits before the most-significant 1 bit of
+| `a'. If `a' is zero, 64 is returned.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC si3r countLeadingZeros64( ui6b a )
+{
+ si3r shiftCount;
+
+ shiftCount = 0;
+ if ( a < ( (ui6b) 1 )<<32 ) {
+ shiftCount += 32;
+ }
+ else {
+ a >>= 32;
+ }
+ shiftCount += countLeadingZeros32( a );
+ return shiftCount;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
+| is equal to the 128-bit value formed by concatenating `b0' and `b1'.
+| Otherwise, returns 0.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC flag eq128( ui6b a0, ui6b a1, ui6b b0, ui6b b1 )
+{
+
+ return ( a0 == b0 ) && ( a1 == b1 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
+| than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
+| Otherwise, returns 0.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC flag le128( ui6b a0, ui6b a1, ui6b b0, ui6b b1 )
+{
+
+ return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
+| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise,
+| returns 0.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC flag lt128( ui6b a0, ui6b a1, ui6b b0, ui6b b1 )
+{
+
+ return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is
+| not equal to the 128-bit value formed by concatenating `b0' and `b1'.
+| Otherwise, returns 0.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALINLINEFUNC flag ne128( ui6b a0, ui6b a1, ui6b b0, ui6b b1 )
+{
+
+ return ( a0 != b0 ) || ( a1 != b1 );
+
+}
+#endif
+
+/* ----- end from original file "softfloat-macros" ----- */
+
+/*----------------------------------------------------------------------------
+| Functions and definitions to determine: (1) whether tininess for underflow
+| is detected before or after rounding by default, (2) what (if anything)
+| happens when exceptions are raised, (3) how signaling NaNs are distinguished
+| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
+| are propagated from function inputs to output. These details are target-
+| specific.
+*----------------------------------------------------------------------------*/
+
+/* ----- from original file "softfloat-specialize" ----- */
+
+/*============================================================================
+
+This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2b.
+
+["original SoftFloat Copyright notice" went here, included near top of this file.]
+
+=============================================================================*/
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point underflow tininess-detection mode.
+*----------------------------------------------------------------------------*/
+enum {
+ float_tininess_after_rounding = 0,
+ float_tininess_before_rounding = 1
+};
+
+/*----------------------------------------------------------------------------
+| Underflow tininess-detection mode, statically initialized to default value.
+| (The declaration in `softfloat.h' must match the `si3r' type here.)
+*----------------------------------------------------------------------------*/
+LOCALVAR si3r float_detect_tininess = float_tininess_after_rounding;
+
+/*----------------------------------------------------------------------------
+| Routine to raise any or all of the software IEC/IEEE floating-point
+| exception flags.
+*----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------
+| Raises the exceptions specified by `flags'. Floating-point traps can be
+| defined here if desired. It is currently not possible for such a trap
+| to substitute a result value. If traps are not implemented, this routine
+| should be simply `float_exception_flags |= flags;'.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC void float_raise( si3r flags )
+{
+
+ float_exception_flags |= flags;
+
+}
+
+/*----------------------------------------------------------------------------
+| Internal canonical NaN format.
+*----------------------------------------------------------------------------*/
+typedef struct {
+ flag sign;
+ ui6b high, low;
+} commonNaNT;
+
+/*----------------------------------------------------------------------------
+| The pattern for a default generated extended double-precision NaN. The
+| `high' and `low' values hold the most- and least-significant bits,
+| respectively.
+*----------------------------------------------------------------------------*/
+#define floatx80_default_nan_high 0xFFFF
+#define floatx80_default_nan_low LIT64( 0xC000000000000000 )
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point value `a' is a
+| NaN; otherwise returns 0.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC flag floatx80_is_nan( floatx80 a )
+{
+
+ return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (ui6b) ( a.low<<1 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point value `a' is a
+| signaling NaN; otherwise returns 0.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC flag floatx80_is_signaling_nan( floatx80 a )
+{
+ ui6b aLow;
+
+ aLow = a.low & ~ LIT64( 0x4000000000000000 );
+ return
+ ( ( a.high & 0x7FFF ) == 0x7FFF )
+ && (ui6b) ( aLow<<1 )
+ && ( a.low == aLow );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the extended double-precision floating-
+| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
+| invalid exception is raised.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC commonNaNT floatx80ToCommonNaN( floatx80 a )
+{
+ commonNaNT z;
+
+ if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
+ z.sign = a.high>>15;
+ z.low = 0;
+ z.high = a.low<<1;
+ return z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the canonical NaN `a' to the extended
+| double-precision floating-point format.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 commonNaNToFloatx80( commonNaNT a )
+{
+ floatx80 z;
+
+ z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
+ z.high = ( ( (ui4b) a.sign )<<15 ) | 0x7FFF;
+ return z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Takes two extended double-precision floating-point values `a' and `b', one
+| of which is a NaN, and returns the appropriate NaN result. If either `a' or
+| `b' is a signaling NaN, the invalid exception is raised.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
+{
+ flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
+
+ aIsNaN = floatx80_is_nan( a );
+ aIsSignalingNaN = floatx80_is_signaling_nan( a );
+ bIsNaN = floatx80_is_nan( b );
+ bIsSignalingNaN = floatx80_is_signaling_nan( b );
+ a.low |= LIT64( 0xC000000000000000 );
+ b.low |= LIT64( 0xC000000000000000 );
+ if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
+ if ( aIsSignalingNaN ) {
+ if ( bIsSignalingNaN ) goto returnLargerSignificand;
+ return bIsNaN ? b : a;
+ }
+ else if ( aIsNaN ) {
+ if ( bIsSignalingNaN | ! bIsNaN ) return a;
+ returnLargerSignificand:
+ if ( a.low < b.low ) return b;
+ if ( b.low < a.low ) return a;
+ return ( a.high < b.high ) ? a : b;
+ }
+ else {
+ return b;
+ }
+
+}
+
+#ifdef FLOAT128
+
+/*----------------------------------------------------------------------------
+| The pattern for a default generated quadruple-precision NaN. The `high' and
+| `low' values hold the most- and least-significant bits, respectively.
+*----------------------------------------------------------------------------*/
+#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
+#define float128_default_nan_low LIT64( 0x0000000000000000 )
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
+| otherwise returns 0.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC flag float128_is_nan( float128 a )
+{
+
+ return
+ ( LIT64( 0xFFFE000000000000 ) <= (ui6b) ( a.high<<1 ) )
+ && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the quadruple-precision floating-point value `a' is a
+| signaling NaN; otherwise returns 0.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC flag float128_is_signaling_nan( float128 a )
+{
+
+ return
+ ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
+ && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the quadruple-precision floating-point NaN
+| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
+| exception is raised.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC commonNaNT float128ToCommonNaN( float128 a )
+{
+ commonNaNT z;
+
+ if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
+ z.sign = a.high>>63;
+ shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
+ return z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the canonical NaN `a' to the quadruple-
+| precision floating-point format.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float128 commonNaNToFloat128( commonNaNT a )
+{
+ float128 z;
+
+ shift128Right( a.high, a.low, 16, &z.high, &z.low );
+ z.high |= ( ( (ui6b) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
+ return z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Takes two quadruple-precision floating-point values `a' and `b', one of
+| which is a NaN, and returns the appropriate NaN result. If either `a' or
+| `b' is a signaling NaN, the invalid exception is raised.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float128 propagateFloat128NaN( float128 a, float128 b )
+{
+ flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
+
+ aIsNaN = float128_is_nan( a );
+ aIsSignalingNaN = float128_is_signaling_nan( a );
+ bIsNaN = float128_is_nan( b );
+ bIsSignalingNaN = float128_is_signaling_nan( b );
+ a.high |= LIT64( 0x0000800000000000 );
+ b.high |= LIT64( 0x0000800000000000 );
+ if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
+ if ( aIsSignalingNaN ) {
+ if ( bIsSignalingNaN ) goto returnLargerSignificand;
+ return bIsNaN ? b : a;
+ }
+ else if ( aIsNaN ) {
+ if ( bIsSignalingNaN | ! bIsNaN ) return a;
+ returnLargerSignificand:
+ if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
+ if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
+ return ( a.high < b.high ) ? a : b;
+ }
+ else {
+ return b;
+ }
+
+}
+
+#endif
+
+/* ----- end from original file "softfloat-specialize" ----- */
+
+/* ----- from original file "softfloat.c" ----- */
+
+
+/*============================================================================
+
+This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
+Package, Release 2b.
+
+["original SoftFloat Copyright notice" went here, included near top of this file.]
+
+=============================================================================*/
+
+/*----------------------------------------------------------------------------
+| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
+| and 7, and returns the properly rounded 32-bit integer corresponding to the
+| input. If `zSign' is 1, the input is negated before being converted to an
+| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input
+| is simply rounded to an integer, with the inexact exception raised if the
+| input cannot be represented exactly as an integer. However, if the fixed-
+| point input is too large, the invalid exception is raised and the largest
+| positive or negative integer is returned.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC si5r roundAndPackInt32( flag zSign, ui6b absZ )
+{
+ si3r roundingMode;
+ flag roundNearestEven;
+ si3r roundIncrement, roundBits;
+ si5r z;
+
+ roundingMode = float_rounding_mode;
+ roundNearestEven = ( roundingMode == float_round_nearest_even );
+ roundIncrement = 0x40;
+ if ( ! roundNearestEven ) {
+ if ( roundingMode == float_round_to_zero ) {
+ roundIncrement = 0;
+ }
+ else {
+ roundIncrement = 0x7F;
+ if ( zSign ) {
+ if ( roundingMode == float_round_up ) roundIncrement = 0;
+ }
+ else {
+ if ( roundingMode == float_round_down ) roundIncrement = 0;
+ }
+ }
+ }
+ roundBits = absZ & 0x7F;
+ absZ = ( absZ + roundIncrement )>>7;
+ absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
+ z = absZ;
+ if ( zSign ) z = - z;
+ if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
+ float_raise( float_flag_invalid );
+ return zSign ? (si5b) 0x80000000 : 0x7FFFFFFF;
+ }
+ if ( roundBits ) float_exception_flags |= float_flag_inexact;
+ return z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the fraction bits of the extended double-precision floating-point
+| value `a'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC ui6b extractFloatx80Frac( floatx80 a )
+{
+
+ return a.low;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the exponent bits of the extended double-precision floating-point
+| value `a'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC si5r extractFloatx80Exp( floatx80 a )
+{
+
+ return a.high & 0x7FFF;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the sign bit of the extended double-precision floating-point value
+| `a'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC flag extractFloatx80Sign( floatx80 a )
+{
+
+ return a.high>>15;
+
+}
+
+/*----------------------------------------------------------------------------
+| Normalizes the subnormal extended double-precision floating-point value
+| represented by the denormalized significand `aSig'. The normalized exponent
+| and significand are stored at the locations pointed to by `zExpPtr' and
+| `zSigPtr', respectively.
+*----------------------------------------------------------------------------*/
+
+LOCALPROC
+ normalizeFloatx80Subnormal( ui6b aSig, si5r *zExpPtr, ui6b *zSigPtr )
+{
+ si3r shiftCount;
+
+ shiftCount = countLeadingZeros64( aSig );
+ *zSigPtr = aSig<<shiftCount;
+ *zExpPtr = 1 - shiftCount;
+
+}
+
+/*----------------------------------------------------------------------------
+| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
+| extended double-precision floating-point value, returning the result.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC floatx80 packFloatx80( flag zSign, si5r zExp, ui6b zSig )
+{
+ floatx80 z;
+
+ z.low = zSig;
+ z.high = ( ( (ui4b) zSign )<<15 ) + zExp;
+ return z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+| and extended significand formed by the concatenation of `zSig0' and `zSig1',
+| and returns the proper extended double-precision floating-point value
+| corresponding to the abstract input. Ordinarily, the abstract value is
+| rounded and packed into the extended double-precision format, with the
+| inexact exception raised if the abstract input cannot be represented
+| exactly. However, if the abstract value is too large, the overflow and
+| inexact exceptions are raised and an infinity or maximal finite value is
+| returned. If the abstract value is too small, the input value is rounded to
+| a subnormal number, and the underflow and inexact exceptions are raised if
+| the abstract input cannot be represented exactly as a subnormal extended
+| double-precision floating-point number.
+| If `roundingPrecision' is 32 or 64, the result is rounded to the same
+| number of bits as single or double precision, respectively. Otherwise, the
+| result is rounded to the full precision of the extended double-precision
+| format.
+| The input significand must be normalized or smaller. If the input
+| significand is not normalized, `zExp' must be 0; in that case, the result
+| returned is a subnormal number, and it must not require rounding. The
+| handling of underflow and overflow follows the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80
+ roundAndPackFloatx80(
+ si3r roundingPrecision, flag zSign, si5r zExp, ui6b zSig0, ui6b zSig1
+ )
+{
+ si3r roundingMode;
+ flag roundNearestEven, increment, isTiny;
+ si6r roundIncrement, roundMask, roundBits;
+
+ roundingMode = float_rounding_mode;
+ roundNearestEven = ( roundingMode == float_round_nearest_even );
+ if ( roundingPrecision == 80 ) goto precision80;
+ if ( roundingPrecision == 64 ) {
+ roundIncrement = LIT64( 0x0000000000000400 );
+ roundMask = LIT64( 0x00000000000007FF );
+ }
+ else if ( roundingPrecision == 32 ) {
+ roundIncrement = LIT64( 0x0000008000000000 );
+ roundMask = LIT64( 0x000000FFFFFFFFFF );
+ }
+ else {
+ goto precision80;
+ }
+ zSig0 |= ( zSig1 != 0 );
+ if ( ! roundNearestEven ) {
+ if ( roundingMode == float_round_to_zero ) {
+ roundIncrement = 0;
+ }
+ else {
+ roundIncrement = roundMask;
+ if ( zSign ) {
+ if ( roundingMode == float_round_up ) roundIncrement = 0;
+ }
+ else {
+ if ( roundingMode == float_round_down ) roundIncrement = 0;
+ }
+ }
+ }
+ roundBits = zSig0 & roundMask;
+ if ( 0x7FFD <= (ui5b) ( zExp - 1 ) ) {
+ if ( ( 0x7FFE < zExp )
+ || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
+ ) {
+ goto overflow;
+ }
+ if ( zExp <= 0 ) {
+ isTiny =
+ ( float_detect_tininess == float_tininess_before_rounding )
+ || ( zExp < 0 )
+ || ( zSig0 <= zSig0 + roundIncrement );
+ shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
+ zExp = 0;
+ roundBits = zSig0 & roundMask;
+ if ( isTiny && roundBits ) float_raise( float_flag_underflow );
+ if ( roundBits ) float_exception_flags |= float_flag_inexact;
+ zSig0 += roundIncrement;
+ if ( (si6b) zSig0 < 0 ) zExp = 1;
+ roundIncrement = roundMask + 1;
+ if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
+ roundMask |= roundIncrement;
+ }
+ zSig0 &= ~ roundMask;
+ return packFloatx80( zSign, zExp, zSig0 );
+ }
+ }
+ if ( roundBits ) float_exception_flags |= float_flag_inexact;
+ zSig0 += roundIncrement;
+ if ( zSig0 < roundIncrement ) {
+ ++zExp;
+ zSig0 = LIT64( 0x8000000000000000 );
+ }
+ roundIncrement = roundMask + 1;
+ if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
+ roundMask |= roundIncrement;
+ }
+ zSig0 &= ~ roundMask;
+ if ( zSig0 == 0 ) zExp = 0;
+ return packFloatx80( zSign, zExp, zSig0 );
+ precision80:
+ increment = ( (si6b) zSig1 < 0 );
+ if ( ! roundNearestEven ) {
+ if ( roundingMode == float_round_to_zero ) {
+ increment = 0;
+ }
+ else {
+ if ( zSign ) {
+ increment = ( roundingMode == float_round_down ) && zSig1;
+ }
+ else {
+ increment = ( roundingMode == float_round_up ) && zSig1;
+ }
+ }
+ }
+ if ( 0x7FFD <= (ui5b) ( zExp - 1 ) ) {
+ if ( ( 0x7FFE < zExp )
+ || ( ( zExp == 0x7FFE )
+ && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
+ && increment
+ )
+ ) {
+ roundMask = 0;
+ overflow:
+ float_raise( float_flag_overflow | float_flag_inexact );
+ if ( ( roundingMode == float_round_to_zero )
+ || ( zSign && ( roundingMode == float_round_up ) )
+ || ( ! zSign && ( roundingMode == float_round_down ) )
+ ) {
+ return packFloatx80( zSign, 0x7FFE, ~ roundMask );
+ }
+ return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( zExp <= 0 ) {
+ isTiny =
+ ( float_detect_tininess == float_tininess_before_rounding )
+ || ( zExp < 0 )
+ || ! increment
+ || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
+ shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
+ zExp = 0;
+ if ( isTiny && zSig1 ) float_raise( float_flag_underflow );
+ if ( zSig1 ) float_exception_flags |= float_flag_inexact;
+ if ( roundNearestEven ) {
+ increment = ( (si6b) zSig1 < 0 );
+ }
+ else {
+ if ( zSign ) {
+ increment = ( roundingMode == float_round_down ) && zSig1;
+ }
+ else {
+ increment = ( roundingMode == float_round_up ) && zSig1;
+ }
+ }
+ if ( increment ) {
+ ++zSig0;
+ zSig0 &=
+ ~ ( ( (ui6b) ( zSig1<<1 ) == 0 ) & roundNearestEven );
+ if ( (si6b) zSig0 < 0 ) zExp = 1;
+ }
+ return packFloatx80( zSign, zExp, zSig0 );
+ }
+ }
+ if ( zSig1 ) float_exception_flags |= float_flag_inexact;
+ if ( increment ) {
+ ++zSig0;
+ if ( zSig0 == 0 ) {
+ ++zExp;
+ zSig0 = LIT64( 0x8000000000000000 );
+ }
+ else {
+ zSig0 &= ~ ( ( (ui6b) ( zSig1<<1 ) == 0 ) & roundNearestEven );
+ }
+ }
+ else {
+ if ( zSig0 == 0 ) zExp = 0;
+ }
+ return packFloatx80( zSign, zExp, zSig0 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Takes an abstract floating-point value having sign `zSign', exponent
+| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
+| and returns the proper extended double-precision floating-point value
+| corresponding to the abstract input. This routine is just like
+| `roundAndPackFloatx80' except that the input significand does not have to be
+| normalized.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80
+ normalizeRoundAndPackFloatx80(
+ si3r roundingPrecision, flag zSign, si5r zExp, ui6b zSig0, ui6b zSig1
+ )
+{
+ si3r shiftCount;
+
+ if ( zSig0 == 0 ) {
+ zSig0 = zSig1;
+ zSig1 = 0;
+ zExp -= 64;
+ }
+ shiftCount = countLeadingZeros64( zSig0 );
+ shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
+ zExp -= shiftCount;
+ return
+ roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 );
+
+}
+
+#ifdef FLOAT128
+
+/*----------------------------------------------------------------------------
+| Returns the least-significant 64 fraction bits of the quadruple-precision
+| floating-point value `a'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC ui6b extractFloat128Frac1( float128 a )
+{
+
+ return a.low;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the most-significant 48 fraction bits of the quadruple-precision
+| floating-point value `a'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC ui6b extractFloat128Frac0( float128 a )
+{
+
+ return a.high & LIT64( 0x0000FFFFFFFFFFFF );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the exponent bits of the quadruple-precision floating-point value
+| `a'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC si5r extractFloat128Exp( float128 a )
+{
+
+ return ( a.high>>48 ) & 0x7FFF;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the sign bit of the quadruple-precision floating-point value `a'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC flag extractFloat128Sign( float128 a )
+{
+
+ return a.high>>63;
+
+}
+
+/*----------------------------------------------------------------------------
+| Normalizes the subnormal quadruple-precision floating-point value
+| represented by the denormalized significand formed by the concatenation of
+| `aSig0' and `aSig1'. The normalized exponent is stored at the location
+| pointed to by `zExpPtr'. The most significant 49 bits of the normalized
+| significand are stored at the location pointed to by `zSig0Ptr', and the
+| least significant 64 bits of the normalized significand are stored at the
+| location pointed to by `zSig1Ptr'.
+*----------------------------------------------------------------------------*/
+
+LOCALPROC
+ normalizeFloat128Subnormal(
+ ui6b aSig0,
+ ui6b aSig1,
+ si5r *zExpPtr,
+ ui6b *zSig0Ptr,
+ ui6b *zSig1Ptr
+ )
+{
+ si3r shiftCount;
+
+ if ( aSig0 == 0 ) {
+ shiftCount = countLeadingZeros64( aSig1 ) - 15;
+ if ( shiftCount < 0 ) {
+ *zSig0Ptr = aSig1>>( - shiftCount );
+ *zSig1Ptr = aSig1<<( shiftCount & 63 );
+ }
+ else {
+ *zSig0Ptr = aSig1<<shiftCount;
+ *zSig1Ptr = 0;
+ }
+ *zExpPtr = - shiftCount - 63;
+ }
+ else {
+ shiftCount = countLeadingZeros64( aSig0 ) - 15;
+ shortShift128Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );
+ *zExpPtr = 1 - shiftCount;
+ }
+
+}
+
+/*----------------------------------------------------------------------------
+| Packs the sign `zSign', the exponent `zExp', and the significand formed
+| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
+| floating-point value, returning the result. After being shifted into the
+| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
+| added together to form the most significant 32 bits of the result. This
+| means that any integer portion of `zSig0' will be added into the exponent.
+| Since a properly normalized significand will have an integer portion equal
+| to 1, the `zExp' input should be 1 less than the desired result exponent
+| whenever `zSig0' and `zSig1' concatenated form a complete, normalized
+| significand.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC float128
+ packFloat128( flag zSign, si5r zExp, ui6b zSig0, ui6b zSig1 )
+{
+ float128 z;
+
+ z.low = zSig1;
+ z.high = ( ( (ui6b) zSign )<<63 ) + ( ( (ui6b) zExp )<<48 ) + zSig0;
+ return z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+| and extended significand formed by the concatenation of `zSig0', `zSig1',
+| and `zSig2', and returns the proper quadruple-precision floating-point value
+| corresponding to the abstract input. Ordinarily, the abstract value is
+| simply rounded and packed into the quadruple-precision format, with the
+| inexact exception raised if the abstract input cannot be represented
+| exactly. However, if the abstract value is too large, the overflow and
+| inexact exceptions are raised and an infinity or maximal finite value is
+| returned. If the abstract value is too small, the input value is rounded to
+| a subnormal number, and the underflow and inexact exceptions are raised if
+| the abstract input cannot be represented exactly as a subnormal quadruple-
+| precision floating-point number.
+| The input significand must be normalized or smaller. If the input
+| significand is not normalized, `zExp' must be 0; in that case, the result
+| returned is a subnormal number, and it must not require rounding. In the
+| usual case that the input significand is normalized, `zExp' must be 1 less
+| than the ``true'' floating-point exponent. The handling of underflow and
+| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float128
+ roundAndPackFloat128(
+ flag zSign, si5r zExp, ui6b zSig0, ui6b zSig1, ui6b zSig2 )
+{
+ si3r roundingMode;
+ flag roundNearestEven, increment, isTiny;
+
+ roundingMode = float_rounding_mode;
+ roundNearestEven = ( roundingMode == float_round_nearest_even );
+ increment = ( (si6b) zSig2 < 0 );
+ if ( ! roundNearestEven ) {
+ if ( roundingMode == float_round_to_zero ) {
+ increment = 0;
+ }
+ else {
+ if ( zSign ) {
+ increment = ( roundingMode == float_round_down ) && zSig2;
+ }
+ else {
+ increment = ( roundingMode == float_round_up ) && zSig2;
+ }
+ }
+ }
+ if ( 0x7FFD <= (ui5b) zExp ) {
+ if ( ( 0x7FFD < zExp )
+ || ( ( zExp == 0x7FFD )
+ && eq128(
+ LIT64( 0x0001FFFFFFFFFFFF ),
+ LIT64( 0xFFFFFFFFFFFFFFFF ),
+ zSig0,
+ zSig1
+ )
+ && increment
+ )
+ ) {
+ float_raise( float_flag_overflow | float_flag_inexact );
+ if ( ( roundingMode == float_round_to_zero )
+ || ( zSign && ( roundingMode == float_round_up ) )
+ || ( ! zSign && ( roundingMode == float_round_down ) )
+ ) {
+ return
+ packFloat128(
+ zSign,
+ 0x7FFE,
+ LIT64( 0x0000FFFFFFFFFFFF ),
+ LIT64( 0xFFFFFFFFFFFFFFFF )
+ );
+ }
+ return packFloat128( zSign, 0x7FFF, 0, 0 );
+ }
+ if ( zExp < 0 ) {
+ isTiny =
+ ( float_detect_tininess == float_tininess_before_rounding )
+ || ( zExp < -1 )
+ || ! increment
+ || lt128(
+ zSig0,
+ zSig1,
+ LIT64( 0x0001FFFFFFFFFFFF ),
+ LIT64( 0xFFFFFFFFFFFFFFFF )
+ );
+ shift128ExtraRightJamming(
+ zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
+ zExp = 0;
+ if ( isTiny && zSig2 ) float_raise( float_flag_underflow );
+ if ( roundNearestEven ) {
+ increment = ( (si6b) zSig2 < 0 );
+ }
+ else {
+ if ( zSign ) {
+ increment = ( roundingMode == float_round_down ) && zSig2;
+ }
+ else {
+ increment = ( roundingMode == float_round_up ) && zSig2;
+ }
+ }
+ }
+ }
+ if ( zSig2 ) float_exception_flags |= float_flag_inexact;
+ if ( increment ) {
+ add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
+ zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
+ }
+ else {
+ if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
+ }
+ return packFloat128( zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+| and significand formed by the concatenation of `zSig0' and `zSig1', and
+| returns the proper quadruple-precision floating-point value corresponding
+| to the abstract input. This routine is just like `roundAndPackFloat128'
+| except that the input significand has fewer bits and does not have to be
+| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating-
+| point exponent.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float128
+ normalizeRoundAndPackFloat128(
+ flag zSign, si5r zExp, ui6b zSig0, ui6b zSig1 )
+{
+ si3r shiftCount;
+ ui6b zSig2;
+
+ if ( zSig0 == 0 ) {
+ zSig0 = zSig1;
+ zSig1 = 0;
+ zExp -= 64;
+ }
+ shiftCount = countLeadingZeros64( zSig0 ) - 15;
+ if ( 0 <= shiftCount ) {
+ zSig2 = 0;
+ shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
+ }
+ else {
+ shift128ExtraRightJamming(
+ zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
+ }
+ zExp -= shiftCount;
+ return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
+
+}
+
+#endif
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the 32-bit two's complement integer `a'
+| to the extended double-precision floating-point format. The conversion
+| is performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 int32_to_floatx80( si5r a )
+{
+ flag zSign;
+ ui5r absA;
+ si3r shiftCount;
+ ui6b zSig;
+
+ if ( a == 0 ) return packFloatx80( 0, 0, 0 );
+ zSign = ( a < 0 );
+ absA = zSign ? - a : a;
+ shiftCount = countLeadingZeros32( absA ) + 32;
+ zSig = absA;
+ return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the extended double-precision floating-
+| point value `a' to the 32-bit two's complement integer format. The
+| conversion is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic---which means in particular that the conversion
+| is rounded according to the current rounding mode. If `a' is a NaN, the
+| largest positive integer is returned. Otherwise, if the conversion
+| overflows, the largest integer with the same sign as `a' is returned.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC si5r floatx80_to_int32( floatx80 a )
+{
+ flag aSign;
+ si5r aExp, shiftCount;
+ ui6b aSig;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ if ( ( aExp == 0x7FFF ) && (ui6b) ( aSig<<1 ) ) aSign = 0;
+ shiftCount = 0x4037 - aExp;
+ if ( shiftCount <= 0 ) shiftCount = 1;
+ shift64RightJamming( aSig, shiftCount, &aSig );
+ return roundAndPackInt32( aSign, aSig );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the extended double-precision floating-
+| point value `a' to the 32-bit two's complement integer format. The
+| conversion is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic, except that the conversion is always rounded
+| toward zero. If `a' is a NaN, the largest positive integer is returned.
+| Otherwise, if the conversion overflows, the largest integer with the same
+| sign as `a' is returned.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALFUNC si5r floatx80_to_int32_round_to_zero( floatx80 a )
+{
+ flag aSign;
+ si5r aExp, shiftCount;
+ ui6b aSig, savedASig;
+ si5r z;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ if ( 0x401E < aExp ) {
+ if ( ( aExp == 0x7FFF ) && (ui6b) ( aSig<<1 ) ) aSign = 0;
+ goto invalid;
+ }
+ else if ( aExp < 0x3FFF ) {
+ if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
+ return 0;
+ }
+ shiftCount = 0x403E - aExp;
+ savedASig = aSig;
+ aSig >>= shiftCount;
+ z = aSig;
+ if ( aSign ) z = - z;
+ if ( ( z < 0 ) ^ aSign ) {
+ invalid:
+ float_raise( float_flag_invalid );
+ return aSign ? (si5b) 0x80000000 : 0x7FFFFFFF;
+ }
+ if ( ( aSig<<shiftCount ) != savedASig ) {
+ float_exception_flags |= float_flag_inexact;
+ }
+ return z;
+
+}
+#endif
+
+#ifdef FLOAT128
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the extended double-precision floating-
+| point value `a' to the quadruple-precision floating-point format. The
+| conversion is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float128 floatx80_to_float128( floatx80 a )
+{
+ flag aSign;
+ si4r aExp;
+ ui6b aSig, zSig0, zSig1;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ if ( ( aExp == 0x7FFF ) && (ui6b) ( aSig<<1 ) ) {
+ return commonNaNToFloat128( floatx80ToCommonNaN( a ) );
+ }
+ shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 );
+ return packFloat128( aSign, aExp, zSig0, zSig1 );
+
+}
+
+#endif
+
+/*----------------------------------------------------------------------------
+| Rounds the extended double-precision floating-point value `a' to an integer,
+| and returns the result as an extended quadruple-precision floating-point
+| value. The operation is performed according to the IEC/IEEE Standard for
+| Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 floatx80_round_to_int( floatx80 a )
+{
+ flag aSign;
+ si5r aExp;
+ ui6b lastBitMask, roundBitsMask;
+ si3r roundingMode;
+ floatx80 z;
+
+ aExp = extractFloatx80Exp( a );
+ if ( 0x403E <= aExp ) {
+ if ( ( aExp == 0x7FFF ) && (ui6b) ( extractFloatx80Frac( a )<<1 ) ) {
+ return propagateFloatx80NaN( a, a );
+ }
+ return a;
+ }
+ if ( aExp < 0x3FFF ) {
+ if ( ( aExp == 0 )
+ && ( (ui6b) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
+ return a;
+ }
+ float_exception_flags |= float_flag_inexact;
+ aSign = extractFloatx80Sign( a );
+ switch ( float_rounding_mode ) {
+ case float_round_nearest_even:
+ if ( ( aExp == 0x3FFE ) && (ui6b) ( extractFloatx80Frac( a )<<1 )
+ ) {
+ return
+ packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
+ }
+ break;
+ case float_round_down:
+ return
+ aSign ?
+ packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
+ : packFloatx80( 0, 0, 0 );
+ case float_round_up:
+ return
+ aSign ? packFloatx80( 1, 0, 0 )
+ : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
+ }
+ return packFloatx80( aSign, 0, 0 );
+ }
+ lastBitMask = 1;
+ lastBitMask <<= 0x403E - aExp;
+ roundBitsMask = lastBitMask - 1;
+ z = a;
+ roundingMode = float_rounding_mode;
+ if ( roundingMode == float_round_nearest_even ) {
+ z.low += lastBitMask>>1;
+ if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
+ }
+ else if ( roundingMode != float_round_to_zero ) {
+ if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
+ z.low += roundBitsMask;
+ }
+ }
+ z.low &= ~ roundBitsMask;
+ if ( z.low == 0 ) {
+ ++z.high;
+ z.low = LIT64( 0x8000000000000000 );
+ }
+ if ( z.low != a.low ) float_exception_flags |= float_flag_inexact;
+ return z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of adding the absolute values of the extended double-
+| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is
+| negated before being returned. `zSign' is ignored if the result is a NaN.
+| The addition is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
+{
+ si5r aExp, bExp, zExp;
+ ui6b aSig, bSig, zSig0, zSig1;
+ si5r expDiff;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ bSig = extractFloatx80Frac( b );
+ bExp = extractFloatx80Exp( b );
+ expDiff = aExp - bExp;
+ if ( 0 < expDiff ) {
+ if ( aExp == 0x7FFF ) {
+ if ( (ui6b) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) --expDiff;
+ shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
+ zExp = aExp;
+ }
+ else if ( expDiff < 0 ) {
+ if ( bExp == 0x7FFF ) {
+ if ( (ui6b) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( aExp == 0 ) ++expDiff;
+ shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
+ zExp = bExp;
+ }
+ else {
+ if ( aExp == 0x7FFF ) {
+ if ( (ui6b) ( ( aSig | bSig )<<1 ) ) {
+ return propagateFloatx80NaN( a, b );
+ }
+ return a;
+ }
+ zSig1 = 0;
+ zSig0 = aSig + bSig;
+ if ( aExp == 0 ) {
+ normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
+ goto roundAndPack;
+ }
+ zExp = aExp;
+ goto shiftRight1;
+ }
+ zSig0 = aSig + bSig;
+ if ( (si6b) zSig0 < 0 ) goto roundAndPack;
+ shiftRight1:
+ shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
+ zSig0 |= LIT64( 0x8000000000000000 );
+ ++zExp;
+ roundAndPack:
+ return
+ roundAndPackFloatx80(
+ floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of subtracting the absolute values of the extended
+| double-precision floating-point values `a' and `b'. If `zSign' is 1, the
+| difference is negated before being returned. `zSign' is ignored if the
+| result is a NaN. The subtraction is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
+{
+ si5r aExp, bExp, zExp;
+ ui6b aSig, bSig, zSig0, zSig1;
+ si5r expDiff;
+ floatx80 z;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ bSig = extractFloatx80Frac( b );
+ bExp = extractFloatx80Exp( b );
+ expDiff = aExp - bExp;
+ if ( 0 < expDiff ) goto aExpBigger;
+ if ( expDiff < 0 ) goto bExpBigger;
+ if ( aExp == 0x7FFF ) {
+ if ( (ui6b) ( ( aSig | bSig )<<1 ) ) {
+ return propagateFloatx80NaN( a, b );
+ }
+ float_raise( float_flag_invalid );
+ z.low = floatx80_default_nan_low;
+ z.high = floatx80_default_nan_high;
+ return z;
+ }
+ if ( aExp == 0 ) {
+ aExp = 1;
+ bExp = 1;
+ }
+ zSig1 = 0;
+ if ( bSig < aSig ) goto aBigger;
+ if ( aSig < bSig ) goto bBigger;
+ return packFloatx80( float_rounding_mode == float_round_down, 0, 0 );
+ bExpBigger:
+ if ( bExp == 0x7FFF ) {
+ if ( (ui6b) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( aExp == 0 ) ++expDiff;
+ shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
+ bBigger:
+ sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
+ zExp = bExp;
+ zSign ^= 1;
+ goto normalizeRoundAndPack;
+ aExpBigger:
+ if ( aExp == 0x7FFF ) {
+ if ( (ui6b) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) --expDiff;
+ shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
+ aBigger:
+ sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
+ zExp = aExp;
+ normalizeRoundAndPack:
+ return
+ normalizeRoundAndPackFloatx80(
+ floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of adding the extended double-precision floating-point
+| values `a' and `b'. The operation is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 floatx80_add( floatx80 a, floatx80 b )
+{
+ flag aSign, bSign;
+
+ aSign = extractFloatx80Sign( a );
+ bSign = extractFloatx80Sign( b );
+ if ( aSign == bSign ) {
+ return addFloatx80Sigs( a, b, aSign );
+ }
+ else {
+ return subFloatx80Sigs( a, b, aSign );
+ }
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of subtracting the extended double-precision floating-
+| point values `a' and `b'. The operation is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 floatx80_sub( floatx80 a, floatx80 b )
+{
+ flag aSign, bSign;
+
+ aSign = extractFloatx80Sign( a );
+ bSign = extractFloatx80Sign( b );
+ if ( aSign == bSign ) {
+ return subFloatx80Sigs( a, b, aSign );
+ }
+ else {
+ return addFloatx80Sigs( a, b, aSign );
+ }
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of multiplying the extended double-precision floating-
+| point values `a' and `b'. The operation is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 floatx80_mul( floatx80 a, floatx80 b )
+{
+ flag aSign, bSign, zSign;
+ si5r aExp, bExp, zExp;
+ ui6b aSig, bSig, zSig0, zSig1;
+ floatx80 z;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ bSig = extractFloatx80Frac( b );
+ bExp = extractFloatx80Exp( b );
+ bSign = extractFloatx80Sign( b );
+ zSign = aSign ^ bSign;
+ if ( aExp == 0x7FFF ) {
+ if ( (ui6b) ( aSig<<1 )
+ || ( ( bExp == 0x7FFF ) && (ui6b) ( bSig<<1 ) ) ) {
+ return propagateFloatx80NaN( a, b );
+ }
+ if ( ( bExp | bSig ) == 0 ) goto invalid;
+ return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( bExp == 0x7FFF ) {
+ if ( (ui6b) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ if ( ( aExp | aSig ) == 0 ) {
+ invalid:
+ float_raise( float_flag_invalid );
+ z.low = floatx80_default_nan_low;
+ z.high = floatx80_default_nan_high;
+ return z;
+ }
+ return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
+ normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
+ }
+ if ( bExp == 0 ) {
+ if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
+ normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
+ }
+ zExp = aExp + bExp - 0x3FFE;
+ mul64To128( aSig, bSig, &zSig0, &zSig1 );
+ if ( 0 < (si6b) zSig0 ) {
+ shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
+ --zExp;
+ }
+ return
+ roundAndPackFloatx80(
+ floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of dividing the extended double-precision floating-point
+| value `a' by the corresponding value `b'. The operation is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 floatx80_div( floatx80 a, floatx80 b )
+{
+ flag aSign, bSign, zSign;
+ si5r aExp, bExp, zExp;
+ ui6b aSig, bSig, zSig0, zSig1;
+ ui6b rem0, rem1, rem2, term0, term1, term2;
+ floatx80 z;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ bSig = extractFloatx80Frac( b );
+ bExp = extractFloatx80Exp( b );
+ bSign = extractFloatx80Sign( b );
+ zSign = aSign ^ bSign;
+ if ( aExp == 0x7FFF ) {
+ if ( (ui6b) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ if ( bExp == 0x7FFF ) {
+ if ( (ui6b) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ goto invalid;
+ }
+ return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( bExp == 0x7FFF ) {
+ if ( (ui6b) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ return packFloatx80( zSign, 0, 0 );
+ }
+ if ( bExp == 0 ) {
+ if ( bSig == 0 ) {
+ if ( ( aExp | aSig ) == 0 ) {
+ invalid:
+ float_raise( float_flag_invalid );
+ z.low = floatx80_default_nan_low;
+ z.high = floatx80_default_nan_high;
+ return z;
+ }
+ float_raise( float_flag_divbyzero );
+ return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
+ normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
+ }
+ if ( aSig == 0 ) {
+ /*
+ added by pcp. this invalid input seems to
+ cause hang in estimateDiv128To64. should
+ validate inputs generally.
+ */
+ return packFloatx80( zSign, 0, 0 );
+ }
+ if ( (si6b) bSig >= 0 ) {
+ /*
+ added by pcp. another check.
+ invalid input, most significant bit should be set?
+ */
+ return packFloatx80( zSign, 0, 0 );
+ }
+ zExp = aExp - bExp + 0x3FFE;
+ rem1 = 0;
+ if ( bSig <= aSig ) {
+ shift128Right( aSig, 0, 1, &aSig, &rem1 );
+ ++zExp;
+ }
+ zSig0 = estimateDiv128To64( aSig, rem1, bSig );
+ mul64To128( bSig, zSig0, &term0, &term1 );
+ sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
+ while ( (si6b) rem0 < 0 ) {
+ --zSig0;
+ add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
+ }
+ zSig1 = estimateDiv128To64( rem1, 0, bSig );
+ if ( (ui6b) ( zSig1<<1 ) <= 8 ) {
+ mul64To128( bSig, zSig1, &term1, &term2 );
+ sub128( rem1, 0, term1, term2, &rem1, &rem2 );
+ while ( (si6b) rem1 < 0 ) {
+ --zSig1;
+ add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
+ }
+ zSig1 |= ( ( rem1 | rem2 ) != 0 );
+ }
+ return
+ roundAndPackFloatx80(
+ floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the remainder of the extended double-precision floating-point value
+| `a' with respect to the corresponding value `b'. The operation is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 floatx80_rem( floatx80 a, floatx80 b )
+{
+ flag aSign, /* bSign, */ zSign;
+ si5r aExp, bExp, expDiff;
+ ui6b aSig0, aSig1, bSig;
+ ui6b q, term0, term1, alternateASig0, alternateASig1;
+ floatx80 z;
+
+ aSig0 = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ bSig = extractFloatx80Frac( b );
+ bExp = extractFloatx80Exp( b );
+ /*
+ not used. should it be?
+ bSign = extractFloatx80Sign( b );
+ */
+ if ( aExp == 0x7FFF ) {
+ if ( (ui6b) ( aSig0<<1 )
+ || ( ( bExp == 0x7FFF ) && (ui6b) ( bSig<<1 ) ) ) {
+ return propagateFloatx80NaN( a, b );
+ }
+ goto invalid;
+ }
+ if ( bExp == 0x7FFF ) {
+ if ( (ui6b) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) {
+ if ( bSig == 0 ) {
+ invalid:
+ float_raise( float_flag_invalid );
+ z.low = floatx80_default_nan_low;
+ z.high = floatx80_default_nan_high;
+ return z;
+ }
+ normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
+ }
+ if ( aExp == 0 ) {
+ if ( (ui6b) ( aSig0<<1 ) == 0 ) return a;
+ normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
+ }
+ bSig |= LIT64( 0x8000000000000000 );
+ zSign = aSign;
+ expDiff = aExp - bExp;
+ aSig1 = 0;
+ if ( expDiff < 0 ) {
+ if ( expDiff < -1 ) return a;
+ shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
+ expDiff = 0;
+ }
+ q = ( bSig <= aSig0 );
+ if ( q ) aSig0 -= bSig;
+ expDiff -= 64;
+ while ( 0 < expDiff ) {
+ q = estimateDiv128To64( aSig0, aSig1, bSig );
+ q = ( 2 < q ) ? q - 2 : 0;
+ mul64To128( bSig, q, &term0, &term1 );
+ sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
+ shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
+ expDiff -= 62;
+ }
+ expDiff += 64;
+ if ( 0 < expDiff ) {
+ q = estimateDiv128To64( aSig0, aSig1, bSig );
+ q = ( 2 < q ) ? q - 2 : 0;
+ q >>= 64 - expDiff;
+ mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
+ sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
+ shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
+ while ( le128( term0, term1, aSig0, aSig1 ) ) {
+ ++q;
+ sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
+ }
+ }
+ else {
+ term1 = 0;
+ term0 = bSig;
+ }
+ sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
+ if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
+ || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
+ && ( q & 1 ) )
+ ) {
+ aSig0 = alternateASig0;
+ aSig1 = alternateASig1;
+ zSign = ! zSign;
+ }
+ return
+ normalizeRoundAndPackFloatx80(
+ 80, zSign, bExp + expDiff, aSig0, aSig1 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the square root of the extended double-precision floating-point
+| value `a'. The operation is performed according to the IEC/IEEE Standard
+| for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 floatx80_sqrt( floatx80 a )
+{
+ flag aSign;
+ si5r aExp, zExp;
+ ui6b aSig0, aSig1, zSig0, zSig1, doubleZSig0;
+ ui6b rem0, rem1, rem2, rem3, term0, term1, term2, term3;
+ floatx80 z;
+
+ aSig0 = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ if ( aExp == 0x7FFF ) {
+ if ( (ui6b) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a );
+ if ( ! aSign ) return a;
+ goto invalid;
+ }
+ if ( aSign ) {
+ if ( ( aExp | aSig0 ) == 0 ) return a;
+ invalid:
+ float_raise( float_flag_invalid );
+ z.low = floatx80_default_nan_low;
+ z.high = floatx80_default_nan_high;
+ return z;
+ }
+ if ( aExp == 0 ) {
+ if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
+ normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
+ }
+ zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
+ zSig0 = estimateSqrt32( aExp, aSig0>>32 );
+ shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 );
+ zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
+ doubleZSig0 = zSig0<<1;
+ mul64To128( zSig0, zSig0, &term0, &term1 );
+ sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
+ while ( (si6b) rem0 < 0 ) {
+ --zSig0;
+ doubleZSig0 -= 2;
+ add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
+ }
+ zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
+ if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) {
+ if ( zSig1 == 0 ) zSig1 = 1;
+ mul64To128( doubleZSig0, zSig1, &term1, &term2 );
+ sub128( rem1, 0, term1, term2, &rem1, &rem2 );
+ mul64To128( zSig1, zSig1, &term2, &term3 );
+ sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
+ while ( (si6b) rem1 < 0 ) {
+ --zSig1;
+ shortShift128Left( 0, zSig1, 1, &term2, &term3 );
+ term3 |= 1;
+ term2 |= doubleZSig0;
+ add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
+ }
+ zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
+ }
+ shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 );
+ zSig0 |= doubleZSig0;
+ return
+ roundAndPackFloatx80(
+ floatx80_rounding_precision, 0, zExp, zSig0, zSig1 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point value `a' is
+| equal to the corresponding value `b', and 0 otherwise. The comparison is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALFUNC flag floatx80_eq( floatx80 a, floatx80 b )
+{
+
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (ui6b) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (ui6b) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ if ( floatx80_is_signaling_nan( a )
+ || floatx80_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid );
+ }
+ return 0;
+ }
+ return
+ ( a.low == b.low )
+ && ( ( a.high == b.high )
+ || ( ( a.low == 0 )
+ && ( (ui4b) ( ( a.high | b.high )<<1 ) == 0 ) )
+ );
+
+}
+#endif
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point value `a' is
+| less than or equal to the corresponding value `b', and 0 otherwise. The
+| comparison is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALFUNC flag floatx80_le( floatx80 a, floatx80 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (ui6b) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (ui6b) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ float_raise( float_flag_invalid );
+ return 0;
+ }
+ aSign = extractFloatx80Sign( a );
+ bSign = extractFloatx80Sign( b );
+ if ( aSign != bSign ) {
+ return
+ aSign
+ || ( ( ( (ui4b) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+ == 0 );
+ }
+ return
+ aSign ? le128( b.high, b.low, a.high, a.low )
+ : le128( a.high, a.low, b.high, b.low );
+
+}
+#endif
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point value `a' is
+| less than the corresponding value `b', and 0 otherwise. The comparison
+| is performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALFUNC flag floatx80_lt( floatx80 a, floatx80 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (ui6b) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (ui6b) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ float_raise( float_flag_invalid );
+ return 0;
+ }
+ aSign = extractFloatx80Sign( a );
+ bSign = extractFloatx80Sign( b );
+ if ( aSign != bSign ) {
+ return
+ aSign
+ && ( ( ( (ui4b) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+ != 0 );
+ }
+ return
+ aSign ? lt128( b.high, b.low, a.high, a.low )
+ : lt128( a.high, a.low, b.high, b.low );
+
+}
+#endif
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point value `a' is equal
+| to the corresponding value `b', and 0 otherwise. The invalid exception is
+| raised if either operand is a NaN. Otherwise, the comparison is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALFUNC flag floatx80_eq_signaling( floatx80 a, floatx80 b )
+{
+
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (ui6b) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (ui6b) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ float_raise( float_flag_invalid );
+ return 0;
+ }
+ return
+ ( a.low == b.low )
+ && ( ( a.high == b.high )
+ || ( ( a.low == 0 )
+ && ( (ui4b) ( ( a.high | b.high )<<1 ) == 0 ) )
+ );
+
+}
+#endif
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point value `a' is less
+| than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs
+| do not cause an exception. Otherwise, the comparison is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALFUNC flag floatx80_le_quiet( floatx80 a, floatx80 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (ui6b) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (ui6b) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ if ( floatx80_is_signaling_nan( a )
+ || floatx80_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid );
+ }
+ return 0;
+ }
+ aSign = extractFloatx80Sign( a );
+ bSign = extractFloatx80Sign( b );
+ if ( aSign != bSign ) {
+ return
+ aSign
+ || ( ( ( (ui4b) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+ == 0 );
+ }
+ return
+ aSign ? le128( b.high, b.low, a.high, a.low )
+ : le128( a.high, a.low, b.high, b.low );
+
+}
+#endif
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point value `a' is less
+| than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause
+| an exception. Otherwise, the comparison is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALFUNC flag floatx80_lt_quiet( floatx80 a, floatx80 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (ui6b) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (ui6b) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ if ( floatx80_is_signaling_nan( a )
+ || floatx80_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid );
+ }
+ return 0;
+ }
+ aSign = extractFloatx80Sign( a );
+ bSign = extractFloatx80Sign( b );
+ if ( aSign != bSign ) {
+ return
+ aSign
+ && ( ( ( (ui4b) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+ != 0 );
+ }
+ return
+ aSign ? lt128( b.high, b.low, a.high, a.low )
+ : lt128( a.high, a.low, b.high, b.low );
+
+}
+#endif
+
+#ifdef FLOAT128
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the quadruple-precision floating-point
+| value `a' to the extended double-precision floating-point format. The
+| conversion is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 float128_to_floatx80( float128 a )
+{
+ flag aSign;
+ si5r aExp;
+ ui6b aSig0, aSig1;
+
+ aSig1 = extractFloat128Frac1( a );
+ aSig0 = extractFloat128Frac0( a );
+ aExp = extractFloat128Exp( a );
+ aSign = extractFloat128Sign( a );
+ if ( aExp == 0x7FFF ) {
+ if ( aSig0 | aSig1 ) {
+ return commonNaNToFloatx80( float128ToCommonNaN( a ) );
+ }
+ return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( aExp == 0 ) {
+ if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 );
+ normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
+ }
+ else {
+ aSig0 |= LIT64( 0x0001000000000000 );
+ }
+ shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 );
+ return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of adding the absolute values of the quadruple-precision
+| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
+| before being returned. `zSign' is ignored if the result is a NaN.
+| The addition is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float128 addFloat128Sigs( float128 a, float128 b, flag zSign )
+{
+ si5r aExp, bExp, zExp;
+ ui6b aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
+ si5r expDiff;
+
+ aSig1 = extractFloat128Frac1( a );
+ aSig0 = extractFloat128Frac0( a );
+ aExp = extractFloat128Exp( a );
+ bSig1 = extractFloat128Frac1( b );
+ bSig0 = extractFloat128Frac0( b );
+ bExp = extractFloat128Exp( b );
+ expDiff = aExp - bExp;
+ if ( 0 < expDiff ) {
+ if ( aExp == 0x7FFF ) {
+ if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) {
+ --expDiff;
+ }
+ else {
+ bSig0 |= LIT64( 0x0001000000000000 );
+ }
+ shift128ExtraRightJamming(
+ bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 );
+ zExp = aExp;
+ }
+ else if ( expDiff < 0 ) {
+ if ( bExp == 0x7FFF ) {
+ if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
+ return packFloat128( zSign, 0x7FFF, 0, 0 );
+ }
+ if ( aExp == 0 ) {
+ ++expDiff;
+ }
+ else {
+ aSig0 |= LIT64( 0x0001000000000000 );
+ }
+ shift128ExtraRightJamming(
+ aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 );
+ zExp = bExp;
+ }
+ else {
+ if ( aExp == 0x7FFF ) {
+ if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
+ return propagateFloat128NaN( a, b );
+ }
+ return a;
+ }
+ add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
+ if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 );
+ zSig2 = 0;
+ zSig0 |= LIT64( 0x0002000000000000 );
+ zExp = aExp;
+ goto shiftRight1;
+ }
+ aSig0 |= LIT64( 0x0001000000000000 );
+ add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
+ --zExp;
+ if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack;
+ ++zExp;
+ shiftRight1:
+ shift128ExtraRightJamming(
+ zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
+ roundAndPack:
+ return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of subtracting the absolute values of the quadruple-
+| precision floating-point values `a' and `b'. If `zSign' is 1, the
+| difference is negated before being returned. `zSign' is ignored if the
+| result is a NaN. The subtraction is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float128 subFloat128Sigs( float128 a, float128 b, flag zSign )
+{
+ si5r aExp, bExp, zExp;
+ ui6b aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
+ si5r expDiff;
+ float128 z;
+
+ aSig1 = extractFloat128Frac1( a );
+ aSig0 = extractFloat128Frac0( a );
+ aExp = extractFloat128Exp( a );
+ bSig1 = extractFloat128Frac1( b );
+ bSig0 = extractFloat128Frac0( b );
+ bExp = extractFloat128Exp( b );
+ expDiff = aExp - bExp;
+ shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
+ shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 );
+ if ( 0 < expDiff ) goto aExpBigger;
+ if ( expDiff < 0 ) goto bExpBigger;
+ if ( aExp == 0x7FFF ) {
+ if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
+ return propagateFloat128NaN( a, b );
+ }
+ float_raise( float_flag_invalid );
+ z.low = float128_default_nan_low;
+ z.high = float128_default_nan_high;
+ return z;
+ }
+ if ( aExp == 0 ) {
+ aExp = 1;
+ bExp = 1;
+ }
+ if ( bSig0 < aSig0 ) goto aBigger;
+ if ( aSig0 < bSig0 ) goto bBigger;
+ if ( bSig1 < aSig1 ) goto aBigger;
+ if ( aSig1 < bSig1 ) goto bBigger;
+ return packFloat128( float_rounding_mode == float_round_down, 0, 0, 0 );
+ bExpBigger:
+ if ( bExp == 0x7FFF ) {
+ if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
+ return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 );
+ }
+ if ( aExp == 0 ) {
+ ++expDiff;
+ }
+ else {
+ aSig0 |= LIT64( 0x4000000000000000 );
+ }
+ shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
+ bSig0 |= LIT64( 0x4000000000000000 );
+ bBigger:
+ sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 );
+ zExp = bExp;
+ zSign ^= 1;
+ goto normalizeRoundAndPack;
+ aExpBigger:
+ if ( aExp == 0x7FFF ) {
+ if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) {
+ --expDiff;
+ }
+ else {
+ bSig0 |= LIT64( 0x4000000000000000 );
+ }
+ shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 );
+ aSig0 |= LIT64( 0x4000000000000000 );
+ aBigger:
+ sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
+ zExp = aExp;
+ normalizeRoundAndPack:
+ --zExp;
+ return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of adding the quadruple-precision floating-point values
+| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
+| for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float128 float128_add( float128 a, float128 b )
+{
+ flag aSign, bSign;
+
+ aSign = extractFloat128Sign( a );
+ bSign = extractFloat128Sign( b );
+ if ( aSign == bSign ) {
+ return addFloat128Sigs( a, b, aSign );
+ }
+ else {
+ return subFloat128Sigs( a, b, aSign );
+ }
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of subtracting the quadruple-precision floating-point
+| values `a' and `b'. The operation is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float128 float128_sub( float128 a, float128 b )
+{
+ flag aSign, bSign;
+
+ aSign = extractFloat128Sign( a );
+ bSign = extractFloat128Sign( b );
+ if ( aSign == bSign ) {
+ return subFloat128Sigs( a, b, aSign );
+ }
+ else {
+ return addFloat128Sigs( a, b, aSign );
+ }
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of multiplying the quadruple-precision floating-point
+| values `a' and `b'. The operation is performed according to the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float128 float128_mul( float128 a, float128 b )
+{
+ flag aSign, bSign, zSign;
+ si5r aExp, bExp, zExp;
+ ui6b aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
+ float128 z;
+
+ aSig1 = extractFloat128Frac1( a );
+ aSig0 = extractFloat128Frac0( a );
+ aExp = extractFloat128Exp( a );
+ aSign = extractFloat128Sign( a );
+ bSig1 = extractFloat128Frac1( b );
+ bSig0 = extractFloat128Frac0( b );
+ bExp = extractFloat128Exp( b );
+ bSign = extractFloat128Sign( b );
+ zSign = aSign ^ bSign;
+ if ( aExp == 0x7FFF ) {
+ if ( ( aSig0 | aSig1 )
+ || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
+ return propagateFloat128NaN( a, b );
+ }
+ if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid;
+ return packFloat128( zSign, 0x7FFF, 0, 0 );
+ }
+ if ( bExp == 0x7FFF ) {
+ if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
+ if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
+ invalid:
+ float_raise( float_flag_invalid );
+ z.low = float128_default_nan_low;
+ z.high = float128_default_nan_high;
+ return z;
+ }
+ return packFloat128( zSign, 0x7FFF, 0, 0 );
+ }
+ if ( aExp == 0 ) {
+ if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
+ normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
+ }
+ if ( bExp == 0 ) {
+ if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
+ normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
+ }
+ zExp = aExp + bExp - 0x4000;
+ aSig0 |= LIT64( 0x0001000000000000 );
+ shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 );
+ mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 );
+ add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 );
+ zSig2 |= ( zSig3 != 0 );
+ if ( LIT64( 0x0002000000000000 ) <= zSig0 ) {
+ shift128ExtraRightJamming(
+ zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
+ ++zExp;
+ }
+ return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of dividing the quadruple-precision floating-point value
+| `a' by the corresponding value `b'. The operation is performed according to
+| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float128 float128_div( float128 a, float128 b )
+{
+ flag aSign, bSign, zSign;
+ si5r aExp, bExp, zExp;
+ ui6b aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
+ ui6b rem0, rem1, rem2, rem3, term0, term1, term2, term3;
+ float128 z;
+
+ aSig1 = extractFloat128Frac1( a );
+ aSig0 = extractFloat128Frac0( a );
+ aExp = extractFloat128Exp( a );
+ aSign = extractFloat128Sign( a );
+ bSig1 = extractFloat128Frac1( b );
+ bSig0 = extractFloat128Frac0( b );
+ bExp = extractFloat128Exp( b );
+ bSign = extractFloat128Sign( b );
+ zSign = aSign ^ bSign;
+ if ( aExp == 0x7FFF ) {
+ if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b );
+ if ( bExp == 0x7FFF ) {
+ if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
+ goto invalid;
+ }
+ return packFloat128( zSign, 0x7FFF, 0, 0 );
+ }
+ if ( bExp == 0x7FFF ) {
+ if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
+ return packFloat128( zSign, 0, 0, 0 );
+ }
+ if ( bExp == 0 ) {
+ if ( ( bSig0 | bSig1 ) == 0 ) {
+ if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
+ invalid:
+ float_raise( float_flag_invalid );
+ z.low = float128_default_nan_low;
+ z.high = float128_default_nan_high;
+ return z;
+ }
+ float_raise( float_flag_divbyzero );
+ return packFloat128( zSign, 0x7FFF, 0, 0 );
+ }
+ normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
+ }
+ if ( aExp == 0 ) {
+ if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
+ normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
+ }
+ zExp = aExp - bExp + 0x3FFD;
+ shortShift128Left(
+ aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 );
+ shortShift128Left(
+ bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
+ if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) {
+ shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 );
+ ++zExp;
+ }
+ zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 );
+ mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 );
+ sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 );
+ while ( (si6b) rem0 < 0 ) {
+ --zSig0;
+ add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
+ }
+ zSig1 = estimateDiv128To64( rem1, rem2, bSig0 );
+ if ( ( zSig1 & 0x3FFF ) <= 4 ) {
+ mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 );
+ sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 );
+ while ( (si6b) rem1 < 0 ) {
+ --zSig1;
+ add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 );
+ }
+ zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
+ }
+ shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 );
+ return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
+
+}
+
+#endif
+
+typedef unsigned int float32;
+
+/*----------------------------------------------------------------------------
+| Normalizes the subnormal single-precision floating-point value represented
+| by the denormalized significand `aSig'. The normalized exponent and
+| significand are stored at the locations pointed to by `zExpPtr' and
+| `zSigPtr', respectively.
+*----------------------------------------------------------------------------*/
+
+LOCALPROC
+ normalizeFloat32Subnormal( ui5b aSig, si4r *zExpPtr, ui5b *zSigPtr )
+{
+ si3r shiftCount;
+
+ shiftCount = countLeadingZeros32( aSig ) - 8;
+ *zSigPtr = aSig<<shiftCount;
+ *zExpPtr = 1 - shiftCount;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the fraction bits of the single-precision floating-point value `a'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC ui5b extractFloat32Frac( float32 a )
+{
+
+ return a & 0x007FFFFF;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the exponent bits of the single-precision floating-point value `a'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC si4r extractFloat32Exp( float32 a )
+{
+
+ return ( a>>23 ) & 0xFF;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the sign bit of the single-precision floating-point value `a'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC flag extractFloat32Sign( float32 a )
+{
+
+ return a>>31;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the single-precision floating-point value `a' is a signaling
+| NaN; otherwise returns 0.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC flag float32_is_signaling_nan( float32 a )
+{
+
+ return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the single-precision floating-point NaN
+| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
+| exception is raised.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC commonNaNT float32ToCommonNaN( float32 a )
+{
+ commonNaNT z;
+
+ if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
+ z.sign = a>>31;
+ z.low = 0;
+ z.high = ( (ui6b) a )<<41;
+ return z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the single-precision floating-point value
+| `a' to the extended double-precision floating-point format. The conversion
+| is performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 float32_to_floatx80( float32 a )
+{
+ flag aSign;
+ si4r aExp;
+ ui5b aSig;
+
+ aSig = extractFloat32Frac( a );
+ aExp = extractFloat32Exp( a );
+ aSign = extractFloat32Sign( a );
+ if ( aExp == 0xFF ) {
+ if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) );
+ return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
+ normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+ }
+ aSig |= 0x00800000;
+ return packFloatx80( aSign, aExp + 0x3F80, ( (ui6b) aSig )<<40 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
+| single-precision floating-point value, returning the result. After being
+| shifted into the proper positions, the three fields are simply added
+| together to form the result. This means that any integer portion of `zSig'
+| will be added into the exponent. Since a properly normalized significand
+| will have an integer portion equal to 1, the `zExp' input should be 1 less
+| than the desired result exponent whenever `zSig' is a complete, normalized
+| significand.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC float32 packFloat32( flag zSign, si4r zExp, ui5b zSig )
+{
+
+ return ( ( (ui5b) zSign )<<31 ) + ( ( (ui5b) zExp )<<23 ) + zSig;
+
+}
+
+/*----------------------------------------------------------------------------
+| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+| and significand `zSig', and returns the proper single-precision floating-
+| point value corresponding to the abstract input. Ordinarily, the abstract
+| value is simply rounded and packed into the single-precision format, with
+| the inexact exception raised if the abstract input cannot be represented
+| exactly. However, if the abstract value is too large, the overflow and
+| inexact exceptions are raised and an infinity or maximal finite value is
+| returned. If the abstract value is too small, the input value is rounded to
+| a subnormal number, and the underflow and inexact exceptions are raised if
+| the abstract input cannot be represented exactly as a subnormal single-
+| precision floating-point number.
+| The input significand `zSig' has its binary point between bits 30
+| and 29, which is 7 bits to the left of the usual location. This shifted
+| significand must be normalized or smaller. If `zSig' is not normalized,
+| `zExp' must be 0; in that case, the result returned is a subnormal number,
+| and it must not require rounding. In the usual case that `zSig' is
+| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
+| The handling of underflow and overflow follows the IEC/IEEE Standard for
+| Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float32 roundAndPackFloat32( flag zSign, si4r zExp, ui5b zSig )
+{
+ si3r roundingMode;
+ flag roundNearestEven;
+ si3r roundIncrement, roundBits;
+ flag isTiny;
+
+ roundingMode = float_rounding_mode;
+ roundNearestEven = ( roundingMode == float_round_nearest_even );
+ roundIncrement = 0x40;
+ if ( ! roundNearestEven ) {
+ if ( roundingMode == float_round_to_zero ) {
+ roundIncrement = 0;
+ }
+ else {
+ roundIncrement = 0x7F;
+ if ( zSign ) {
+ if ( roundingMode == float_round_up ) roundIncrement = 0;
+ }
+ else {
+ if ( roundingMode == float_round_down ) roundIncrement = 0;
+ }
+ }
+ }
+ roundBits = zSig & 0x7F;
+ if ( 0xFD <= (ui4b) zExp ) {
+ if ( ( 0xFD < zExp )
+ || ( ( zExp == 0xFD )
+ && ( (si5b) ( zSig + roundIncrement ) < 0 ) )
+ ) {
+ float_raise( float_flag_overflow | float_flag_inexact );
+ return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
+ }
+ if ( zExp < 0 ) {
+ isTiny =
+ ( float_detect_tininess == float_tininess_before_rounding )
+ || ( zExp < -1 )
+ || ( zSig + roundIncrement < 0x80000000 );
+ shift32RightJamming( zSig, - zExp, &zSig );
+ zExp = 0;
+ roundBits = zSig & 0x7F;
+ if ( isTiny && roundBits ) float_raise( float_flag_underflow );
+ }
+ }
+ if ( roundBits ) float_exception_flags |= float_flag_inexact;
+ zSig = ( zSig + roundIncrement )>>7;
+ zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
+ if ( zSig == 0 ) zExp = 0;
+ return packFloat32( zSign, zExp, zSig );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the canonical NaN `a' to the single-
+| precision floating-point format.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float32 commonNaNToFloat32( commonNaNT a )
+{
+
+ return ( ( (ui5b) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the extended double-precision floating-
+| point value `a' to the single-precision floating-point format. The
+| conversion is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float32 floatx80_to_float32( floatx80 a )
+{
+ flag aSign;
+ si5r aExp;
+ ui6b aSig;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ if ( aExp == 0x7FFF ) {
+ if ( (ui6b) ( aSig<<1 ) ) {
+ return commonNaNToFloat32( floatx80ToCommonNaN( a ) );
+ }
+ return packFloat32( aSign, 0xFF, 0 );
+ }
+ shift64RightJamming( aSig, 33, &aSig );
+ if ( aExp || aSig ) aExp -= 0x3F81;
+ return roundAndPackFloat32( aSign, aExp, aSig );
+
+}
+
+
+typedef ui6b float64;
+
+/*----------------------------------------------------------------------------
+| Returns the fraction bits of the double-precision floating-point value `a'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC ui6b extractFloat64Frac( float64 a )
+{
+
+ return a & LIT64( 0x000FFFFFFFFFFFFF );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the exponent bits of the double-precision floating-point value `a'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC si4r extractFloat64Exp( float64 a )
+{
+
+ return ( a>>52 ) & 0x7FF;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the sign bit of the double-precision floating-point value `a'.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC flag extractFloat64Sign( float64 a )
+{
+
+ return a>>63;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the double-precision floating-point value `a' is a signaling
+| NaN; otherwise returns 0.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC flag float64_is_signaling_nan( float64 a )
+{
+
+ return
+ ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
+ && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the double-precision floating-point NaN
+| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
+| exception is raised.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC commonNaNT float64ToCommonNaN( float64 a )
+{
+ commonNaNT z;
+
+ if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
+ z.sign = a>>63;
+ z.low = 0;
+ z.high = a<<12;
+ return z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Normalizes the subnormal double-precision floating-point value represented
+| by the denormalized significand `aSig'. The normalized exponent and
+| significand are stored at the locations pointed to by `zExpPtr' and
+| `zSigPtr', respectively.
+*----------------------------------------------------------------------------*/
+
+LOCALPROC
+ normalizeFloat64Subnormal( ui6b aSig, si4r *zExpPtr, ui6b *zSigPtr )
+{
+ si3r shiftCount;
+
+ shiftCount = countLeadingZeros64( aSig ) - 11;
+ *zSigPtr = aSig<<shiftCount;
+ *zExpPtr = 1 - shiftCount;
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the double-precision floating-point value
+| `a' to the extended double-precision floating-point format. The conversion
+| is performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 float64_to_floatx80( float64 a )
+{
+ flag aSign;
+ si4r aExp;
+ ui6b aSig;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ aSign = extractFloat64Sign( a );
+ if ( aExp == 0x7FF ) {
+ if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) );
+ return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
+ normalizeFloat64Subnormal( aSig, &aExp, &aSig );
+ }
+ return
+ packFloatx80(
+ aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
+| double-precision floating-point value, returning the result. After being
+| shifted into the proper positions, the three fields are simply added
+| together to form the result. This means that any integer portion of `zSig'
+| will be added into the exponent. Since a properly normalized significand
+| will have an integer portion equal to 1, the `zExp' input should be 1 less
+| than the desired result exponent whenever `zSig' is a complete, normalized
+| significand.
+*----------------------------------------------------------------------------*/
+
+LOCALINLINEFUNC float64 packFloat64( flag zSign, si4r zExp, ui6b zSig )
+{
+
+ return ( ( (ui6b) zSign )<<63 ) + ( ( (ui6b) zExp )<<52 ) + zSig;
+
+}
+
+/*----------------------------------------------------------------------------
+| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+| and significand `zSig', and returns the proper double-precision floating-
+| point value corresponding to the abstract input. Ordinarily, the abstract
+| value is simply rounded and packed into the double-precision format, with
+| the inexact exception raised if the abstract input cannot be represented
+| exactly. However, if the abstract value is too large, the overflow and
+| inexact exceptions are raised and an infinity or maximal finite value is
+| returned. If the abstract value is too small, the input value is rounded
+| to a subnormal number, and the underflow and inexact exceptions are raised
+| if the abstract input cannot be represented exactly as a subnormal double-
+| precision floating-point number.
+| The input significand `zSig' has its binary point between bits 62
+| and 61, which is 10 bits to the left of the usual location. This shifted
+| significand must be normalized or smaller. If `zSig' is not normalized,
+| `zExp' must be 0; in that case, the result returned is a subnormal number,
+| and it must not require rounding. In the usual case that `zSig' is
+| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
+| The handling of underflow and overflow follows the IEC/IEEE Standard for
+| Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float64 roundAndPackFloat64( flag zSign, si4r zExp, ui6b zSig )
+{
+ si3r roundingMode;
+ flag roundNearestEven;
+ si4r roundIncrement, roundBits;
+ flag isTiny;
+
+ roundingMode = float_rounding_mode;
+ roundNearestEven = ( roundingMode == float_round_nearest_even );
+ roundIncrement = 0x200;
+ if ( ! roundNearestEven ) {
+ if ( roundingMode == float_round_to_zero ) {
+ roundIncrement = 0;
+ }
+ else {
+ roundIncrement = 0x3FF;
+ if ( zSign ) {
+ if ( roundingMode == float_round_up ) roundIncrement = 0;
+ }
+ else {
+ if ( roundingMode == float_round_down ) roundIncrement = 0;
+ }
+ }
+ }
+ roundBits = zSig & 0x3FF;
+ if ( 0x7FD <= (ui4b) zExp ) {
+ if ( ( 0x7FD < zExp )
+ || ( ( zExp == 0x7FD )
+ && ( (si6b) ( zSig + roundIncrement ) < 0 ) )
+ ) {
+ float_raise( float_flag_overflow | float_flag_inexact );
+ return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 );
+ }
+ if ( zExp < 0 ) {
+ isTiny =
+ ( float_detect_tininess == float_tininess_before_rounding )
+ || ( zExp < -1 )
+ || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
+ shift64RightJamming( zSig, - zExp, &zSig );
+ zExp = 0;
+ roundBits = zSig & 0x3FF;
+ if ( isTiny && roundBits ) float_raise( float_flag_underflow );
+ }
+ }
+ if ( roundBits ) float_exception_flags |= float_flag_inexact;
+ zSig = ( zSig + roundIncrement )>>10;
+ zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
+ if ( zSig == 0 ) zExp = 0;
+ return packFloat64( zSign, zExp, zSig );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the canonical NaN `a' to the double-
+| precision floating-point format.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float64 commonNaNToFloat64( commonNaNT a )
+{
+
+ return
+ ( ( (ui6b) a.sign )<<63 )
+ | LIT64( 0x7FF8000000000000 )
+ | ( a.high>>12 );
+
+}
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the extended double-precision floating-
+| point value `a' to the double-precision floating-point format. The
+| conversion is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC float64 floatx80_to_float64( floatx80 a )
+{
+ flag aSign;
+ si5r aExp;
+ ui6b aSig, zSig;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ if ( aExp == 0x7FFF ) {
+ if ( (ui6b) ( aSig<<1 ) ) {
+ return commonNaNToFloat64( floatx80ToCommonNaN( a ) );
+ }
+ return packFloat64( aSign, 0x7FF, 0 );
+ }
+ shift64RightJamming( aSig, 1, &zSig );
+ if ( aExp || aSig ) aExp -= 0x3C01;
+ return roundAndPackFloat64( aSign, aExp, zSig );
+
+}
+
+/* ----- end from original file "softfloat.c" ----- */
+
+typedef si4r Bit16s;
+typedef si5r Bit32s;
+typedef si6r Bit64s;
+
+typedef ui5r Bit32u;
+typedef ui6r Bit64u;
+
+#define int16_indefinite 0x8000
+
+/*----------------------------------------------------------------------------
+| Takes extended double-precision floating-point NaN `a' and returns the
+| appropriate NaN result. If `a' is a signaling NaN, the invalid exception
+| is raised.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 propagateOneFloatx80NaN(floatx80 *a)
+{
+ if (floatx80_is_signaling_nan(*a))
+ float_raise(float_flag_invalid);
+
+ a->low |= LIT64(0xC000000000000000);
+
+ return *a;
+}
+
+#define float_flag_denormal 0x02
+
+#define floatx80_default_nan_exp 0xFFFF
+#define floatx80_default_nan_fraction LIT64(0xC000000000000000)
+
+#define packFloatx80m(zSign, zExp, zSig) {(zSig), ((zSign) << 15) + (zExp) }
+
+/*----------------------------------------------------------------------------
+| Packs two 64-bit precision integers into into the quadruple-precision
+| floating-point value, returning the result.
+*----------------------------------------------------------------------------*/
+
+#define packFloat2x128m(zHi, zLo) {(zLo), (zHi)}
+#define PACK_FLOAT_128(hi,lo) packFloat2x128m(LIT64(hi),LIT64(lo))
+
+static const floatx80 floatx80_default_nan =
+ packFloatx80m(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point ordering relations
+*----------------------------------------------------------------------------*/
+enum {
+ float_relation_less = -1,
+ float_relation_equal = 0,
+ float_relation_greater = 1,
+ float_relation_unordered = 2
+};
+
+#define EXP_BIAS 0x3FFF
+
+
+/*----------------------------------------------------------------------------
+| Returns the result of multiplying the extended double-precision floating-
+| point value `a' and quadruple-precision floating point value `b'. The
+| operation is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 floatx80_mul128(floatx80 a, float128 b)
+{
+ Bit32s aExp, bExp, zExp;
+ Bit64u aSig, bSig0, bSig1, zSig0, zSig1, zSig2;
+ int aSign, bSign, zSign;
+
+ // handle unsupported extended double-precision floating encodings
+ if (0 /* floatx80_is_unsupported(a) */)
+ {
+ invalid:
+ float_raise(float_flag_invalid);
+ return floatx80_default_nan;
+ }
+
+ aSig = extractFloatx80Frac(a);
+ aExp = extractFloatx80Exp(a);
+ aSign = extractFloatx80Sign(a);
+ bSig0 = extractFloat128Frac0(b);
+ bSig1 = extractFloat128Frac1(b);
+ bExp = extractFloat128Exp(b);
+ bSign = extractFloat128Sign(b);
+
+ zSign = aSign ^ bSign;
+
+ if (aExp == 0x7FFF) {
+ if ((Bit64u) (aSig<<1)
+ || ((bExp == 0x7FFF) && (bSig0 | bSig1)))
+ {
+ floatx80 r = commonNaNToFloatx80(float128ToCommonNaN(b));
+ return propagateFloatx80NaN(a, r);
+ }
+ if (bExp == 0) {
+ if ((bSig0 | bSig1) == 0) goto invalid;
+ float_raise(float_flag_denormal);
+ }
+ return packFloatx80(zSign, 0x7FFF, LIT64(0x8000000000000000));
+ }
+ if (bExp == 0x7FFF) {
+ if (bSig0 | bSig1) {
+ floatx80 r = commonNaNToFloatx80(float128ToCommonNaN(b));
+ return propagateFloatx80NaN(a, r);
+ }
+ if (aExp == 0) {
+ if (aSig == 0) goto invalid;
+ float_raise(float_flag_denormal);
+ }
+ return packFloatx80(zSign, 0x7FFF, LIT64(0x8000000000000000));
+ }
+ if (aExp == 0) {
+ if (aSig == 0) {
+ if ((bExp == 0) && (bSig0 | bSig1)) float_raise(float_flag_denormal);
+ return packFloatx80(zSign, 0, 0);
+ }
+ float_raise(float_flag_denormal);
+ normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ }
+ if (bExp == 0) {
+ if ((bSig0 | bSig1) == 0) return packFloatx80(zSign, 0, 0);
+ float_raise(float_flag_denormal);
+ normalizeFloat128Subnormal(bSig0, bSig1, &bExp, &bSig0, &bSig1);
+ }
+ else bSig0 |= LIT64(0x0001000000000000);
+
+ zExp = aExp + bExp - 0x3FFE;
+ shortShift128Left(bSig0, bSig1, 15, &bSig0, &bSig1);
+ mul128By64To192(bSig0, bSig1, aSig, &zSig0, &zSig1, &zSig2);
+ if (0 < (Bit64s) zSig0) {
+ shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
+ --zExp;
+ }
+ return
+ roundAndPackFloatx80(floatx80_rounding_precision,
+ zSign, zExp, zSig0, zSig1);
+}
+
+/* ----- from original file "softfloatx80.h" ----- */
+
+/*
+ ["original Stanislav Shwartsman Copyright notice" went here, included near top of this file.]
+*/
+
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point class.
+*----------------------------------------------------------------------------*/
+typedef enum {
+ float_zero,
+ float_NaN,
+ float_negative_inf,
+ float_positive_inf,
+ float_denormal,
+ float_normalized
+} float_class_t;
+
+
+/*-----------------------------------------------------------------------------
+| Calculates the absolute value of the extended double-precision floating-point
+| value `a'. The operation is performed according to the IEC/IEEE Standard
+| for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+#if 0
+inline floatx80 floatx80_abs(floatx80 *reg)
+{
+ reg->high &= 0x7FFF;
+ return *reg;
+}
+#endif
+
+/*-----------------------------------------------------------------------------
+| Changes the sign of the extended double-precision floating-point value 'a'.
+| The operation is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 floatx80_chs(floatx80 *x)
+{
+ x->high ^= 0x8000;
+ return *x;
+}
+
+/* ----- end from original file "softfloatx80.h" ----- */
+
+/* ----- from original file "softfloatx80.cc" ----- */
+
+/*
+ ["original Stanislav Shwartsman Copyright notice" went here, included near top of this file.]
+*/
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the extended double-precision floating-
+| point value `a' to the 16-bit two's complement integer format. The
+| conversion is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic - which means in particular that the conversion
+| is rounded according to the current rounding mode. If `a' is a NaN or the
+| conversion overflows, the integer indefinite value is returned.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALFUNC Bit16s floatx80_to_int16(floatx80 a)
+{
+#if 0
+ if (floatx80_is_unsupported(a))
+ {
+ float_raise(float_flag_invalid);
+ return int16_indefinite;
+ }
+#endif
+
+ Bit32s v32 = floatx80_to_int32(a);
+
+ if ((v32 > 32767) || (v32 < -32768)) {
+ float_exception_flags = float_flag_invalid; // throw way other flags
+ return int16_indefinite;
+ }
+
+ return (Bit16s) v32;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+| Returns the result of converting the extended double-precision floating-
+| point value `a' to the 16-bit two's complement integer format. The
+| conversion is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic, except that the conversion is always rounded
+| toward zero. If `a' is a NaN or the conversion overflows, the integer
+| indefinite value is returned.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALFUNC Bit16s floatx80_to_int16_round_to_zero(floatx80 a)
+{
+#if 0
+ if (floatx80_is_unsupported(a))
+ {
+ float_raise(float_flag_invalid);
+ return int16_indefinite;
+ }
+#endif
+
+ Bit32s v32 = floatx80_to_int32_round_to_zero(a);
+
+ if ((v32 > 32767) || (v32 < -32768)) {
+ float_exception_flags = float_flag_invalid; // throw way other flags
+ return int16_indefinite;
+ }
+
+ return (Bit16s) v32;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+| Separate the source extended double-precision floating point value `a'
+| into its exponent and significand, store the significant back to the
+| 'a' and return the exponent. The operation performed is a superset of
+| the IEC/IEEE recommended logb(x) function.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 floatx80_extract(floatx80 *a)
+{
+ Bit64u aSig = extractFloatx80Frac(*a);
+ Bit32s aExp = extractFloatx80Exp(*a);
+ int aSign = extractFloatx80Sign(*a);
+
+#if 0
+ if (floatx80_is_unsupported(*a))
+ {
+ float_raise(float_flag_invalid);
+ *a = floatx80_default_nan;
+ return *a;
+ }
+#endif
+
+ if (aExp == 0x7FFF) {
+ if ((Bit64u) (aSig<<1))
+ {
+ *a = propagateOneFloatx80NaN(a);
+ return *a;
+ }
+ return packFloatx80(0, 0x7FFF, LIT64(0x8000000000000000));
+ }
+ if (aExp == 0)
+ {
+ if (aSig == 0) {
+ float_raise(float_flag_divbyzero);
+ *a = packFloatx80(aSign, 0, 0);
+ return packFloatx80(1, 0x7FFF, LIT64(0x8000000000000000));
+ }
+ float_raise(float_flag_denormal);
+ normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ }
+
+ a->high = (aSign << 15) + 0x3FFF;
+ a->low = aSig;
+ return int32_to_floatx80(aExp - 0x3FFF);
+}
+
+/*----------------------------------------------------------------------------
+| Scales extended double-precision floating-point value in operand `a' by
+| value `b'. The function truncates the value in the second operand 'b' to
+| an integral value and adds that value to the exponent of the operand 'a'.
+| The operation performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 floatx80_scale(floatx80 a, floatx80 b)
+{
+ int shiftCount;
+ Bit32s scale;
+
+ // handle unsupported extended double-precision floating encodings
+#if 0
+ if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
+ {
+ float_raise(float_flag_invalid);
+ return floatx80_default_nan;
+ }
+#endif
+
+ Bit64u aSig = extractFloatx80Frac(a);
+ Bit32s aExp = extractFloatx80Exp(a);
+ int aSign = extractFloatx80Sign(a);
+ Bit64u bSig = extractFloatx80Frac(b);
+ Bit32s bExp = extractFloatx80Exp(b);
+ int bSign = extractFloatx80Sign(b);
+
+ if (aExp == 0x7FFF) {
+ if ((Bit64u) (aSig<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
+ {
+ return propagateFloatx80NaN(a, b);
+ }
+ if ((bExp == 0x7FFF) && bSign) {
+ float_raise(float_flag_invalid);
+ return floatx80_default_nan;
+ }
+ if (bSig && (bExp == 0)) float_raise(float_flag_denormal);
+ return a;
+ }
+ if (bExp == 0x7FFF) {
+ if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b);
+ if ((aExp | aSig) == 0) {
+ if (! bSign) {
+ float_raise(float_flag_invalid);
+ return floatx80_default_nan;
+ }
+ return a;
+ }
+ if (aSig && (aExp == 0)) float_raise(float_flag_denormal);
+ if (bSign) return packFloatx80(aSign, 0, 0);
+ return packFloatx80(aSign, 0x7FFF, LIT64(0x8000000000000000));
+ }
+ if (aExp == 0) {
+ if (bSig && (bExp == 0)) float_raise(float_flag_denormal);
+ if (aSig == 0) return a;
+ float_raise(float_flag_denormal);
+ normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ if (bExp < 0x3FFF)
+ return normalizeRoundAndPackFloatx80(80, aSign, aExp, aSig, 0);
+ }
+ if (bExp == 0) {
+ if (bSig == 0) return a;
+ float_raise(float_flag_denormal);
+ normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+ }
+
+ if (bExp > 0x400E) {
+ /* generate appropriate overflow/underflow */
+ return roundAndPackFloatx80(80, aSign,
+ bSign ? -0x3FFF : 0x7FFF, aSig, 0);
+ }
+
+ if (bExp < 0x3FFF) return a;
+
+ shiftCount = 0x403E - bExp;
+ bSig >>= shiftCount;
+ scale = (Bit32s) bSig;
+ if (bSign) scale = -scale; /* -32768..32767 */
+ return
+ roundAndPackFloatx80(80, aSign, aExp+scale, aSig, 0);
+}
+
+/*----------------------------------------------------------------------------
+| Determine extended-precision floating-point number class.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALFUNC float_class_t floatx80_class(floatx80 a)
+{
+ Bit32s aExp = extractFloatx80Exp(a);
+ Bit64u aSig = extractFloatx80Frac(a);
+
+ if(aExp == 0) {
+ if (aSig == 0)
+ return float_zero;
+
+ /* denormal or pseudo-denormal */
+ return float_denormal;
+ }
+
+ /* valid numbers have the MS bit set */
+ if (!(aSig & LIT64(0x8000000000000000)))
+ return float_NaN; /* report unsupported as NaNs */
+
+ if(aExp == 0x7fff) {
+ int aSign = extractFloatx80Sign(a);
+
+ if (((Bit64u) (aSig<< 1)) == 0)
+ return (aSign) ? float_negative_inf : float_positive_inf;
+
+ return float_NaN;
+ }
+
+ return float_normalized;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+| Compare between two extended precision floating point numbers. Returns
+| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
+| the value 'a' is less than the corresponding value `b',
+| 'float_relation_greater' if the value 'a' is greater than the corresponding
+| value `b', or 'float_relation_unordered' otherwise.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALFUNC int floatx80_compare(floatx80 a, floatx80 b)
+{
+ int aSign;
+ int bSign;
+ Bit64u aSig;
+ Bit32s aExp;
+ Bit64u bSig;
+ Bit32s bExp;
+ int less_than;
+ float_class_t aClass = floatx80_class(a);
+ float_class_t bClass = floatx80_class(b);
+
+ if (aClass == float_NaN || bClass == float_NaN)
+ {
+ float_raise(float_flag_invalid);
+ return float_relation_unordered;
+ }
+
+ if (aClass == float_denormal || bClass == float_denormal)
+ {
+ float_raise(float_flag_denormal);
+ }
+
+ aSign = extractFloatx80Sign(a);
+ bSign = extractFloatx80Sign(b);
+
+ if (aClass == float_zero) {
+ if (bClass == float_zero) return float_relation_equal;
+ return bSign ? float_relation_greater : float_relation_less;
+ }
+
+ if (bClass == float_zero || aSign != bSign) {
+ return aSign ? float_relation_less : float_relation_greater;
+ }
+
+ aSig = extractFloatx80Frac(a);
+ aExp = extractFloatx80Exp(a);
+ bSig = extractFloatx80Frac(b);
+ bExp = extractFloatx80Exp(b);
+
+ if (aClass == float_denormal)
+ normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+
+ if (bClass == float_denormal)
+ normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+
+ if (aExp == bExp && aSig == bSig)
+ return float_relation_equal;
+
+ less_than =
+ aSign ? ((bExp < aExp) || ((bExp == aExp) && (bSig < aSig)))
+ : ((aExp < bExp) || ((aExp == bExp) && (aSig < bSig)));
+
+ if (less_than) return float_relation_less;
+
+ return float_relation_greater;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+| Compare between two extended precision floating point numbers. Returns
+| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
+| the value 'a' is less than the corresponding value `b',
+| 'float_relation_greater' if the value 'a' is greater than the corresponding
+| value `b', or 'float_relation_unordered' otherwise. Quiet NaNs do not cause
+| an exception.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALFUNC int floatx80_compare_quiet(floatx80 a, floatx80 b)
+{
+ int aSign;
+ int bSign;
+ Bit64u aSig;
+ Bit32s aExp;
+ Bit64u bSig;
+ Bit32s bExp;
+ int less_than;
+ float_class_t aClass = floatx80_class(a);
+ float_class_t bClass = floatx80_class(b);
+
+ if (aClass == float_NaN || bClass == float_NaN)
+ {
+#if 0
+ if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
+ float_raise(float_flag_invalid);
+#endif
+
+ if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
+ float_raise(float_flag_invalid);
+
+ return float_relation_unordered;
+ }
+
+ if (aClass == float_denormal || bClass == float_denormal)
+ {
+ float_raise(float_flag_denormal);
+ }
+
+ aSign = extractFloatx80Sign(a);
+ bSign = extractFloatx80Sign(b);
+
+ if (aClass == float_zero) {
+ if (bClass == float_zero) return float_relation_equal;
+ return bSign ? float_relation_greater : float_relation_less;
+ }
+
+ if (bClass == float_zero || aSign != bSign) {
+ return aSign ? float_relation_less : float_relation_greater;
+ }
+
+ aSig = extractFloatx80Frac(a);
+ aExp = extractFloatx80Exp(a);
+ bSig = extractFloatx80Frac(b);
+ bExp = extractFloatx80Exp(b);
+
+ if (aClass == float_denormal)
+ normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+
+ if (bClass == float_denormal)
+ normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+
+ if (aExp == bExp && aSig == bSig)
+ return float_relation_equal;
+
+ less_than =
+ aSign ? ((bExp < aExp) || ((bExp == aExp) && (bSig < aSig)))
+ : ((aExp < bExp) || ((aExp == bExp) && (aSig < bSig)));
+
+ if (less_than) return float_relation_less;
+ return float_relation_greater;
+}
+#endif
+
+/* ----- end from original file "softfloatx80.cc" ----- */
+
+/* ----- from original file "fprem.cc" ----- */
+
+/*
+ ["original Stanislav Shwartsman Copyright notice" went here, included near top of this file.]
+*/
+
+#define USE_estimateDiv128To64
+
+/* executes single exponent reduction cycle */
+LOCALFUNC Bit64u remainder_kernel(Bit64u aSig0, Bit64u bSig, int expDiff, Bit64u *zSig0, Bit64u *zSig1)
+{
+ Bit64u term0, term1;
+ Bit64u aSig1 = 0;
+ Bit64u q;
+
+ shortShift128Left(aSig1, aSig0, expDiff, &aSig1, &aSig0);
+ q = estimateDiv128To64(aSig1, aSig0, bSig);
+ mul64To128(bSig, q, &term0, &term1);
+ sub128(aSig1, aSig0, term0, term1, zSig1, zSig0);
+ while ((Bit64s)(*zSig1) < 0) {
+ --q;
+ add128(*zSig1, *zSig0, 0, bSig, zSig1, zSig0);
+ }
+ return q;
+}
+
+LOCALFUNC floatx80 do_fprem(floatx80 a, floatx80 b, Bit64u *q, int rounding_mode)
+{
+ Bit32s aExp, bExp, zExp, expDiff;
+ Bit64u aSig0, aSig1, bSig;
+ int aSign;
+ *q = 0;
+
+#if 0
+ // handle unsupported extended double-precision floating encodings
+ if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
+ {
+ float_raise(float_flag_invalid);
+ return floatx80_default_nan;
+ }
+#endif
+
+ aSig0 = extractFloatx80Frac(a);
+ aExp = extractFloatx80Exp(a);
+ aSign = extractFloatx80Sign(a);
+ bSig = extractFloatx80Frac(b);
+ bExp = extractFloatx80Exp(b);
+
+ if (aExp == 0x7FFF) {
+ if ((Bit64u) (aSig0<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) {
+ return propagateFloatx80NaN(a, b);
+ }
+ float_raise(float_flag_invalid);
+ return floatx80_default_nan;
+ }
+ if (bExp == 0x7FFF) {
+ if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b);
+ if (aExp == 0 && aSig0) {
+ float_raise(float_flag_denormal);
+ normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
+ return (a.low & LIT64(0x8000000000000000)) ?
+ packFloatx80(aSign, aExp, aSig0) : a;
+ }
+ return a;
+ }
+ if (bExp == 0) {
+ if (bSig == 0) {
+ float_raise(float_flag_invalid);
+ return floatx80_default_nan;
+ }
+ float_raise(float_flag_denormal);
+ normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+ }
+ if (aExp == 0) {
+ if (aSig0 == 0) return a;
+ float_raise(float_flag_denormal);
+ normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
+ }
+ expDiff = aExp - bExp;
+ aSig1 = 0;
+
+ if (expDiff >= 64) {
+ int n = (expDiff & 0x1f) | 0x20;
+ remainder_kernel(aSig0, bSig, n, &aSig0, &aSig1);
+ zExp = aExp - n;
+ *q = (Bit64u) -1;
+ }
+ else {
+ zExp = bExp;
+
+ if (expDiff < 0) {
+ if (expDiff < -1)
+ return (a.low & LIT64(0x8000000000000000)) ?
+ packFloatx80(aSign, aExp, aSig0) : a;
+ shift128Right(aSig0, 0, 1, &aSig0, &aSig1);
+ expDiff = 0;
+ }
+
+ if (expDiff > 0) {
+ *q = remainder_kernel(aSig0, bSig, expDiff, &aSig0, &aSig1);
+ }
+ else {
+ if (bSig <= aSig0) {
+ aSig0 -= bSig;
+ *q = 1;
+ }
+ }
+
+ if (rounding_mode == float_round_nearest_even)
+ {
+ Bit64u term0, term1;
+ shift128Right(bSig, 0, 1, &term0, &term1);
+
+ if (! lt128(aSig0, aSig1, term0, term1))
+ {
+ int lt = lt128(term0, term1, aSig0, aSig1);
+ int eq = eq128(aSig0, aSig1, term0, term1);
+
+ if ((eq && (*q & 1)) || lt) {
+ aSign = !aSign;
+ ++*q;
+ }
+ if (lt) sub128(bSig, 0, aSig0, aSig1, &aSig0, &aSig1);
+ }
+ }
+ }
+
+ return normalizeRoundAndPackFloatx80(80, aSign, zExp, aSig0, aSig1);
+}
+
+/*----------------------------------------------------------------------------
+| Returns the remainder of the extended double-precision floating-point value
+| `a' with respect to the corresponding value `b'. The operation is performed
+| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+#if cIncludeFPUUnused
+LOCALFUNC floatx80 floatx80_ieee754_remainder(floatx80 a, floatx80 b, Bit64u *q)
+{
+ return do_fprem(a, b, q, float_round_nearest_even);
+}
+#endif
+
+/*----------------------------------------------------------------------------
+| Returns the remainder of the extended double-precision floating-point value
+| `a' with respect to the corresponding value `b'. Unlike previous function
+| the function does not compute the remainder specified in the IEC/IEEE
+| Standard for Binary Floating-Point Arithmetic. This function operates
+| differently from the previous function in the way that it rounds the
+| quotient of 'a' divided by 'b' to an integer.
+*----------------------------------------------------------------------------*/
+
+LOCALFUNC floatx80 floatx80_remainder(floatx80 a, floatx80 b, Bit64u *q)
+{
+ return do_fprem(a, b, q, float_round_to_zero);
+}
+
+/* ----- end from original file "fprem.cc" ----- */
+
+/* ----- from original file "fpu_constant.h" ----- */
+
+/*
+ ["original Stanislav Shwartsman Copyright notice" went here, included near top of this file.]
+*/
+
+// Pentium CPU uses only 68-bit precision M_PI approximation
+// #define BETTER_THAN_PENTIUM
+
+//////////////////////////////
+// PI, PI/2, PI/4 constants
+//////////////////////////////
+
+#define FLOATX80_PI_EXP (0x4000)
+
+// 128-bit PI fraction
+#ifdef BETTER_THAN_PENTIUM
+#define FLOAT_PI_HI (LIT64(0xc90fdaa22168c234))
+#define FLOAT_PI_LO (LIT64(0xc4c6628b80dc1cd1))
+#else
+#define FLOAT_PI_HI (LIT64(0xc90fdaa22168c234))
+#define FLOAT_PI_LO (LIT64(0xC000000000000000))
+#endif
+
+#define FLOATX80_PI2_EXP (0x3FFF)
+#define FLOATX80_PI4_EXP (0x3FFE)
+
+//////////////////////////////
+// 3PI/4 constant
+//////////////////////////////
+
+#define FLOATX80_3PI4_EXP (0x4000)
+
+// 128-bit 3PI/4 fraction
+#ifdef BETTER_THAN_PENTIUM
+#define FLOAT_3PI4_HI (LIT64(0x96cbe3f9990e91a7))
+#define FLOAT_3PI4_LO (LIT64(0x9394c9e8a0a5159c))
+#else
+#define FLOAT_3PI4_HI (LIT64(0x96cbe3f9990e91a7))
+#define FLOAT_3PI4_LO (LIT64(0x9000000000000000))
+#endif
+
+//////////////////////////////
+// 1/LN2 constant
+//////////////////////////////
+
+#define FLOAT_LN2INV_EXP (0x3FFF)
+
+// 128-bit 1/LN2 fraction
+#ifdef BETTER_THAN_PENTIUM
+#define FLOAT_LN2INV_HI (LIT64(0xb8aa3b295c17f0bb))
+#define FLOAT_LN2INV_LO (LIT64(0xbe87fed0691d3e89))
+#else
+#define FLOAT_LN2INV_HI (LIT64(0xb8aa3b295c17f0bb))
+#define FLOAT_LN2INV_LO (LIT64(0xC000000000000000))
+#endif
+
+/* ----- end from original file "fpu_constant.h" ----- */
+
+/* ----- from original file "poly.cc" ----- */
+
+/*
+ ["original Stanislav Shwartsman Copyright notice" went here, included near top of this file.]
+*/
+
+// 2 3 4 n
+// f(x) ~ C + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x)
+// 0 1 2 3 4 n
+//
+// -- 2k -- 2k+1
+// p(x) = > C * x q(x) = > C * x
+// -- 2k -- 2k+1
+//
+// f(x) ~ [ p(x) + x * q(x) ]
+//
+
+LOCALFUNC float128 EvalPoly(float128 x, float128 *arr, unsigned n)
+{
+ float128 r2;
+ float128 x2 = float128_mul(x, x);
+ unsigned i;
+
+#if 0
+ assert(n > 1);
+#endif
+
+ float128 r1 = arr[--n];
+ i = n;
+ while(i >= 2) {
+ r1 = float128_mul(r1, x2);
+ i -= 2;
+ r1 = float128_add(r1, arr[i]);
+ }
+ if (i) r1 = float128_mul(r1, x);
+
+ r2 = arr[--n];
+ i = n;
+ while(i >= 2) {
+ r2 = float128_mul(r2, x2);
+ i -= 2;
+ r2 = float128_add(r2, arr[i]);
+ }
+ if (i) r2 = float128_mul(r2, x);
+
+ return float128_add(r1, r2);
+}
+
+// 2 4 6 8 2n
+// f(x) ~ C + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x)
+// 0 1 2 3 4 n
+//
+// -- 4k -- 4k+2
+// p(x) = > C * x q(x) = > C * x
+// -- 2k -- 2k+1
+//
+// 2
+// f(x) ~ [ p(x) + x * q(x) ]
+//
+
+LOCALFUNC float128 EvenPoly(float128 x, float128 *arr, unsigned n)
+{
+ return EvalPoly(float128_mul(x, x), arr, n);
+}
+
+// 3 5 7 9 2n+1
+// f(x) ~ (C * x) + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x)
+// 0 1 2 3 4 n
+// 2 4 6 8 2n
+// = x * [ C + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x)
+// 0 1 2 3 4 n
+//
+// -- 4k -- 4k+2
+// p(x) = > C * x q(x) = > C * x
+// -- 2k -- 2k+1
+//
+// 2
+// f(x) ~ x * [ p(x) + x * q(x) ]
+//
+
+LOCALFUNC float128 OddPoly(float128 x, float128 *arr, unsigned n)
+{
+ return float128_mul(x, EvenPoly(x, arr, n));
+}
+
+/* ----- end from original file "poly.cc" ----- */
+
+/* ----- from original file "fyl2x.cc" ----- */
+
+/*
+ ["original Stanislav Shwartsman Copyright notice" went here, included near top of this file.]
+*/
+
+static const floatx80 floatx80_one =
+ packFloatx80m(0, 0x3fff, LIT64(0x8000000000000000));
+
+static const float128 float128_one =
+ packFloat2x128m(LIT64(0x3fff000000000000), LIT64(0x0000000000000000));
+static const float128 float128_two =
+ packFloat2x128m(LIT64(0x4000000000000000), LIT64(0x0000000000000000));
+
+static const float128 float128_ln2inv2 =
+ packFloat2x128m(LIT64(0x400071547652b82f), LIT64(0xe1777d0ffda0d23a));
+
+#define SQRT2_HALF_SIG LIT64(0xb504f333f9de6484)
+
+#define L2_ARR_SIZE 9
+
+static float128 ln_arr[L2_ARR_SIZE] =
+{
+ PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
+ PACK_FLOAT_128(0x3ffd555555555555, 0x5555555555555555), /* 3 */
+ PACK_FLOAT_128(0x3ffc999999999999, 0x999999999999999a), /* 5 */
+ PACK_FLOAT_128(0x3ffc249249249249, 0x2492492492492492), /* 7 */
+ PACK_FLOAT_128(0x3ffbc71c71c71c71, 0xc71c71c71c71c71c), /* 9 */
+ PACK_FLOAT_128(0x3ffb745d1745d174, 0x5d1745d1745d1746), /* 11 */
+ PACK_FLOAT_128(0x3ffb3b13b13b13b1, 0x3b13b13b13b13b14), /* 13 */
+ PACK_FLOAT_128(0x3ffb111111111111, 0x1111111111111111), /* 15 */
+ PACK_FLOAT_128(0x3ffae1e1e1e1e1e1, 0xe1e1e1e1e1e1e1e2) /* 17 */
+};
+
+LOCALFUNC float128 poly_ln(float128 x1)
+{
+/*
+ //
+ // 3 5 7 9 11 13 15
+ // 1+u u u u u u u u
+ // 1/2 ln --- ~ u + --- + --- + --- + --- + ---- + ---- + ---- =
+ // 1-u 3 5 7 9 11 13 15
+ //
+ // 2 4 6 8 10 12 14
+ // u u u u u u u
+ // = u * [ 1 + --- + --- + --- + --- + ---- + ---- + ---- ] =
+ // 3 5 7 9 11 13 15
+ //
+ // 3 3
+ // -- 4k -- 4k+2
+ // p(u) = > C * u q(u) = > C * u
+ // -- 2k -- 2k+1
+ // k=0 k=0
+ //
+ // 1+u 2
+ // 1/2 ln --- ~ u * [ p(u) + u * q(u) ]
+ // 1-u
+ //
+*/
+ return OddPoly(x1, ln_arr, L2_ARR_SIZE);
+}
+
+/* required sqrt(2)/2 < x < sqrt(2) */
+LOCALFUNC float128 poly_l2(float128 x)
+{
+ /* using float128 for approximation */
+ float128 x_p1 = float128_add(x, float128_one);
+ float128 x_m1 = float128_sub(x, float128_one);
+ x = float128_div(x_m1, x_p1);
+ x = poly_ln(x);
+ x = float128_mul(x, float128_ln2inv2);
+ return x;
+}
+
+LOCALFUNC float128 poly_l2p1(float128 x)
+{
+ /* using float128 for approximation */
+ float128 x_p2 = float128_add(x, float128_two);
+ x = float128_div(x, x_p2);
+ x = poly_ln(x);
+ x = float128_mul(x, float128_ln2inv2);
+ return x;
+}
+
+// =================================================
+// FYL2X Compute y * log (x)
+// 2
+// =================================================
+
+//
+// Uses the following identities:
+//
+// 1. ----------------------------------------------------------
+// ln(x)
+// log (x) = -------, ln (x*y) = ln(x) + ln(y)
+// 2 ln(2)
+//
+// 2. ----------------------------------------------------------
+// 1+u x-1
+// ln (x) = ln -----, when u = -----
+// 1-u x+1
+//
+// 3. ----------------------------------------------------------
+// 3 5 7 2n+1
+// 1+u u u u u
+// ln ----- = 2 [ u + --- + --- + --- + ... + ------ + ... ]
+// 1-u 3 5 7 2n+1
+//
+
+LOCALFUNC floatx80 fyl2x(floatx80 a, floatx80 b)
+{
+ int aSign;
+ int bSign;
+ Bit64u aSig;
+ Bit32s aExp;
+ Bit64u bSig;
+ Bit32s bExp;
+ int zSign;
+ int ExpDiff;
+ Bit64u zSig0, zSig1;
+ float128 x;
+
+ // handle unsupported extended double-precision floating encodings
+ if (0 /* floatx80_is_unsupported(a) */) {
+invalid:
+ float_raise(float_flag_invalid);
+ return floatx80_default_nan;
+ }
+
+ aSig = extractFloatx80Frac(a);
+ aExp = extractFloatx80Exp(a);
+ aSign = extractFloatx80Sign(a);
+ bSig = extractFloatx80Frac(b);
+ bExp = extractFloatx80Exp(b);
+ bSign = extractFloatx80Sign(b);
+
+ zSign = bSign ^ 1;
+
+ if (aExp == 0x7FFF) {
+ if ((Bit64u) (aSig<<1)
+ || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
+ {
+ return propagateFloatx80NaN(a, b);
+ }
+ if (aSign) goto invalid;
+ else {
+ if (bExp == 0) {
+ if (bSig == 0) goto invalid;
+ float_raise(float_flag_denormal);
+ }
+ return packFloatx80(bSign, 0x7FFF, LIT64(0x8000000000000000));
+ }
+ }
+ if (bExp == 0x7FFF)
+ {
+ if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b);
+ if (aSign && (Bit64u)(aExp | aSig)) goto invalid;
+ if (aSig && (aExp == 0))
+ float_raise(float_flag_denormal);
+ if (aExp < 0x3FFF) {
+ return packFloatx80(zSign, 0x7FFF, LIT64(0x8000000000000000));
+ }
+ if (aExp == 0x3FFF && ((Bit64u) (aSig<<1) == 0)) goto invalid;
+ return packFloatx80(bSign, 0x7FFF, LIT64(0x8000000000000000));
+ }
+ if (aExp == 0) {
+ if (aSig == 0) {
+ if ((bExp | bSig) == 0) goto invalid;
+ float_raise(float_flag_divbyzero);
+ return packFloatx80(zSign, 0x7FFF, LIT64(0x8000000000000000));
+ }
+ if (aSign) goto invalid;
+ float_raise(float_flag_denormal);
+ normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ }
+ if (aSign) goto invalid;
+ if (bExp == 0) {
+ if (bSig == 0) {
+ if (aExp < 0x3FFF) return packFloatx80(zSign, 0, 0);
+ return packFloatx80(bSign, 0, 0);
+ }
+ float_raise(float_flag_denormal);
+ normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+ }
+ if (aExp == 0x3FFF && ((Bit64u) (aSig<<1) == 0))
+ return packFloatx80(bSign, 0, 0);
+
+ float_raise(float_flag_inexact);
+
+ ExpDiff = aExp - 0x3FFF;
+ aExp = 0;
+ if (aSig >= SQRT2_HALF_SIG) {
+ ExpDiff++;
+ aExp--;
+ }
+
+ /* ******************************** */
+ /* using float128 for approximation */
+ /* ******************************** */
+
+ shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
+ x = packFloat128(0, aExp+0x3FFF, zSig0, zSig1);
+ x = poly_l2(x);
+ x = float128_add(x, floatx80_to_float128(int32_to_floatx80(ExpDiff)));
+ return floatx80_mul128(b, x);
+}
+
+// =================================================
+// FYL2XP1 Compute y * log (x + 1)
+// 2
+// =================================================
+
+//
+// Uses the following identities:
+//
+// 1. ----------------------------------------------------------
+// ln(x)
+// log (x) = -------
+// 2 ln(2)
+//
+// 2. ----------------------------------------------------------
+// 1+u x
+// ln (x+1) = ln -----, when u = -----
+// 1-u x+2
+//
+// 3. ----------------------------------------------------------
+// 3 5 7 2n+1
+// 1+u u u u u
+// ln ----- = 2 [ u + --- + --- + --- + ... + ------ + ... ]
+// 1-u 3 5 7 2n+1
+//
+
+LOCALFUNC floatx80 fyl2xp1(floatx80 a, floatx80 b)
+{
+ Bit32s aExp, bExp;
+ Bit64u aSig, bSig, zSig0, zSig1, zSig2;
+ int aSign, bSign;
+ int zSign;
+ float128 x;
+
+ // handle unsupported extended double-precision floating encodings
+ if (0 /* floatx80_is_unsupported(a) */) {
+invalid:
+ float_raise(float_flag_invalid);
+ return floatx80_default_nan;
+ }
+
+ aSig = extractFloatx80Frac(a);
+ aExp = extractFloatx80Exp(a);
+ aSign = extractFloatx80Sign(a);
+ bSig = extractFloatx80Frac(b);
+ bExp = extractFloatx80Exp(b);
+ bSign = extractFloatx80Sign(b);
+ zSign = aSign ^ bSign;
+
+ if (aExp == 0x7FFF) {
+ if ((Bit64u) (aSig<<1)
+ || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
+ {
+ return propagateFloatx80NaN(a, b);
+ }
+ if (aSign) goto invalid;
+ else {
+ if (bExp == 0) {
+ if (bSig == 0) goto invalid;
+ float_raise(float_flag_denormal);
+ }
+ return packFloatx80(bSign, 0x7FFF, LIT64(0x8000000000000000));
+ }
+ }
+ if (bExp == 0x7FFF)
+ {
+ if ((Bit64u) (bSig<<1))
+ return propagateFloatx80NaN(a, b);
+
+ if (aExp == 0) {
+ if (aSig == 0) goto invalid;
+ float_raise(float_flag_denormal);
+ }
+
+ return packFloatx80(zSign, 0x7FFF, LIT64(0x8000000000000000));
+ }
+ if (aExp == 0) {
+ if (aSig == 0) {
+ if (bSig && (bExp == 0)) float_raise(float_flag_denormal);
+ return packFloatx80(zSign, 0, 0);
+ }
+ float_raise(float_flag_denormal);
+ normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ }
+ if (bExp == 0) {
+ if (bSig == 0) return packFloatx80(zSign, 0, 0);
+ float_raise(float_flag_denormal);
+ normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+ }
+
+ float_raise(float_flag_inexact);
+
+ if (aSign && aExp >= 0x3FFF)
+ return a;
+
+ if (aExp >= 0x3FFC) // big argument
+ {
+ return fyl2x(floatx80_add(a, floatx80_one), b);
+ }
+
+ // handle tiny argument
+ if (aExp < EXP_BIAS-70)
+ {
+ // first order approximation, return (a*b)/ln(2)
+ Bit32s zExp = aExp + FLOAT_LN2INV_EXP - 0x3FFE;
+
+ mul128By64To192(FLOAT_LN2INV_HI, FLOAT_LN2INV_LO, aSig, &zSig0, &zSig1, &zSig2);
+ if (0 < (Bit64s) zSig0) {
+ shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
+ --zExp;
+ }
+
+ zExp = zExp + bExp - 0x3FFE;
+ mul128By64To192(zSig0, zSig1, bSig, &zSig0, &zSig1, &zSig2);
+ if (0 < (Bit64s) zSig0) {
+ shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
+ --zExp;
+ }
+
+ return
+ roundAndPackFloatx80(80, aSign ^ bSign, zExp, zSig0, zSig1);
+ }
+
+ /* ******************************** */
+ /* using float128 for approximation */
+ /* ******************************** */
+
+ shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
+ x = packFloat128(aSign, aExp, zSig0, zSig1);
+ x = poly_l2p1(x);
+ return floatx80_mul128(b, x);
+}
+
+/* ----- end from original file "fyl2x.cc" ----- */
+
+/* ----- from original file "f2xm1.cc" ----- */
+
+/*
+ ["original Stanislav Shwartsman Copyright notice" went here, included near top of this file.]
+*/
+
+static const floatx80 floatx80_negone = packFloatx80m(1, 0x3fff, LIT64(0x8000000000000000));
+static const floatx80 floatx80_neghalf = packFloatx80m(1, 0x3ffe, LIT64(0x8000000000000000));
+static const float128 float128_ln2 =
+ packFloat2x128m(LIT64(0x3ffe62e42fefa39e), LIT64(0xf35793c7673007e6));
+
+#define LN2_SIG LIT64(0xb17217f7d1cf79ac)
+
+#define EXP_ARR_SIZE 15
+
+static float128 exp_arr[EXP_ARR_SIZE] =
+{
+ PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
+ PACK_FLOAT_128(0x3ffe000000000000, 0x0000000000000000), /* 2 */
+ PACK_FLOAT_128(0x3ffc555555555555, 0x5555555555555555), /* 3 */
+ PACK_FLOAT_128(0x3ffa555555555555, 0x5555555555555555), /* 4 */
+ PACK_FLOAT_128(0x3ff8111111111111, 0x1111111111111111), /* 5 */
+ PACK_FLOAT_128(0x3ff56c16c16c16c1, 0x6c16c16c16c16c17), /* 6 */
+ PACK_FLOAT_128(0x3ff2a01a01a01a01, 0xa01a01a01a01a01a), /* 7 */
+ PACK_FLOAT_128(0x3fefa01a01a01a01, 0xa01a01a01a01a01a), /* 8 */
+ PACK_FLOAT_128(0x3fec71de3a556c73, 0x38faac1c88e50017), /* 9 */
+ PACK_FLOAT_128(0x3fe927e4fb7789f5, 0xc72ef016d3ea6679), /* 10 */
+ PACK_FLOAT_128(0x3fe5ae64567f544e, 0x38fe747e4b837dc7), /* 11 */
+ PACK_FLOAT_128(0x3fe21eed8eff8d89, 0x7b544da987acfe85), /* 12 */
+ PACK_FLOAT_128(0x3fde6124613a86d0, 0x97ca38331d23af68), /* 13 */
+ PACK_FLOAT_128(0x3fda93974a8c07c9, 0xd20badf145dfa3e5), /* 14 */
+ PACK_FLOAT_128(0x3fd6ae7f3e733b81, 0xf11d8656b0ee8cb0) /* 15 */
+};
+
+/* required -1 < x < 1 */
+LOCALFUNC float128 poly_exp(float128 x)
+{
+/*
+ // 2 3 4 5 6 7 8 9
+ // x x x x x x x x x
+ // e - 1 ~ x + --- + --- + --- + --- + --- + --- + --- + --- + ...
+ // 2! 3! 4! 5! 6! 7! 8! 9!
+ //
+ // 2 3 4 5 6 7 8
+ // x x x x x x x x
+ // = x [ 1 + --- + --- + --- + --- + --- + --- + --- + --- + ... ]
+ // 2! 3! 4! 5! 6! 7! 8! 9!
+ //
+ // 8 8
+ // -- 2k -- 2k+1
+ // p(x) = > C * x q(x) = > C * x
+ // -- 2k -- 2k+1
+ // k=0 k=0
+ //
+ // x
+ // e - 1 ~ x * [ p(x) + x * q(x) ]
+ //
+*/
+ float128 t = EvalPoly(x, exp_arr, EXP_ARR_SIZE);
+ return float128_mul(t, x);
+}
+
+// =================================================
+// x
+// FX2P1 Compute 2 - 1
+// =================================================
+
+//
+// Uses the following identities:
+//
+// 1. ----------------------------------------------------------
+// x x*ln(2)
+// 2 = e
+//
+// 2. ----------------------------------------------------------
+// 2 3 4 5 n
+// x x x x x x x
+// e = 1 + --- + --- + --- + --- + --- + ... + --- + ...
+// 1! 2! 3! 4! 5! n!
+//
+
+LOCALFUNC floatx80 f2xm1(floatx80 a)
+{
+ Bit64u zSig0, zSig1;
+ float128 x;
+
+#if 0
+ // handle unsupported extended double-precision floating encodings
+ if (floatx80_is_unsupported(a))
+ {
+ float_raise(float_flag_invalid);
+ return floatx80_default_nan;
+ }
+#endif
+
+ Bit64u aSig = extractFloatx80Frac(a);
+ Bit32s aExp = extractFloatx80Exp(a);
+ int aSign = extractFloatx80Sign(a);
+
+ if (aExp == 0x7FFF) {
+ if ((Bit64u) (aSig<<1))
+ return propagateOneFloatx80NaN(&a);
+
+ return (aSign) ? floatx80_negone : a;
+ }
+
+ if (aExp == 0) {
+ if (aSig == 0) return a;
+ float_raise(float_flag_denormal | float_flag_inexact);
+ normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+
+ tiny_argument:
+ mul64To128(aSig, LN2_SIG, &zSig0, &zSig1);
+ if (0 < (Bit64s) zSig0) {
+ shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
+ --aExp;
+ }
+ return
+ roundAndPackFloatx80(80, aSign, aExp, zSig0, zSig1);
+ }
+
+ float_raise(float_flag_inexact);
+
+ if (aExp < 0x3FFF)
+ {
+ if (aExp < EXP_BIAS-68)
+ goto tiny_argument;
+
+ /* ******************************** */
+ /* using float128 for approximation */
+ /* ******************************** */
+
+ x = floatx80_to_float128(a);
+ x = float128_mul(x, float128_ln2);
+ x = poly_exp(x);
+ return float128_to_floatx80(x);
+ }
+ else
+ {
+ if ((a.high == 0xBFFF) && (! (aSig<<1)))
+ return floatx80_neghalf;
+
+ return a;
+ }
+}
+
+/* ----- end from original file "f2xm1.cc" ----- */
+
+/* ----- from original file "fsincos.cc" ----- */
+
+/*
+ ["original Stanislav Shwartsman Copyright notice" went here, included near top of this file.]
+*/
+
+#define USE_estimateDiv128To64
+
+#if 0
+static const floatx80 floatx80_one = packFloatx80m(0, 0x3fff, LIT64(0x8000000000000000));
+#endif
+
+/* reduce trigonometric function argument using 128-bit precision
+ M_PI approximation */
+LOCALFUNC Bit64u argument_reduction_kernel(Bit64u aSig0, int Exp, Bit64u *zSig0, Bit64u *zSig1)
+{
+ Bit64u term0, term1, term2;
+ Bit64u aSig1 = 0;
+ Bit64u q;
+
+ shortShift128Left(aSig1, aSig0, Exp, &aSig1, &aSig0);
+ q = estimateDiv128To64(aSig1, aSig0, FLOAT_PI_HI);
+ mul128By64To192(FLOAT_PI_HI, FLOAT_PI_LO, q, &term0, &term1, &term2);
+ sub128(aSig1, aSig0, term0, term1, zSig1, zSig0);
+ while ((Bit64s)(*zSig1) < 0) {
+ --q;
+ add192(*zSig1, *zSig0, term2, 0, FLOAT_PI_HI, FLOAT_PI_LO, zSig1, zSig0, &term2);
+ }
+ *zSig1 = term2;
+ return q;
+}
+
+LOCALFUNC int reduce_trig_arg(int expDiff, int *zSign, Bit64u *aSig0, Bit64u *aSig1)
+{
+ Bit64u term0, term1, q = 0;
+
+ if (expDiff < 0) {
+ shift128Right(*aSig0, 0, 1, aSig0, aSig1);
+ expDiff = 0;
+ }
+ if (expDiff > 0) {
+ q = argument_reduction_kernel(*aSig0, expDiff, aSig0, aSig1);
+ }
+ else {
+ if (FLOAT_PI_HI <= *aSig0) {
+ *aSig0 -= FLOAT_PI_HI;
+ q = 1;
+ }
+ }
+
+ shift128Right(FLOAT_PI_HI, FLOAT_PI_LO, 1, &term0, &term1);
+ if (! lt128(*aSig0, *aSig1, term0, term1))
+ {
+ int lt = lt128(term0, term1, *aSig0, *aSig1);
+ int eq = eq128(*aSig0, *aSig1, term0, term1);
+
+ if ((eq && (q & 1)) || lt) {
+ *zSign = !*zSign;
+ ++q;
+ }
+ if (lt) sub128(FLOAT_PI_HI, FLOAT_PI_LO, *aSig0, *aSig1, aSig0, aSig1);
+ }
+
+ return (int)(q & 3);
+}
+
+#define SIN_ARR_SIZE 9
+#define COS_ARR_SIZE 9
+
+static float128 sin_arr[SIN_ARR_SIZE] =
+{
+ PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
+ PACK_FLOAT_128(0xbffc555555555555, 0x5555555555555555), /* 3 */
+ PACK_FLOAT_128(0x3ff8111111111111, 0x1111111111111111), /* 5 */
+ PACK_FLOAT_128(0xbff2a01a01a01a01, 0xa01a01a01a01a01a), /* 7 */
+ PACK_FLOAT_128(0x3fec71de3a556c73, 0x38faac1c88e50017), /* 9 */
+ PACK_FLOAT_128(0xbfe5ae64567f544e, 0x38fe747e4b837dc7), /* 11 */
+ PACK_FLOAT_128(0x3fde6124613a86d0, 0x97ca38331d23af68), /* 13 */
+ PACK_FLOAT_128(0xbfd6ae7f3e733b81, 0xf11d8656b0ee8cb0), /* 15 */
+ PACK_FLOAT_128(0x3fce952c77030ad4, 0xa6b2605197771b00) /* 17 */
+};
+
+static float128 cos_arr[COS_ARR_SIZE] =
+{
+ PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 0 */
+ PACK_FLOAT_128(0xbffe000000000000, 0x0000000000000000), /* 2 */
+ PACK_FLOAT_128(0x3ffa555555555555, 0x5555555555555555), /* 4 */
+ PACK_FLOAT_128(0xbff56c16c16c16c1, 0x6c16c16c16c16c17), /* 6 */
+ PACK_FLOAT_128(0x3fefa01a01a01a01, 0xa01a01a01a01a01a), /* 8 */
+ PACK_FLOAT_128(0xbfe927e4fb7789f5, 0xc72ef016d3ea6679), /* 10 */
+ PACK_FLOAT_128(0x3fe21eed8eff8d89, 0x7b544da987acfe85), /* 12 */
+ PACK_FLOAT_128(0xbfda93974a8c07c9, 0xd20badf145dfa3e5), /* 14 */
+ PACK_FLOAT_128(0x3fd2ae7f3e733b81, 0xf11d8656b0ee8cb0) /* 16 */
+};
+
+/* 0 <= x <= pi/4 */
+LOCALINLINEFUNC float128 poly_sin(float128 x)
+{
+ // 3 5 7 9 11 13 15
+ // x x x x x x x
+ // sin (x) ~ x - --- + --- - --- + --- - ---- + ---- - ---- =
+ // 3! 5! 7! 9! 11! 13! 15!
+ //
+ // 2 4 6 8 10 12 14
+ // x x x x x x x
+ // = x * [ 1 - --- + --- - --- + --- - ---- + ---- - ---- ] =
+ // 3! 5! 7! 9! 11! 13! 15!
+ //
+ // 3 3
+ // -- 4k -- 4k+2
+ // p(x) = > C * x > 0 q(x) = > C * x < 0
+ // -- 2k -- 2k+1
+ // k=0 k=0
+ //
+ // 2
+ // sin(x) ~ x * [ p(x) + x * q(x) ]
+ //
+
+ return OddPoly(x, sin_arr, SIN_ARR_SIZE);
+}
+
+/* 0 <= x <= pi/4 */
+LOCALINLINEFUNC float128 poly_cos(float128 x)
+{
+ // 2 4 6 8 10 12 14
+ // x x x x x x x
+ // cos (x) ~ 1 - --- + --- - --- + --- - ---- + ---- - ----
+ // 2! 4! 6! 8! 10! 12! 14!
+ //
+ // 3 3
+ // -- 4k -- 4k+2
+ // p(x) = > C * x > 0 q(x) = > C * x < 0
+ // -- 2k -- 2k+1
+ // k=0 k=0
+ //
+ // 2
+ // cos(x) ~ [ p(x) + x * q(x) ]
+ //
+
+ return EvenPoly(x, cos_arr, COS_ARR_SIZE);
+}
+
+LOCALINLINEPROC sincos_invalid(floatx80 *sin_a, floatx80 *cos_a, floatx80 a)
+{
+ if (sin_a) *sin_a = a;
+ if (cos_a) *cos_a = a;
+}
+
+LOCALINLINEPROC sincos_tiny_argument(floatx80 *sin_a, floatx80 *cos_a, floatx80 a)
+{
+ if (sin_a) *sin_a = a;
+ if (cos_a) *cos_a = floatx80_one;
+}
+
+LOCALFUNC floatx80 sincos_approximation(int neg, float128 r, Bit64u quotient)
+{
+ floatx80 result;
+
+ if (quotient & 0x1) {
+ r = poly_cos(r);
+ neg = 0;
+ } else {
+ r = poly_sin(r);
+ }
+
+ result = float128_to_floatx80(r);
+ if (quotient & 0x2)
+ neg = ! neg;
+
+ if (neg)
+ floatx80_chs(&result);
+
+ return result;
+}
+
+// =================================================
+// FSINCOS Compute sin(x) and cos(x)
+// =================================================
+
+//
+// Uses the following identities:
+// ----------------------------------------------------------
+//
+// sin(-x) = -sin(x)
+// cos(-x) = cos(x)
+//
+// sin(x+y) = sin(x)*cos(y)+cos(x)*sin(y)
+// cos(x+y) = sin(x)*sin(y)+cos(x)*cos(y)
+//
+// sin(x+ pi/2) = cos(x)
+// sin(x+ pi) = -sin(x)
+// sin(x+3pi/2) = -cos(x)
+// sin(x+2pi) = sin(x)
+//
+
+LOCALFUNC int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a)
+{
+ float128 r;
+ Bit64u aSig0, aSig1 = 0;
+ Bit32s aExp, zExp, expDiff;
+ int aSign, zSign;
+ int q = 0;
+
+#if 0
+ // handle unsupported extended double-precision floating encodings
+ if (floatx80_is_unsupported(a))
+ {
+ goto invalid;
+ }
+#endif
+
+ aSig0 = extractFloatx80Frac(a);
+ aExp = extractFloatx80Exp(a);
+ aSign = extractFloatx80Sign(a);
+
+ /* invalid argument */
+ if (aExp == 0x7FFF) {
+ if ((Bit64u) (aSig0<<1)) {
+ sincos_invalid(sin_a, cos_a, propagateOneFloatx80NaN(&a));
+ return 0;
+ }
+
+#if 0
+ invalid:
+#endif
+ float_raise(float_flag_invalid);
+ sincos_invalid(sin_a, cos_a, floatx80_default_nan);
+ return 0;
+ }
+
+ if (aExp == 0) {
+ if (aSig0 == 0) {
+ sincos_tiny_argument(sin_a, cos_a, a);
+ return 0;
+ }
+
+ float_raise(float_flag_denormal);
+
+ /* handle pseudo denormals */
+ if (! (aSig0 & LIT64(0x8000000000000000)))
+ {
+ float_raise(float_flag_inexact);
+ if (sin_a)
+ float_raise(float_flag_underflow);
+ sincos_tiny_argument(sin_a, cos_a, a);
+ return 0;
+ }
+
+ normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
+ }
+
+ zSign = aSign;
+ zExp = EXP_BIAS;
+ expDiff = aExp - zExp;
+
+ /* argument is out-of-range */
+ if (expDiff >= 63)
+ return -1;
+
+ float_raise(float_flag_inexact);
+
+ if (expDiff < -1) { // doesn't require reduction
+ if (expDiff <= -68) {
+ a = packFloatx80(aSign, aExp, aSig0);
+ sincos_tiny_argument(sin_a, cos_a, a);
+ return 0;
+ }
+ zExp = aExp;
+ }
+ else {
+ q = reduce_trig_arg(expDiff, &zSign, &aSig0, &aSig1);
+ }
+
+ /* **************************** */
+ /* argument reduction completed */
+ /* **************************** */
+
+ /* using float128 for approximation */
+ r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1);
+
+ if (aSign) q = -q;
+ if (sin_a) *sin_a = sincos_approximation(zSign, r, q);
+ if (cos_a) *cos_a = sincos_approximation(zSign, r, q+1);
+
+ return 0;
+}
+
+// =================================================
+// FPTAN Compute tan(x)
+// =================================================
+
+//
+// Uses the following identities:
+//
+// 1. ----------------------------------------------------------
+//
+// sin(-x) = -sin(x)
+// cos(-x) = cos(x)
+//
+// sin(x+y) = sin(x)*cos(y)+cos(x)*sin(y)
+// cos(x+y) = sin(x)*sin(y)+cos(x)*cos(y)
+//
+// sin(x+ pi/2) = cos(x)
+// sin(x+ pi) = -sin(x)
+// sin(x+3pi/2) = -cos(x)
+// sin(x+2pi) = sin(x)
+//
+// 2. ----------------------------------------------------------
+//
+// sin(x)
+// tan(x) = ------
+// cos(x)
+//
+
+LOCALFUNC int ftan(floatx80 *a)
+{
+ float128 r;
+ float128 sin_r;
+ float128 cos_r;
+ Bit64u aSig0, aSig1 = 0;
+ Bit32s aExp, zExp, expDiff;
+ int aSign, zSign;
+ int q = 0;
+
+#if 0
+ // handle unsupported extended double-precision floating encodings
+ if (floatx80_is_unsupported(*a))
+ {
+ goto invalid;
+ }
+#endif
+
+ aSig0 = extractFloatx80Frac(*a);
+ aExp = extractFloatx80Exp(*a);
+ aSign = extractFloatx80Sign(*a);
+
+ /* invalid argument */
+ if (aExp == 0x7FFF) {
+ if ((Bit64u) (aSig0<<1))
+ {
+ *a = propagateOneFloatx80NaN(a);
+ return 0;
+ }
+
+#if 0
+ invalid:
+#endif
+ float_raise(float_flag_invalid);
+ *a = floatx80_default_nan;
+ return 0;
+ }
+
+ if (aExp == 0) {
+ if (aSig0 == 0) return 0;
+ float_raise(float_flag_denormal);
+ /* handle pseudo denormals */
+ if (! (aSig0 & LIT64(0x8000000000000000)))
+ {
+ float_raise(float_flag_inexact | float_flag_underflow);
+ return 0;
+ }
+ normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
+ }
+
+ zSign = aSign;
+ zExp = EXP_BIAS;
+ expDiff = aExp - zExp;
+
+ /* argument is out-of-range */
+ if (expDiff >= 63)
+ return -1;
+
+ float_raise(float_flag_inexact);
+
+ if (expDiff < -1) { // doesn't require reduction
+ if (expDiff <= -68) {
+ *a = packFloatx80(aSign, aExp, aSig0);
+ return 0;
+ }
+ zExp = aExp;
+ }
+ else {
+ q = reduce_trig_arg(expDiff, &zSign, &aSig0, &aSig1);
+ }
+
+ /* **************************** */
+ /* argument reduction completed */
+ /* **************************** */
+
+ /* using float128 for approximation */
+ r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1);
+
+ sin_r = poly_sin(r);
+ cos_r = poly_cos(r);
+
+ if (q & 0x1) {
+ r = float128_div(cos_r, sin_r);
+ zSign = ! zSign;
+ } else {
+ r = float128_div(sin_r, cos_r);
+ }
+
+ *a = float128_to_floatx80(r);
+ if (zSign)
+ floatx80_chs(a);
+
+ return 0;
+}
+
+/* ----- end from original file "fsincos.cc" ----- */
+
+/* ----- from original file "fpatan.cc" ----- */
+
+/*
+ ["original Stanislav Shwartsman Copyright notice" went here, included near top of this file.]
+*/
+
+#define FPATAN_ARR_SIZE 11
+
+#if 0
+static const float128 float128_one =
+ packFloat2x128m(LIT64(0x3fff000000000000), LIT64(0x0000000000000000));
+#endif
+static const float128 float128_sqrt3 =
+ packFloat2x128m(LIT64(0x3fffbb67ae8584ca), LIT64(0xa73b25742d7078b8));
+static const floatx80 floatx80_pi =
+ packFloatx80m(0, 0x4000, LIT64(0xc90fdaa22168c235));
+
+static const float128 float128_pi2 =
+ packFloat2x128m(LIT64(0x3fff921fb54442d1), LIT64(0x8469898CC5170416));
+static const float128 float128_pi4 =
+ packFloat2x128m(LIT64(0x3ffe921fb54442d1), LIT64(0x8469898CC5170416));
+static const float128 float128_pi6 =
+ packFloat2x128m(LIT64(0x3ffe0c152382d736), LIT64(0x58465BB32E0F580F));
+
+static float128 atan_arr[FPATAN_ARR_SIZE] =
+{
+ PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
+ PACK_FLOAT_128(0xbffd555555555555, 0x5555555555555555), /* 3 */
+ PACK_FLOAT_128(0x3ffc999999999999, 0x999999999999999a), /* 5 */
+ PACK_FLOAT_128(0xbffc249249249249, 0x2492492492492492), /* 7 */
+ PACK_FLOAT_128(0x3ffbc71c71c71c71, 0xc71c71c71c71c71c), /* 9 */
+ PACK_FLOAT_128(0xbffb745d1745d174, 0x5d1745d1745d1746), /* 11 */
+ PACK_FLOAT_128(0x3ffb3b13b13b13b1, 0x3b13b13b13b13b14), /* 13 */
+ PACK_FLOAT_128(0xbffb111111111111, 0x1111111111111111), /* 15 */
+ PACK_FLOAT_128(0x3ffae1e1e1e1e1e1, 0xe1e1e1e1e1e1e1e2), /* 17 */
+ PACK_FLOAT_128(0xbffaaf286bca1af2, 0x86bca1af286bca1b), /* 19 */
+ PACK_FLOAT_128(0x3ffa861861861861, 0x8618618618618618) /* 21 */
+};
+
+/* |x| < 1/4 */
+LOCALFUNC float128 poly_atan(float128 x1)
+{
+/*
+ // 3 5 7 9 11 13 15 17
+ // x x x x x x x x
+ // atan(x) ~ x - --- + --- - --- + --- - ---- + ---- - ---- + ----
+ // 3 5 7 9 11 13 15 17
+ //
+ // 2 4 6 8 10 12 14 16
+ // x x x x x x x x
+ // = x * [ 1 - --- + --- - --- + --- - ---- + ---- - ---- + ---- ]
+ // 3 5 7 9 11 13 15 17
+ //
+ // 5 5
+ // -- 4k -- 4k+2
+ // p(x) = > C * x q(x) = > C * x
+ // -- 2k -- 2k+1
+ // k=0 k=0
+ //
+ // 2
+ // atan(x) ~ x * [ p(x) + x * q(x) ]
+ //
+*/
+ return OddPoly(x1, atan_arr, FPATAN_ARR_SIZE);
+}
+
+// =================================================
+// FPATAN Compute y * log (x)
+// 2
+// =================================================
+
+//
+// Uses the following identities:
+//
+// 1. ----------------------------------------------------------
+//
+// atan(-x) = -atan(x)
+//
+// 2. ----------------------------------------------------------
+//
+// x + y
+// atan(x) + atan(y) = atan -------, xy < 1
+// 1-xy
+//
+// x + y
+// atan(x) + atan(y) = atan ------- + PI, x > 0, xy > 1
+// 1-xy
+//
+// x + y
+// atan(x) + atan(y) = atan ------- - PI, x < 0, xy > 1
+// 1-xy
+//
+// 3. ----------------------------------------------------------
+//
+// atan(x) = atan(INF) + atan(- 1/x)
+//
+// x-1
+// atan(x) = PI/4 + atan( ----- )
+// x+1
+//
+// x * sqrt(3) - 1
+// atan(x) = PI/6 + atan( ----------------- )
+// x + sqrt(3)
+//
+// 4. ----------------------------------------------------------
+// 3 5 7 9 2n+1
+// x x x x n x
+// atan(x) = x - --- + --- - --- + --- - ... + (-1) ------ + ...
+// 3 5 7 9 2n+1
+//
+
+LOCALFUNC floatx80 fpatan(floatx80 a, floatx80 b)
+{
+ float128 a128;
+ float128 b128;
+ float128 x;
+ int swap, add_pi6, add_pi4;
+ Bit32s xExp;
+ floatx80 result;
+ int rSign;
+
+ // handle unsupported extended double-precision floating encodings
+#if 0
+ if (floatx80_is_unsupported(a)) {
+ float_raise(float_flag_invalid);
+ return floatx80_default_nan;
+ }
+#endif
+
+ Bit64u aSig = extractFloatx80Frac(a);
+ Bit32s aExp = extractFloatx80Exp(a);
+ int aSign = extractFloatx80Sign(a);
+ Bit64u bSig = extractFloatx80Frac(b);
+ Bit32s bExp = extractFloatx80Exp(b);
+ int bSign = extractFloatx80Sign(b);
+
+ int zSign = aSign ^ bSign;
+
+ if (bExp == 0x7FFF)
+ {
+ if ((Bit64u) (bSig<<1))
+ return propagateFloatx80NaN(a, b);
+
+ if (aExp == 0x7FFF) {
+ if ((Bit64u) (aSig<<1))
+ return propagateFloatx80NaN(a, b);
+
+ if (aSign) { /* return 3PI/4 */
+ return roundAndPackFloatx80(80, bSign,
+ FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO);
+ }
+ else { /* return PI/4 */
+ return roundAndPackFloatx80(80, bSign,
+ FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO);
+ }
+ }
+
+ if (aSig && (aExp == 0))
+ float_raise(float_flag_denormal);
+
+ /* return PI/2 */
+ return roundAndPackFloatx80(80, bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO);
+ }
+ if (aExp == 0x7FFF)
+ {
+ if ((Bit64u) (aSig<<1))
+ return propagateFloatx80NaN(a, b);
+
+ if (bSig && (bExp == 0))
+ float_raise(float_flag_denormal);
+
+return_PI_or_ZERO:
+
+ if (aSign) { /* return PI */
+ return roundAndPackFloatx80(80, bSign, FLOATX80_PI_EXP, FLOAT_PI_HI, FLOAT_PI_LO);
+ } else { /* return 0 */
+ return packFloatx80(bSign, 0, 0);
+ }
+ }
+ if (bExp == 0)
+ {
+ if (bSig == 0) {
+ if (aSig && (aExp == 0)) float_raise(float_flag_denormal);
+ goto return_PI_or_ZERO;
+ }
+
+ float_raise(float_flag_denormal);
+ normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+ }
+ if (aExp == 0)
+ {
+ if (aSig == 0) /* return PI/2 */
+ return roundAndPackFloatx80(80, bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO);
+
+ float_raise(float_flag_denormal);
+ normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ }
+
+ float_raise(float_flag_inexact);
+
+ /* |a| = |b| ==> return PI/4 */
+ if (aSig == bSig && aExp == bExp)
+ return roundAndPackFloatx80(80, bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO);
+
+ /* ******************************** */
+ /* using float128 for approximation */
+ /* ******************************** */
+
+ a128 = normalizeRoundAndPackFloat128(0, aExp-0x10, aSig, 0);
+ b128 = normalizeRoundAndPackFloat128(0, bExp-0x10, bSig, 0);
+ swap = 0;
+ add_pi6 = 0;
+ add_pi4 = 0;
+
+ if (aExp > bExp || (aExp == bExp && aSig > bSig))
+ {
+ x = float128_div(b128, a128);
+ }
+ else {
+ x = float128_div(a128, b128);
+ swap = 1;
+ }
+
+ xExp = extractFloat128Exp(x);
+
+ if (xExp <= EXP_BIAS-40)
+ goto approximation_completed;
+
+ if (x.high >= LIT64(0x3ffe800000000000)) // 3/4 < x < 1
+ {
+ /*
+ arctan(x) = arctan((x-1)/(x+1)) + pi/4
+ */
+ float128 t1 = float128_sub(x, float128_one);
+ float128 t2 = float128_add(x, float128_one);
+ x = float128_div(t1, t2);
+ add_pi4 = 1;
+ }
+ else
+ {
+ /* argument correction */
+ if (xExp >= 0x3FFD) // 1/4 < x < 3/4
+ {
+ /*
+ arctan(x) = arctan((x*sqrt(3)-1)/(x+sqrt(3))) + pi/6
+ */
+ float128 t1 = float128_mul(x, float128_sqrt3);
+ float128 t2 = float128_add(x, float128_sqrt3);
+ x = float128_sub(t1, float128_one);
+ x = float128_div(x, t2);
+ add_pi6 = 1;
+ }
+ }
+
+ x = poly_atan(x);
+ if (add_pi6) x = float128_add(x, float128_pi6);
+ if (add_pi4) x = float128_add(x, float128_pi4);
+
+approximation_completed:
+ if (swap) x = float128_sub(float128_pi2, x);
+ result = float128_to_floatx80(x);
+ if (zSign) floatx80_chs(&result);
+ rSign = extractFloatx80Sign(result);
+ if (!bSign && rSign)
+ return floatx80_add(result, floatx80_pi);
+ if (bSign && !rSign)
+ return floatx80_sub(result, floatx80_pi);
+ return result;
+}
+
+/* ----- end from original file "fpatan.cc" ----- */
+
+/* end soft float stuff */
+
+typedef floatx80 myfpr;
+
+LOCALPROC myfp_FromExtendedFormat(myfpr *r, ui4r v2, ui5r v1, ui5r v0)
+{
+ r->high = v2;
+ r->low = (((ui6b)v1) << 32) | (v0 & 0xFFFFFFFF);
+}
+
+LOCALPROC myfp_ToExtendedFormat(myfpr *dd, ui4r *v2, ui5r *v1, ui5r *v0)
+{
+ *v0 = ((ui6b) dd->low) & 0xFFFFFFFF;
+ *v1 = (((ui6b) dd->low) >> 32) & 0xFFFFFFFF;
+ *v2 = dd->high;
+}
+
+LOCALPROC myfp_FromDoubleFormat(myfpr *r, ui5r v1, ui5r v0)
+{
+ float64 t = (float64)((((ui6b)v1) << 32) | (v0 & 0xFFFFFFFF));
+
+ *r = float64_to_floatx80(t);
+}
+
+LOCALPROC myfp_ToDoubleFormat(myfpr *dd, ui5r *v1, ui5r *v0)
+{
+ float64 t = floatx80_to_float64(*dd);
+
+ *v0 = ((ui6b) t) & 0xFFFFFFFF;
+ *v1 = (((ui6b) t) >> 32) & 0xFFFFFFFF;
+}
+
+LOCALPROC myfp_FromSingleFormat(myfpr *r, ui5r x)
+{
+ *r = float32_to_floatx80(x);
+}
+
+LOCALFUNC ui5r myfp_ToSingleFormat(myfpr *ff)
+{
+ return floatx80_to_float32(*ff);
+}
+
+LOCALPROC myfp_FromLong(myfpr *r, ui5r x)
+{
+ *r = int32_to_floatx80( x );
+}
+
+LOCALFUNC ui5r myfp_ToLong(myfpr *x)
+{
+ return floatx80_to_int32( *x );
+}
+
+LOCALFUNC blnr myfp_IsNan(myfpr *x)
+{
+ return floatx80_is_nan(*x);
+}
+
+LOCALFUNC blnr myfp_IsInf(myfpr *x)
+{
+ return ( ( x->high & 0x7FFF ) == 0x7FFF ) && (0 == ((ui6b) ( x->low<<1 )));
+}
+
+LOCALFUNC blnr myfp_IsZero(myfpr *x)
+{
+ return ( ( x->high & 0x7FFF ) == 0x0000 ) && (0 == ((ui6b) ( x->low<<1 )));
+}
+
+LOCALFUNC blnr myfp_IsNeg(myfpr *x)
+{
+ return ( ( x->high & 0x8000 ) != 0x0000 );
+}
+
+LOCALPROC myfp_Add(myfpr *r, const myfpr *a, const myfpr *b)
+{
+ *r = floatx80_add(*a, *b);
+}
+
+LOCALPROC myfp_Sub(myfpr *r, const myfpr *a, const myfpr *b)
+{
+ *r = floatx80_sub(*a, *b);
+}
+
+LOCALPROC myfp_Mul(myfpr *r, const myfpr *a, const myfpr *b)
+{
+ *r = floatx80_mul(*a, *b);
+}
+
+LOCALPROC myfp_Div(myfpr *r, const myfpr *a, const myfpr *b)
+{
+ *r = floatx80_div(*a, *b);
+}
+
+LOCALPROC myfp_Rem(myfpr *r, const myfpr *a, const myfpr *b)
+{
+ *r = floatx80_rem(*a, *b);
+}
+
+LOCALPROC myfp_Sqrt(myfpr *r, myfpr *x)
+{
+ *r = floatx80_sqrt(*x);
+}
+
+LOCALPROC myfp_Mod(myfpr *r, myfpr *a, myfpr *b)
+{
+ Bit64u q;
+ *r = floatx80_remainder(*a, *b, &q);
+ /* should save low byte of q */
+}
+
+LOCALPROC myfp_Scale(myfpr *r, myfpr *a, myfpr *b)
+{
+ *r = floatx80_scale(*a, *b);
+}
+
+LOCALPROC myfp_GetMan(myfpr *r, myfpr *x)
+{
+ *r = *x;
+ (void) floatx80_extract(r);
+}
+
+LOCALPROC myfp_GetExp(myfpr *r, myfpr *x)
+{
+ floatx80 t0 = *x;
+ *r = floatx80_extract(&t0);
+}
+
+LOCALPROC myfp_floor(myfpr *r, myfpr *x)
+{
+ si3r SaveRoundingMode = float_rounding_mode;
+
+ float_rounding_mode = float_round_down;
+ *r = floatx80_round_to_int(*x);
+ float_rounding_mode = SaveRoundingMode;
+}
+
+LOCALPROC myfp_IntRZ(myfpr *r, myfpr *x)
+{
+ si3r SaveRoundingMode = float_rounding_mode;
+
+ float_rounding_mode = float_round_to_zero;
+ *r = floatx80_round_to_int(*x);
+ float_rounding_mode = SaveRoundingMode;
+}
+
+LOCALPROC myfp_Int(myfpr *r, myfpr *x)
+{
+ *r = floatx80_round_to_int(*x);
+}
+
+LOCALPROC myfp_RoundToSingle(myfpr *r, myfpr *x)
+{
+ float32 t0 = floatx80_to_float32(*x);
+
+ *r = float32_to_floatx80(t0);
+}
+
+LOCALPROC myfp_RoundToDouble(myfpr *r, myfpr *x)
+{
+ float64 t0 = floatx80_to_float64(*x);
+
+ *r = float64_to_floatx80(t0);
+}
+
+LOCALPROC myfp_Abs(myfpr *r, myfpr *x)
+{
+ *r = *x;
+ r->high &= 0x7FFF;
+}
+
+LOCALPROC myfp_Neg(myfpr *r, myfpr *x)
+{
+ *r = *x;
+ r->high ^= 0x8000;
+}
+
+LOCALPROC myfp_TwoToX(myfpr *r, myfpr *x)
+{
+ floatx80 t2;
+ floatx80 t3;
+ floatx80 t4;
+ floatx80 t5;
+ myfp_floor(&t2, x);
+ t3 = floatx80_sub(*x, t2);
+ t4 = f2xm1(t3);
+ t5 = floatx80_add(t4, floatx80_one);
+ *r = floatx80_scale(t5, t2);
+}
+
+LOCALPROC myfp_TenToX(myfpr *r, myfpr *x)
+{
+ floatx80 t1;
+ const floatx80 t = /* 1.0 / log(2.0) */
+ packFloatx80m(0, 0x3fff, LIT64(0xb8aa3b295c17f0bc));
+ const floatx80 t2 = /* log(10.0) */
+ packFloatx80m(0, 0x4000, LIT64(0x935d8dddaaa8ac17));
+ t1 = floatx80_mul(floatx80_mul(*x, t), t2);
+ myfp_TwoToX(r, &t1);
+}
+
+LOCALPROC myfp_EToX(myfpr *r, myfpr *x)
+{
+ floatx80 t1;
+ const floatx80 t = /* 1.0 / log(2.0) */
+ packFloatx80m(0, 0x3fff, LIT64(0xb8aa3b295c17f0bc));
+ t1 = floatx80_mul(*x, t);
+ myfp_TwoToX(r, &t1);
+}
+
+LOCALPROC myfp_EToXM1(myfpr *r, myfpr *x)
+{
+ floatx80 t1;
+ floatx80 t2;
+ floatx80 t3;
+ floatx80 t4;
+ floatx80 t5;
+ floatx80 t6;
+ const floatx80 t = /* 1.0 / log(2.0) */
+ packFloatx80m(0, 0x3fff, LIT64(0xb8aa3b295c17f0bc));
+ t1 = floatx80_mul(*x, t);
+ myfp_floor(&t2, &t1);
+ t3 = floatx80_sub(t1, t2);
+ t4 = f2xm1(t3);
+ if (myfp_IsZero(&t2)) {
+ *r = t4;
+ } else {
+ t5 = floatx80_add(t4, floatx80_one);
+ t6 = floatx80_scale(t5, t2);
+ *r = floatx80_sub(t6, floatx80_one);
+ }
+}
+
+LOCALPROC myfp_Log2(myfpr *r, myfpr *x)
+{
+ *r = fyl2x(*x, floatx80_one);
+}
+
+LOCALPROC myfp_LogN(myfpr *r, myfpr *x)
+{
+ const floatx80 t = /* log(2.0) */
+ packFloatx80m(0, 0x3ffe, LIT64(0xb17217f7d1cf79ac));
+ *r = fyl2x(*x, t);
+}
+
+LOCALPROC myfp_Log10(myfpr *r, myfpr *x)
+{
+ const floatx80 t = /* log10(2.0) = ln(2) / ln(10), unknown accuracy */
+ packFloatx80m(0, 0x3ffd, LIT64(0x9a209a84fbcff798));
+ *r = fyl2x(*x, t);
+}
+
+LOCALPROC myfp_LogNP1(myfpr *r, myfpr *x)
+{
+ const floatx80 t = /* log(2.0) */
+ packFloatx80m(0, 0x3ffe, LIT64(0xb17217f7d1cf79ac));
+ *r = fyl2xp1(*x, t);
+}
+
+LOCALPROC myfp_Sin(myfpr *r, myfpr *x)
+{
+ (void) fsincos(*x, r, 0);
+}
+
+LOCALPROC myfp_Cos(myfpr *r, myfpr *x)
+{
+ (void) fsincos(*x, 0, r);
+}
+
+LOCALPROC myfp_Tan(myfpr *r, myfpr *x)
+{
+ *r = *x;
+ (void) ftan(r);
+}
+
+LOCALPROC myfp_ATan(myfpr *r, myfpr *x)
+{
+ *r = fpatan(floatx80_one, *x);
+}
+
+LOCALPROC myfp_ASin(myfpr *r, myfpr *x)
+{
+ floatx80 x2 = floatx80_mul(*x, *x);
+ floatx80 mx2 = floatx80_sub(floatx80_one, x2);
+ floatx80 cx = floatx80_sqrt(mx2);
+
+ *r = fpatan(cx, *x);
+}
+
+LOCALPROC myfp_ACos(myfpr *r, myfpr *x)
+{
+ floatx80 x2 = floatx80_mul(*x, *x);
+ floatx80 mx2 = floatx80_sub(floatx80_one, x2);
+ floatx80 cx = floatx80_sqrt(mx2);
+
+ *r = fpatan(*x, cx);
+}
+
+static const floatx80 floatx80_zero =
+ packFloatx80m(0, 0x0000, LIT64(0x0000000000000000));
+
+static const floatx80 floatx80_Two =
+ packFloatx80m(0, 0x4000, LIT64(0x8000000000000000));
+
+static const floatx80 floatx80_Ten =
+ packFloatx80m(0, 0x4002, LIT64(0xa000000000000000));
+
+LOCALPROC myfp_Sinh(myfpr *r, myfpr *x)
+{
+ myfpr ex;
+ myfpr nx;
+ myfpr enx;
+ myfpr t1;
+
+ myfp_EToX(&ex, x);
+ myfp_Neg(&nx, x);
+ myfp_EToX(&enx, &nx);
+ myfp_Sub(&t1, &ex, &enx);
+ myfp_Div(r, &t1, &floatx80_Two);
+}
+
+LOCALPROC myfp_Cosh(myfpr *r, myfpr *x)
+{
+ myfpr ex;
+ myfpr nx;
+ myfpr enx;
+ myfpr t1;
+
+ myfp_EToX(&ex, x);
+ myfp_Neg(&nx, x);
+ myfp_EToX(&enx, &nx);
+ myfp_Add(&t1, &ex, &enx);
+ myfp_Div(r, &t1, &floatx80_Two);
+}
+
+LOCALPROC myfp_Tanh(myfpr *r, myfpr *x)
+{
+ myfpr x2;
+ myfpr ex2;
+ myfpr ex2m1;
+ myfpr ex2p1;
+
+ myfp_Mul(&x2, x, &floatx80_Two);
+ myfp_EToX(&ex2, &x2);
+ myfp_Sub(&ex2m1, &ex2, &floatx80_one);
+ myfp_Add(&ex2p1, &ex2, &floatx80_one);
+ myfp_Div(r, &ex2m1, &ex2p1);
+}
+
+LOCALPROC myfp_ATanh(myfpr *r, myfpr *x)
+{
+ myfpr onepx;
+ myfpr onemx;
+ myfpr dv;
+ myfpr ldv;
+
+ myfp_Add(&onepx, x, &floatx80_one);
+ myfp_Sub(&onemx, x, &floatx80_one);
+ myfp_Div(&dv, &onepx, &onemx);
+ myfp_LogN(&ldv, &dv);
+ myfp_Div(r, &ldv, &floatx80_Two);
+}
+
+LOCALPROC myfp_SinCos(myfpr *r_sin, myfpr *r_cos, myfpr *source)
+{
+ (void) fsincos(*source, r_sin, r_cos);
+}
+
+LOCALFUNC blnr myfp_getCR(myfpr *r, ui4b opmode)
+{
+ switch (opmode) {
+ case 0x00:
+ *r = floatx80_pi; /* M_PI */
+ break;
+ case 0x0B:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x3ffd, LIT64(0x9a209a84fbcff798));
+ *r = t; /* log10(2.0) = ln(2) / ln(10), unknown accuracy */
+ }
+ break;
+ case 0x0C:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x4000, LIT64(0xadf85458a2bb4a9b));
+ *r = t; /* exp(1.0), unknown accuracy */
+ }
+ break;
+ case 0x0D:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x3fff, LIT64(0xb8aa3b295c17f0bc));
+ *r = t; /* 1.0 / log(2.0) */
+ }
+ break;
+ case 0x0E:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x3ffd, LIT64(0xde5bd8a937287195));
+ *r = t; /* 1.0 / log(10.0), unknown accuracy */
+ }
+ break;
+ case 0x0F:
+ *r = floatx80_zero; /* 0.0 */
+ break;
+ case 0x30:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x3ffe, LIT64(0xb17217f7d1cf79ac));
+ *r = t; /* log(2.0) */
+ }
+ break;
+ case 0x31:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x4000, LIT64(0x935d8dddaaa8ac17));
+ *r = t; /* log(10.0) */
+ }
+ break;
+ case 0x32:
+ *r = floatx80_one; /* 1.0 */
+ break;
+ case 0x33:
+ *r = floatx80_Ten; /* 10.0 */
+ break;
+ case 0x34:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x4005, LIT64(0xc800000000000000));
+ *r = t; /* 100.0 */
+ }
+ break;
+ case 0x35:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x400c, LIT64(0x9c40000000000000));
+ *r = t; /* 10000.0 */
+ }
+ break;
+ case 0x36:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x4019, LIT64(0xbebc200000000000));
+ *r = t; /* 1.0e8 */
+ }
+ break;
+ case 0x37:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x4034, LIT64(0x8e1bc9bf04000000));
+ *r = t; /* 1.0e16 */
+ }
+ break;
+ case 0x38:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x4069, LIT64(0x9dc5ada82b70b59e));
+ *r = t; /* 1.0e32 */
+ }
+ break;
+ case 0x39:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x40d3, LIT64(0xc2781f49ffcfa6d5));
+ *r = t; /* 1.0e64 */
+ }
+ break;
+ case 0x3A:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x41a8, LIT64(0x93ba47c980e98ce0));
+ *r = t; /* 1.0e128 */
+ }
+ break;
+ case 0x3B:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x4351, LIT64(0xaa7eebfb9df9de8e));
+ *r = t; /* 1.0e256 */
+ }
+ break;
+ case 0x3C:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x46a3, LIT64(0xe319a0aea60e91c7));
+ *r = t; /* 1.0e512 */
+ }
+ break;
+ case 0x3D:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x4d48, LIT64(0xc976758681750c17));
+ *r = t; /* 1.0e1024 */
+ }
+ break;
+ case 0x3E:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x5a92, LIT64(0x9e8b3b5dc53d5de5));
+ *r = t; /* 1.0e2048 */
+ }
+ break;
+ case 0x3F:
+ {
+ const floatx80 t =
+ packFloatx80m(0, 0x7525, LIT64(0xc46052028a20979b));
+ *r = t; /* 1.0e4096 */
+ }
+ break;
+ default:
+ return falseblnr;
+ }
+ return trueblnr;
+}
+
+/* Floating point control register */
+
+LOCALPROC myfp_SetFPCR(ui5r v)
+{
+ switch ((v >> 4) & 0x03) {
+ case 0:
+ float_rounding_mode = float_round_nearest_even;
+ break;
+ case 1:
+ float_rounding_mode = float_round_to_zero;
+ break;
+ case 2:
+ float_rounding_mode = float_round_down;
+ break;
+ case 3:
+ float_rounding_mode = float_round_up;
+ break;
+ }
+ switch ((v >> 6) & 0x03) {
+ case 0:
+ floatx80_rounding_precision = 80;
+ break;
+ case 1:
+ floatx80_rounding_precision = 32;
+ break;
+ case 2:
+ floatx80_rounding_precision = 64;
+ break;
+ case 3:
+ ReportAbnormalID(0x0201,
+ "Bad rounding precision in myfp_SetFPCR");
+ floatx80_rounding_precision = 80;
+ break;
+ }
+ if (0 != (v & 0xF)) {
+ ReportAbnormalID(0x0202,
+ "Reserved bits not zero in myfp_SetFPCR");
+ }
+}
+
+LOCALFUNC ui5r myfp_GetFPCR(void)
+{
+ ui5r v = 0;
+
+ switch (float_rounding_mode) {
+ case float_round_nearest_even:
+ /* v |= (0 << 4); */
+ break;
+ case float_round_to_zero:
+ v |= (1 << 4);
+ break;
+ case float_round_down:
+ v |= (2 << 4);
+ break;
+ case float_round_up:
+ v |= (3 << 4);
+ break;
+ }
+
+ if (80 == floatx80_rounding_precision) {
+ /* v |= (0 << 6); */
+ } else if (32 == floatx80_rounding_precision) {
+ v |= (1 << 6);
+ } else if (64 == floatx80_rounding_precision) {
+ v |= (2 << 6);
+ } else {
+ ReportAbnormalID(0x0203,
+ "Bad rounding precision in myfp_GetFPCR");
+ }
+
+ return v;
+}
+
+LOCALVAR struct myfp_envStruct
+{
+ ui5r FPSR; /* Floating point status register */
+} myfp_env;
+
+LOCALPROC myfp_SetFPSR(ui5r v)
+{
+ myfp_env.FPSR = v;
+}
+
+LOCALFUNC ui5r myfp_GetFPSR(void)
+{
+ return myfp_env.FPSR;
+}
+
+LOCALFUNC ui3r myfp_GetConditionCodeByte(void)
+{
+ return (myfp_env.FPSR >> 24) & 0x0F;
+}
+
+LOCALPROC myfp_SetConditionCodeByte(ui3r v)
+{
+ myfp_env.FPSR = ((myfp_env.FPSR & 0x00FFFFFF)
+ | (v << 24));
+}
+
+LOCALPROC myfp_SetConditionCodeByteFromResult(myfpr *result)
+{
+ /* Set condition codes here based on result */
+
+ int c_nan = myfp_IsNan(result) ? 1 : 0;
+ int c_inf = myfp_IsInf(result) ? 1 : 0;
+ int c_zero = myfp_IsZero(result) ? 1 : 0;
+ int c_neg = myfp_IsNeg(result) ? 1 : 0;
+
+ myfp_SetConditionCodeByte(c_nan
+ | (c_inf << 1)
+ | (c_zero << 2)
+ | (c_neg << 3));
+}
--- /dev/null
+++ b/src/GLOBGLUE.c
@@ -1,0 +1,1762 @@
+/*
+ GLOBGLUE.c
+
+ Copyright (C) 2003 Bernd Schmidt, Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ GLOBal GLUE (or GLOB of GLUE)
+
+ Holds the program together.
+
+ Some code here adapted from "custom.c" in vMac by Philip Cummins,
+ in turn descended from code in the Un*x Amiga Emulator by
+ Bernd Schmidt.
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+
+#include "MYOSGLUE.h"
+#include "ENDIANAC.h"
+#include "EMCONFIG.h"
+#endif
+
+#include "GLOBGLUE.h"
+
+/*
+ ReportAbnormalID unused 0x111D - 0x11FF
+*/
+
+/*
+ ReportAbnormalID ranges unused 0x12xx - 0xFFxx
+*/
+
+IMPORTPROC m68k_reset(void);
+IMPORTPROC IWM_Reset(void);
+IMPORTPROC SCC_Reset(void);
+IMPORTPROC SCSI_Reset(void);
+IMPORTPROC VIA1_Reset(void);
+#if EmVIA2
+IMPORTPROC VIA2_Reset(void);
+#endif
+IMPORTPROC Sony_Reset(void);
+
+IMPORTPROC ExtnDisk_Access(CPTR p);
+IMPORTPROC ExtnSony_Access(CPTR p);
+#if EmVidCard
+IMPORTPROC ExtnVideo_Access(CPTR p);
+#endif
+
+IMPORTPROC Sony_SetQuitOnEject(void);
+
+IMPORTPROC m68k_IPLchangeNtfy(void);
+IMPORTPROC MINEM68K_Init(
+ ui3b *fIPL);
+
+IMPORTFUNC si5r GetCyclesRemaining(void);
+IMPORTPROC SetCyclesRemaining(si5r n);
+
+IMPORTPROC SetHeadATTel(ATTep p);
+IMPORTFUNC ATTep FindATTel(CPTR addr);
+
+IMPORTFUNC ui5b SCSI_Access(ui5b Data, blnr WriteMem, CPTR addr);
+IMPORTFUNC ui5b SCC_Access(ui5b Data, blnr WriteMem, CPTR addr);
+IMPORTFUNC ui5b IWM_Access(ui5b Data, blnr WriteMem, CPTR addr);
+IMPORTFUNC ui5b VIA1_Access(ui5b Data, blnr WriteMem, CPTR addr);
+#if EmVIA2
+IMPORTFUNC ui5b VIA2_Access(ui5b Data, blnr WriteMem, CPTR addr);
+#endif
+#if EmASC
+IMPORTFUNC ui5b ASC_Access(ui5b Data, blnr WriteMem, CPTR addr);
+#endif
+
+IMPORTFUNC ui3r get_vm_byte(CPTR addr);
+IMPORTFUNC ui4r get_vm_word(CPTR addr);
+IMPORTFUNC ui5r get_vm_long(CPTR addr);
+
+IMPORTPROC put_vm_byte(CPTR addr, ui3r b);
+IMPORTPROC put_vm_word(CPTR addr, ui4r w);
+IMPORTPROC put_vm_long(CPTR addr, ui5r l);
+
+GLOBALVAR ui5r my_disk_icon_addr;
+
+GLOBALPROC customreset(void)
+{
+ IWM_Reset();
+ SCC_Reset();
+ SCSI_Reset();
+ VIA1_Reset();
+#if EmVIA2
+ VIA2_Reset();
+#endif
+ Sony_Reset();
+ Extn_Reset();
+#if CurEmMd <= kEmMd_Plus
+ WantMacReset = trueblnr;
+ /*
+ kludge, code in Finder appears
+ to do RESET and not expect
+ to come back. Maybe asserting
+ the RESET somehow causes
+ other hardware compenents to
+ later reset the 68000.
+ */
+#endif
+}
+
+GLOBALVAR ui3p RAM = nullpr;
+
+#if EmVidCard
+GLOBALVAR ui3p VidROM = nullpr;
+#endif
+
+#if IncludeVidMem
+GLOBALVAR ui3p VidMem = nullpr;
+#endif
+
+GLOBALVAR ui3b Wires[kNumWires];
+
+
+#if WantDisasm
+IMPORTPROC m68k_WantDisasmContext(void);
+#endif
+
+#if WantDisasm
+GLOBALPROC dbglog_StartLine(void)
+{
+ m68k_WantDisasmContext();
+ dbglog_writeCStr(" ");
+}
+#endif
+
+#if dbglog_HAVE
+GLOBALPROC dbglog_WriteMemArrow(blnr WriteMem)
+{
+ if (WriteMem) {
+ dbglog_writeCStr(" <- ");
+ } else {
+ dbglog_writeCStr(" -> ");
+ }
+}
+#endif
+
+#if dbglog_HAVE
+GLOBALPROC dbglog_AddrAccess(char *s, ui5r Data,
+ blnr WriteMem, ui5r addr)
+{
+ dbglog_StartLine();
+ dbglog_writeCStr(s);
+ dbglog_writeCStr("[");
+ dbglog_writeHex(addr);
+ dbglog_writeCStr("]");
+ dbglog_WriteMemArrow(WriteMem);
+ dbglog_writeHex(Data);
+ dbglog_writeReturn();
+}
+#endif
+
+#if dbglog_HAVE
+GLOBALPROC dbglog_Access(char *s, ui5r Data, blnr WriteMem)
+{
+ dbglog_StartLine();
+ dbglog_writeCStr(s);
+ dbglog_WriteMemArrow(WriteMem);
+ dbglog_writeHex(Data);
+ dbglog_writeReturn();
+}
+#endif
+
+#if dbglog_HAVE
+GLOBALPROC dbglog_WriteNote(char *s)
+{
+ dbglog_StartLine();
+ dbglog_writeCStr(s);
+ dbglog_writeReturn();
+}
+#endif
+
+#if dbglog_HAVE
+GLOBALPROC dbglog_WriteSetBool(char *s, blnr v)
+{
+ dbglog_StartLine();
+ dbglog_writeCStr(s);
+ dbglog_writeCStr(" <- ");
+ if (v) {
+ dbglog_writeCStr("1");
+ } else {
+ dbglog_writeCStr("0");
+ }
+ dbglog_writeReturn();
+}
+#endif
+
+#if WantAbnormalReports
+LOCALVAR blnr GotOneAbnormal = falseblnr;
+#endif
+
+#ifndef ReportAbnormalInterrupt
+#define ReportAbnormalInterrupt 0
+#endif
+
+#if WantAbnormalReports
+GLOBALPROC DoReportAbnormalID(ui4r id
+#if dbglog_HAVE
+ , char *s
+#endif
+ )
+{
+#if dbglog_HAVE
+ dbglog_StartLine();
+ dbglog_writeCStr("*** abnormal : ");
+ dbglog_writeCStr(s);
+ dbglog_writeReturn();
+#endif
+
+ if (! GotOneAbnormal) {
+ WarnMsgAbnormalID(id);
+#if ReportAbnormalInterrupt
+ SetInterruptButton(trueblnr);
+#endif
+ GotOneAbnormal = trueblnr;
+ }
+}
+#endif
+
+/* map of address space */
+
+#define kRAM_Base 0x00000000 /* when overlay off */
+#if (CurEmMd == kEmMd_PB100)
+#define kRAM_ln2Spc 23
+#elif (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+#define kRAM_ln2Spc 23
+#else
+#define kRAM_ln2Spc 22
+#endif
+
+#if IncludeVidMem
+#if CurEmMd == kEmMd_PB100
+#define kVidMem_Base 0x00FA0000
+#define kVidMem_ln2Spc 16
+#else
+#define kVidMem_Base 0x00540000
+#define kVidMem_ln2Spc 18
+#endif
+#endif
+
+#if CurEmMd == kEmMd_PB100
+#define kSCSI_Block_Base 0x00F90000
+#define kSCSI_ln2Spc 16
+#else
+#define kSCSI_Block_Base 0x00580000
+#define kSCSI_ln2Spc 19
+#endif
+
+#define kRAM_Overlay_Base 0x00600000 /* when overlay on */
+#define kRAM_Overlay_Top 0x00800000
+
+#if CurEmMd == kEmMd_PB100
+#define kSCCRd_Block_Base 0x00FD0000
+#define kSCC_ln2Spc 16
+#else
+#define kSCCRd_Block_Base 0x00800000
+#define kSCC_ln2Spc 22
+#endif
+
+#if CurEmMd != kEmMd_PB100
+#define kSCCWr_Block_Base 0x00A00000
+#define kSCCWr_Block_Top 0x00C00000
+#endif
+
+#if CurEmMd == kEmMd_PB100
+#define kIWM_Block_Base 0x00F60000
+#define kIWM_ln2Spc 16
+#else
+#define kIWM_Block_Base 0x00C00000
+#define kIWM_ln2Spc 21
+#endif
+
+#if CurEmMd == kEmMd_PB100
+#define kVIA1_Block_Base 0x00F70000
+#define kVIA1_ln2Spc 16
+#else
+#define kVIA1_Block_Base 0x00E80000
+#define kVIA1_ln2Spc 19
+#endif
+
+#if CurEmMd == kEmMd_PB100
+#define kASC_Block_Base 0x00FB0000
+#define kASC_ln2Spc 16
+#endif
+#define kASC_Mask 0x00000FFF
+
+
+#if IncludeExtnPbufs
+LOCALFUNC tMacErr PbufTransferVM(CPTR Buffera,
+ tPbuf i, ui5r offset, ui5r count, blnr IsWrite)
+{
+ tMacErr result;
+ ui5b contig;
+ ui3p Buffer;
+
+label_1:
+ if (0 == count) {
+ result = mnvm_noErr;
+ } else {
+ Buffer = get_real_address0(count, ! IsWrite, Buffera, &contig);
+ if (0 == contig) {
+ result = mnvm_miscErr;
+ } else {
+ PbufTransfer(Buffer, i, offset, contig, IsWrite);
+ offset += contig;
+ Buffera += contig;
+ count -= contig;
+ goto label_1;
+ }
+ }
+
+ return result;
+}
+#endif
+
+/* extension mechanism */
+
+#if IncludeExtnPbufs
+#define kCmndPbufFeatures 1
+#define kCmndPbufNew 2
+#define kCmndPbufDispose 3
+#define kCmndPbufGetSize 4
+#define kCmndPbufTransfer 5
+#endif
+
+#if IncludeExtnPbufs
+LOCALPROC ExtnParamBuffers_Access(CPTR p)
+{
+ tMacErr result = mnvm_controlErr;
+
+ switch (get_vm_word(p + ExtnDat_commnd)) {
+ case kCmndVersion:
+ put_vm_word(p + ExtnDat_version, 1);
+ result = mnvm_noErr;
+ break;
+ case kCmndPbufFeatures:
+ put_vm_long(p + ExtnDat_params + 0, 0);
+ result = mnvm_noErr;
+ break;
+ case kCmndPbufNew:
+ {
+ tPbuf Pbuf_No;
+ ui5b count = get_vm_long(p + ExtnDat_params + 4);
+ /* reserved word at offset 2, should be zero */
+ result = PbufNew(count, &Pbuf_No);
+ put_vm_word(p + ExtnDat_params + 0, Pbuf_No);
+ }
+ break;
+ case kCmndPbufDispose:
+ {
+ tPbuf Pbuf_No = get_vm_word(p + ExtnDat_params + 0);
+ /* reserved word at offset 2, should be zero */
+ result = CheckPbuf(Pbuf_No);
+ if (mnvm_noErr == result) {
+ PbufDispose(Pbuf_No);
+ }
+ }
+ break;
+ case kCmndPbufGetSize:
+ {
+ ui5r Count;
+ tPbuf Pbuf_No = get_vm_word(p + ExtnDat_params + 0);
+ /* reserved word at offset 2, should be zero */
+
+ result = PbufGetSize(Pbuf_No, &Count);
+ if (mnvm_noErr == result) {
+ put_vm_long(p + ExtnDat_params + 4, Count);
+ }
+ }
+ break;
+ case kCmndPbufTransfer:
+ {
+ ui5r PbufCount;
+ tPbuf Pbuf_No = get_vm_word(p + ExtnDat_params + 0);
+ /* reserved word at offset 2, should be zero */
+ ui5r offset = get_vm_long(p + ExtnDat_params + 4);
+ ui5r count = get_vm_long(p + ExtnDat_params + 8);
+ CPTR Buffera = get_vm_long(p + ExtnDat_params + 12);
+ blnr IsWrite =
+ (get_vm_word(p + ExtnDat_params + 16) != 0);
+ result = PbufGetSize(Pbuf_No, &PbufCount);
+ if (mnvm_noErr == result) {
+ ui5r endoff = offset + count;
+ if ((endoff < offset) /* overflow */
+ || (endoff > PbufCount))
+ {
+ result = mnvm_eofErr;
+ } else {
+ result = PbufTransferVM(Buffera,
+ Pbuf_No, offset, count, IsWrite);
+ }
+ }
+ }
+ break;
+ }
+
+ put_vm_word(p + ExtnDat_result, result);
+}
+#endif
+
+#if IncludeExtnHostTextClipExchange
+#define kCmndHTCEFeatures 1
+#define kCmndHTCEExport 2
+#define kCmndHTCEImport 3
+#endif
+
+#if IncludeExtnHostTextClipExchange
+LOCALPROC ExtnHostTextClipExchange_Access(CPTR p)
+{
+ tMacErr result = mnvm_controlErr;
+
+ switch (get_vm_word(p + ExtnDat_commnd)) {
+ case kCmndVersion:
+ put_vm_word(p + ExtnDat_version, 1);
+ result = mnvm_noErr;
+ break;
+ case kCmndHTCEFeatures:
+ put_vm_long(p + ExtnDat_params + 0, 0);
+ result = mnvm_noErr;
+ break;
+ case kCmndHTCEExport:
+ {
+ tPbuf Pbuf_No = get_vm_word(p + ExtnDat_params + 0);
+
+ result = CheckPbuf(Pbuf_No);
+ if (mnvm_noErr == result) {
+ result = HTCEexport(Pbuf_No);
+ }
+ }
+ break;
+ case kCmndHTCEImport:
+ {
+ tPbuf Pbuf_No;
+ result = HTCEimport(&Pbuf_No);
+ put_vm_word(p + ExtnDat_params + 0, Pbuf_No);
+ }
+ break;
+ }
+
+ put_vm_word(p + ExtnDat_result, result);
+}
+#endif
+
+#define kFindExtnExtension 0x64E1F58A
+#define kDiskDriverExtension 0x4C9219E6
+#if IncludeExtnPbufs
+#define kHostParamBuffersExtension 0x314C87BF
+#endif
+#if IncludeExtnHostTextClipExchange
+#define kHostClipExchangeExtension 0x27B130CA
+#endif
+
+#define kCmndFindExtnFind 1
+#define kCmndFindExtnId2Code 2
+#define kCmndFindExtnCount 3
+
+#define kParamFindExtnTheExtn 8
+#define kParamFindExtnTheId 12
+
+LOCALPROC ExtnFind_Access(CPTR p)
+{
+ tMacErr result = mnvm_controlErr;
+
+ switch (get_vm_word(p + ExtnDat_commnd)) {
+ case kCmndVersion:
+ put_vm_word(p + ExtnDat_version, 1);
+ result = mnvm_noErr;
+ break;
+ case kCmndFindExtnFind:
+ {
+ ui5b extn = get_vm_long(p + kParamFindExtnTheExtn);
+
+ if (extn == kDiskDriverExtension) {
+ put_vm_word(p + kParamFindExtnTheId, kExtnDisk);
+ result = mnvm_noErr;
+ } else
+#if IncludeExtnPbufs
+ if (extn == kHostParamBuffersExtension) {
+ put_vm_word(p + kParamFindExtnTheId,
+ kExtnParamBuffers);
+ result = mnvm_noErr;
+ } else
+#endif
+#if IncludeExtnHostTextClipExchange
+ if (extn == kHostClipExchangeExtension) {
+ put_vm_word(p + kParamFindExtnTheId,
+ kExtnHostTextClipExchange);
+ result = mnvm_noErr;
+ } else
+#endif
+ if (extn == kFindExtnExtension) {
+ put_vm_word(p + kParamFindExtnTheId,
+ kExtnFindExtn);
+ result = mnvm_noErr;
+ } else
+ {
+ /* not found */
+ }
+ }
+ break;
+ case kCmndFindExtnId2Code:
+ {
+ ui4r extn = get_vm_word(p + kParamFindExtnTheId);
+
+ if (extn == kExtnDisk) {
+ put_vm_long(p + kParamFindExtnTheExtn,
+ kDiskDriverExtension);
+ result = mnvm_noErr;
+ } else
+#if IncludeExtnPbufs
+ if (extn == kExtnParamBuffers) {
+ put_vm_long(p + kParamFindExtnTheExtn,
+ kHostParamBuffersExtension);
+ result = mnvm_noErr;
+ } else
+#endif
+#if IncludeExtnHostTextClipExchange
+ if (extn == kExtnHostTextClipExchange) {
+ put_vm_long(p + kParamFindExtnTheExtn,
+ kHostClipExchangeExtension);
+ result = mnvm_noErr;
+ } else
+#endif
+ if (extn == kExtnFindExtn) {
+ put_vm_long(p + kParamFindExtnTheExtn,
+ kFindExtnExtension);
+ result = mnvm_noErr;
+ } else
+ {
+ /* not found */
+ }
+ }
+ break;
+ case kCmndFindExtnCount:
+ put_vm_word(p + kParamFindExtnTheId, kNumExtns);
+ result = mnvm_noErr;
+ break;
+ }
+
+ put_vm_word(p + ExtnDat_result, result);
+}
+
+#define kDSK_Params_Hi 0
+#define kDSK_Params_Lo 1
+#define kDSK_QuitOnEject 3 /* obsolete */
+
+LOCALVAR ui4b ParamAddrHi;
+
+LOCALPROC Extn_Access(ui5b Data, CPTR addr)
+{
+ switch (addr) {
+ case kDSK_Params_Hi:
+ ParamAddrHi = Data;
+ break;
+ case kDSK_Params_Lo:
+ {
+ CPTR p = ParamAddrHi << 16 | Data;
+
+ ParamAddrHi = (ui4b) - 1;
+ if (kcom_callcheck == get_vm_word(p + ExtnDat_checkval))
+ {
+ put_vm_word(p + ExtnDat_checkval, 0);
+
+ switch (get_vm_word(p + ExtnDat_extension)) {
+ case kExtnFindExtn:
+ ExtnFind_Access(p);
+ break;
+#if EmVidCard
+ case kExtnVideo:
+ ExtnVideo_Access(p);
+ break;
+#endif
+#if IncludeExtnPbufs
+ case kExtnParamBuffers:
+ ExtnParamBuffers_Access(p);
+ break;
+#endif
+#if IncludeExtnHostTextClipExchange
+ case kExtnHostTextClipExchange:
+ ExtnHostTextClipExchange_Access(p);
+ break;
+#endif
+ case kExtnDisk:
+ ExtnDisk_Access(p);
+ break;
+ case kExtnSony:
+ ExtnSony_Access(p);
+ break;
+ default:
+ put_vm_word(p + ExtnDat_result,
+ mnvm_controlErr);
+ break;
+ }
+ }
+ }
+ break;
+ case kDSK_QuitOnEject:
+ /* obsolete, kept for compatibility */
+ Sony_SetQuitOnEject();
+ break;
+ }
+}
+
+GLOBALPROC Extn_Reset(void)
+{
+ ParamAddrHi = (ui4b) - 1;
+}
+
+/* implementation of read/write for everything but RAM and ROM */
+
+#define kSCC_Mask 0x03
+
+#define kVIA1_Mask 0x00000F
+#if EmVIA2
+#define kVIA2_Mask 0x00000F
+#endif
+
+#define kIWM_Mask 0x00000F /* Allocated Memory Bandwidth for IWM */
+
+#if CurEmMd <= kEmMd_512Ke
+#define ROM_CmpZeroMask 0
+#elif CurEmMd <= kEmMd_Plus
+#if kROM_Size > 0x00020000
+#define ROM_CmpZeroMask 0 /* For hacks like Mac ROM-inator */
+#else
+#define ROM_CmpZeroMask 0x00020000
+#endif
+#elif CurEmMd <= kEmMd_PB100
+#define ROM_CmpZeroMask 0
+#elif CurEmMd <= kEmMd_IIx
+#define ROM_CmpZeroMask 0
+#else
+#error "ROM_CmpZeroMask not defined"
+#endif
+
+#define kROM_cmpmask (0x00F00000 | ROM_CmpZeroMask)
+
+#if CurEmMd <= kEmMd_512Ke
+#define Overlay_ROM_CmpZeroMask 0x00100000
+#elif CurEmMd <= kEmMd_Plus
+#define Overlay_ROM_CmpZeroMask 0x00020000
+#elif CurEmMd <= kEmMd_Classic
+#define Overlay_ROM_CmpZeroMask 0x00300000
+#elif CurEmMd <= kEmMd_PB100
+#define Overlay_ROM_CmpZeroMask 0
+#elif CurEmMd <= kEmMd_IIx
+#define Overlay_ROM_CmpZeroMask 0
+#else
+#error "Overlay_ROM_CmpZeroMask not defined"
+#endif
+
+enum {
+ kMMDV_VIA1,
+#if EmVIA2
+ kMMDV_VIA2,
+#endif
+ kMMDV_SCC,
+ kMMDV_Extn,
+#if EmASC
+ kMMDV_ASC,
+#endif
+ kMMDV_SCSI,
+ kMMDV_IWM,
+
+ kNumMMDVs
+};
+
+enum {
+#if CurEmMd >= kEmMd_SE
+ kMAN_OverlayOff,
+#endif
+
+ kNumMANs
+};
+
+
+LOCALVAR ATTer ATTListA[MaxATTListN];
+LOCALVAR ui4r LastATTel;
+
+
+LOCALPROC AddToATTList(ATTep p)
+{
+ ui4r NewLast = LastATTel + 1;
+ if (NewLast >= MaxATTListN) {
+ ReportAbnormalID(0x1101, "MaxATTListN not big enough");
+ } else {
+ ATTListA[LastATTel] = *p;
+ LastATTel = NewLast;
+ }
+}
+
+LOCALPROC InitATTList(void)
+{
+ LastATTel = 0;
+}
+
+LOCALPROC FinishATTList(void)
+{
+ {
+ /* add guard */
+ ATTer r;
+
+ r.cmpmask = 0;
+ r.cmpvalu = 0;
+ r.usemask = 0;
+ r.usebase = nullpr;
+ r.Access = 0;
+ AddToATTList(&r);
+ }
+
+ {
+ ui4r i = LastATTel;
+ ATTep p = &ATTListA[LastATTel];
+ ATTep h = nullpr;
+
+ while (0 != i) {
+ --i;
+ --p;
+ p->Next = h;
+ h = p;
+ }
+
+#if 0 /* verify list. not for final version */
+ {
+ ATTep q1;
+ ATTep q2;
+ for (q1 = h; nullpr != q1->Next; q1 = q1->Next) {
+ if ((q1->cmpvalu & ~ q1->cmpmask) != 0) {
+ ReportAbnormalID(0x1102, "ATTListA bad entry");
+ }
+ for (q2 = q1->Next; nullpr != q2->Next; q2 = q2->Next) {
+ ui5r common_mask = (q1->cmpmask) & (q2->cmpmask);
+ if ((q1->cmpvalu & common_mask) ==
+ (q2->cmpvalu & common_mask))
+ {
+ ReportAbnormalID(0x1103, "ATTListA Conflict");
+ }
+ }
+ }
+ }
+#endif
+
+ SetHeadATTel(h);
+ }
+}
+
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+LOCALPROC SetUp_RAM24(void)
+{
+ ATTer r;
+ ui5r bankbit = 0x00100000 << (((VIA2_iA7 << 1) | VIA2_iA6) << 1);
+
+#if kRAMa_Size == kRAMb_Size
+ if (kRAMa_Size == bankbit) {
+ /* properly set up balanced RAM */
+ r.cmpmask = 0x00FFFFFF & ~ ((1 << kRAM_ln2Spc) - 1);
+ r.cmpvalu = 0;
+ r.usemask = ((1 << kRAM_ln2Spc) - 1) & (kRAM_Size - 1);
+ r.usebase = RAM;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+ } else
+#endif
+ {
+ bankbit &= 0x00FFFFFF; /* if too large, always use RAMa */
+
+ if (0 != bankbit) {
+#if kRAMb_Size != 0
+ r.cmpmask = bankbit
+ | (0x00FFFFFF & ~ ((1 << kRAM_ln2Spc) - 1));
+ r.cmpvalu = bankbit;
+ r.usemask = ((1 << kRAM_ln2Spc) - 1) & (kRAMb_Size - 1);
+ r.usebase = kRAMa_Size + RAM;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+#endif
+ }
+
+ {
+ r.cmpmask = bankbit
+ | (0x00FFFFFF & ~ ((1 << kRAM_ln2Spc) - 1));
+ r.cmpvalu = 0;
+ r.usemask = ((1 << kRAM_ln2Spc) - 1) & (kRAMa_Size - 1);
+ r.usebase = RAM;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+ }
+ }
+}
+#endif
+
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+LOCALPROC SetUp_io(void)
+{
+ ATTer r;
+
+ if (Addr32) {
+ r.cmpmask = 0xFF01E000;
+ r.cmpvalu = 0x50000000;
+ } else {
+ r.cmpmask = 0x00F1E000;
+ r.cmpvalu = 0x00F00000;
+ }
+ r.usebase = nullpr;
+ r.Access = kATTA_mmdvmask;
+ r.MMDV = kMMDV_VIA1;
+ AddToATTList(&r);
+
+ if (Addr32) {
+ r.cmpmask = 0xFF01E000;
+ r.cmpvalu = 0x50000000 | 0x2000;
+ } else {
+ r.cmpmask = 0x00F1E000;
+ r.cmpvalu = 0x00F00000 | 0x2000;
+ }
+ r.usebase = nullpr;
+ r.Access = kATTA_mmdvmask;
+ r.MMDV = kMMDV_VIA2;
+ AddToATTList(&r);
+
+ if (Addr32) {
+ r.cmpmask = 0xFF01E000;
+ r.cmpvalu = 0x50000000 | 0x4000;
+ } else {
+ r.cmpmask = 0x00F1E000;
+ r.cmpvalu = 0x00F00000 | 0x4000;
+ }
+ r.usebase = nullpr;
+ r.Access = kATTA_mmdvmask;
+ r.MMDV = kMMDV_SCC;
+ AddToATTList(&r);
+
+ if (Addr32) {
+ r.cmpmask = 0xFF01E000;
+ r.cmpvalu = 0x50000000 | 0x0C000;
+ } else {
+ r.cmpmask = 0x00F1E000;
+ r.cmpvalu = 0x00F00000 | 0x0C000;
+ }
+ r.usebase = nullpr;
+ r.Access = kATTA_mmdvmask;
+ r.MMDV = kMMDV_Extn;
+ AddToATTList(&r);
+
+ if (Addr32) {
+ r.cmpmask = 0xFF01E000;
+ r.cmpvalu = 0x50000000 | 0x10000;
+ } else {
+ r.cmpmask = 0x00F1E000;
+ r.cmpvalu = 0x00F00000 | 0x10000;
+ }
+ r.usebase = nullpr;
+ r.Access = kATTA_mmdvmask;
+ r.MMDV = kMMDV_SCSI;
+ AddToATTList(&r);
+
+ if (Addr32) {
+ r.cmpmask = 0xFF01E000;
+ r.cmpvalu = 0x50000000 | 0x14000;
+ } else {
+ r.cmpmask = 0x00F1E000;
+ r.cmpvalu = 0x00F00000 | 0x14000;
+ }
+ r.usebase = nullpr;
+ r.Access = kATTA_mmdvmask;
+ r.MMDV = kMMDV_ASC;
+ AddToATTList(&r);
+
+ if (Addr32) {
+ r.cmpmask = 0xFF01E000;
+ r.cmpvalu = 0x50000000 | 0x16000;
+ } else {
+ r.cmpmask = 0x00F1E000;
+ r.cmpvalu = 0x00F00000 | 0x16000;
+ }
+ r.usebase = nullpr;
+ r.Access = kATTA_mmdvmask;
+ r.MMDV = kMMDV_IWM;
+ AddToATTList(&r);
+
+#if 0
+ case 14:
+ /*
+ fail, nothing supposed to be here,
+ but rom accesses it anyway
+ */
+ {
+ ui5r addr2 = addr & 0x1FFFF;
+
+ if ((addr2 != 0x1DA00) && (addr2 != 0x1DC00)) {
+ ReportAbnormalID(0x1104, "another unknown access");
+ }
+ }
+ get_fail_realblock(p);
+ break;
+#endif
+}
+#endif
+
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+LOCALPROC SetUp_address24(void)
+{
+ ATTer r;
+
+#if 0
+ if (MemOverlay) {
+ ReportAbnormalID(0x1105, "Overlay with 24 bit addressing");
+ }
+#endif
+
+ if (MemOverlay) {
+ r.cmpmask = Overlay_ROM_CmpZeroMask |
+ (0x00FFFFFF & ~ ((1 << kRAM_ln2Spc) - 1));
+ r.cmpvalu = kRAM_Base;
+ r.usemask = kROM_Size - 1;
+ r.usebase = ROM;
+ r.Access = kATTA_readreadymask;
+ AddToATTList(&r);
+ } else {
+ SetUp_RAM24();
+ }
+
+ r.cmpmask = kROM_cmpmask;
+ r.cmpvalu = kROM_Base;
+ r.usemask = kROM_Size - 1;
+ r.usebase = ROM;
+ r.Access = kATTA_readreadymask;
+ AddToATTList(&r);
+
+ r.cmpmask = 0x00FFFFFF & ~ (0x100000 - 1);
+ r.cmpvalu = 0x900000;
+ r.usemask = (kVidMemRAM_Size - 1) & (0x100000 - 1);
+ r.usebase = VidMem;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+#if kVidMemRAM_Size >= 0x00200000
+ r.cmpmask = 0x00FFFFFF & ~ (0x100000 - 1);
+ r.cmpvalu = 0xA00000;
+ r.usemask = (0x100000 - 1);
+ r.usebase = VidMem + (1 << 20);
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+#endif
+#if kVidMemRAM_Size >= 0x00400000
+ r.cmpmask = 0x00FFFFFF & ~ (0x100000 - 1);
+ r.cmpvalu = 0xB00000;
+ r.usemask = (0x100000 - 1);
+ r.usebase = VidMem + (2 << 20);
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+ r.cmpmask = 0x00FFFFFF & ~ (0x100000 - 1);
+ r.cmpvalu = 0xC00000;
+ r.usemask = (0x100000 - 1);
+ r.usebase = VidMem + (3 << 20);
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+#endif
+
+ SetUp_io();
+}
+#endif
+
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+LOCALPROC SetUp_address32(void)
+{
+ ATTer r;
+
+ if (MemOverlay) {
+ r.cmpmask = ~ ((1 << 30) - 1);
+ r.cmpvalu = 0;
+ r.usemask = kROM_Size - 1;
+ r.usebase = ROM;
+ r.Access = kATTA_readreadymask;
+ AddToATTList(&r);
+ } else {
+ ui5r bankbit =
+ 0x00100000 << (((VIA2_iA7 << 1) | VIA2_iA6) << 1);
+#if kRAMa_Size == kRAMb_Size
+ if (kRAMa_Size == bankbit) {
+ /* properly set up balanced RAM */
+ r.cmpmask = ~ ((1 << 30) - 1);
+ r.cmpvalu = 0;
+ r.usemask = kRAM_Size - 1;
+ r.usebase = RAM;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+ } else
+#endif
+ {
+#if kRAMb_Size != 0
+ r.cmpmask = bankbit | ~ ((1 << 30) - 1);
+ r.cmpvalu = bankbit;
+ r.usemask = kRAMb_Size - 1;
+ r.usebase = kRAMa_Size + RAM;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+#endif
+
+ r.cmpmask = bankbit | ~ ((1 << 30) - 1);
+ r.cmpvalu = 0;
+ r.usemask = kRAMa_Size - 1;
+ r.usebase = RAM;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+ }
+ }
+
+ r.cmpmask = ~ ((1 << 28) - 1);
+ r.cmpvalu = 0x40000000;
+ r.usemask = kROM_Size - 1;
+ r.usebase = ROM;
+ r.Access = kATTA_readreadymask;
+ AddToATTList(&r);
+
+#if 0
+ /* haven't persuaded emulated computer to look here yet. */
+ /* NuBus super space */
+ r.cmpmask = ~ ((1 << 28) - 1);
+ r.cmpvalu = 0x90000000;
+ r.usemask = kVidMemRAM_Size - 1;
+ r.usebase = VidMem;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+#endif
+
+ /* Standard NuBus space */
+ r.cmpmask = ~ ((1 << 20) - 1);
+ r.cmpvalu = 0xF9F00000;
+ r.usemask = kVidROM_Size - 1;
+ r.usebase = VidROM;
+ r.Access = kATTA_readreadymask;
+ AddToATTList(&r);
+#if 0
+ r.cmpmask = ~ 0x007FFFFF;
+ r.cmpvalu = 0xF9000000;
+ r.usemask = 0x007FFFFF & (kVidMemRAM_Size - 1);
+ r.usebase = VidMem;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+#endif
+
+ r.cmpmask = ~ 0x000FFFFF;
+ r.cmpvalu = 0xF9900000;
+ r.usemask = 0x000FFFFF & (kVidMemRAM_Size - 1);
+ r.usebase = VidMem;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+/* kludge to allow more than 1M of Video Memory */
+#if kVidMemRAM_Size >= 0x00200000
+ r.cmpmask = ~ 0x000FFFFF;
+ r.cmpvalu = 0xF9A00000;
+ r.usemask = 0x000FFFFF & (kVidMemRAM_Size - 1);
+ r.usebase = VidMem + (1 << 20);
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+#endif
+#if kVidMemRAM_Size >= 0x00400000
+ r.cmpmask = ~ 0x000FFFFF;
+ r.cmpvalu = 0xF9B00000;
+ r.usemask = 0x000FFFFF & (kVidMemRAM_Size - 1);
+ r.usebase = VidMem + (2 << 20);
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+ r.cmpmask = ~ 0x000FFFFF;
+ r.cmpvalu = 0xF9C00000;
+ r.usemask = 0x000FFFFF & (kVidMemRAM_Size - 1);
+ r.usebase = VidMem + (3 << 20);
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+#endif
+
+ SetUp_io();
+
+#if 0
+ if ((addr >= 0x58000000) && (addr < 0x58000004)) {
+ /* test hardware. fail */
+ }
+#endif
+}
+#endif
+
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+LOCALPROC SetUp_address(void)
+{
+ if (Addr32) {
+ SetUp_address32();
+ } else {
+ SetUp_address24();
+ }
+}
+#endif
+
+/*
+ unlike in the real Mac Plus, Mini vMac
+ will allow misaligned memory access,
+ since it is easier to allow it than
+ it is to correctly simulate a bus error
+ and back out of the current instruction.
+*/
+
+#ifndef ln2mtb
+#define AddToATTListWithMTB AddToATTList
+#else
+LOCALPROC AddToATTListWithMTB(ATTep p)
+{
+ /*
+ Test of memory mapping system.
+ */
+ ATTer r;
+
+ r.Access = p->Access;
+ r.cmpmask = p->cmpmask | (1 << ln2mtb);
+ r.usemask = p->usemask & ~ (1 << ln2mtb);
+
+ r.cmpvalu = p->cmpvalu + (1 << ln2mtb);
+ r.usebase = p->usebase;
+ AddToATTList(&r);
+
+ r.cmpvalu = p->cmpvalu;
+ r.usebase = p->usebase + (1 << ln2mtb);
+ AddToATTList(&r);
+}
+#endif
+
+#if (CurEmMd != kEmMd_II) && (CurEmMd != kEmMd_IIx)
+LOCALPROC SetUp_RAM24(void)
+{
+ ATTer r;
+
+#if (0 == kRAMb_Size) || (kRAMa_Size == kRAMb_Size)
+ r.cmpmask = 0x00FFFFFF & ~ ((1 << kRAM_ln2Spc) - 1);
+ r.cmpvalu = kRAM_Base;
+ r.usemask = kRAM_Size - 1;
+ r.usebase = RAM;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTListWithMTB(&r);
+#else
+ /* unbalanced memory */
+
+#if 0 != (0x00FFFFFF & kRAMa_Size)
+ /* condition should always be true if configuration file right */
+ r.cmpmask = 0x00FFFFFF & (kRAMa_Size | ~ ((1 << kRAM_ln2Spc) - 1));
+ r.cmpvalu = kRAM_Base + kRAMa_Size;
+ r.usemask = kRAMb_Size - 1;
+ r.usebase = kRAMa_Size + RAM;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTListWithMTB(&r);
+#endif
+
+ r.cmpmask = 0x00FFFFFF & (kRAMa_Size | ~ ((1 << kRAM_ln2Spc) - 1));
+ r.cmpvalu = kRAM_Base;
+ r.usemask = kRAMa_Size - 1;
+ r.usebase = RAM;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTListWithMTB(&r);
+#endif
+}
+#endif
+
+#if (CurEmMd != kEmMd_II) && (CurEmMd != kEmMd_IIx)
+LOCALPROC SetUp_address(void)
+{
+ ATTer r;
+
+ if (MemOverlay) {
+ r.cmpmask = Overlay_ROM_CmpZeroMask |
+ (0x00FFFFFF & ~ ((1 << kRAM_ln2Spc) - 1));
+ r.cmpvalu = kRAM_Base;
+ r.usemask = kROM_Size - 1;
+ r.usebase = ROM;
+ r.Access = kATTA_readreadymask;
+ AddToATTListWithMTB(&r);
+ } else {
+ SetUp_RAM24();
+ }
+
+ r.cmpmask = kROM_cmpmask;
+ r.cmpvalu = kROM_Base;
+#if (CurEmMd >= kEmMd_SE)
+ if (MemOverlay) {
+ r.usebase = nullpr;
+ r.Access = kATTA_ntfymask;
+ r.Ntfy = kMAN_OverlayOff;
+ AddToATTList(&r);
+ } else
+#endif
+ {
+ r.usemask = kROM_Size - 1;
+ r.usebase = ROM;
+ r.Access = kATTA_readreadymask;
+ AddToATTListWithMTB(&r);
+ }
+
+ if (MemOverlay) {
+ r.cmpmask = 0x00E00000;
+ r.cmpvalu = kRAM_Overlay_Base;
+#if (0 == kRAMb_Size) || (kRAMa_Size == kRAMb_Size)
+ r.usemask = kRAM_Size - 1;
+ /* note that cmpmask and usemask overlap for 4M */
+ r.usebase = RAM;
+ r.Access = kATTA_readwritereadymask;
+#else
+ /* unbalanced memory */
+ r.usemask = kRAMb_Size - 1;
+ r.usebase = kRAMa_Size + RAM;
+ r.Access = kATTA_readwritereadymask;
+#endif
+ AddToATTListWithMTB(&r);
+ }
+
+#if IncludeVidMem
+ r.cmpmask = 0x00FFFFFF & ~ ((1 << kVidMem_ln2Spc) - 1);
+ r.cmpvalu = kVidMem_Base;
+ r.usemask = kVidMemRAM_Size - 1;
+ r.usebase = VidMem;
+ r.Access = kATTA_readwritereadymask;
+ AddToATTList(&r);
+#endif
+
+ r.cmpmask = 0x00FFFFFF & ~ ((1 << kVIA1_ln2Spc) - 1);
+ r.cmpvalu = kVIA1_Block_Base;
+ r.usebase = nullpr;
+ r.Access = kATTA_mmdvmask;
+ r.MMDV = kMMDV_VIA1;
+ AddToATTList(&r);
+
+ r.cmpmask = 0x00FFFFFF & ~ ((1 << kSCC_ln2Spc) - 1);
+ r.cmpvalu = kSCCRd_Block_Base;
+ r.usebase = nullpr;
+ r.Access = kATTA_mmdvmask;
+ r.MMDV = kMMDV_SCC;
+ AddToATTList(&r);
+
+ r.cmpmask = 0x00FFFFFF & ~ ((1 << kExtn_ln2Spc) - 1);
+ r.cmpvalu = kExtn_Block_Base;
+ r.usebase = nullpr;
+ r.Access = kATTA_mmdvmask;
+ r.MMDV = kMMDV_Extn;
+ AddToATTList(&r);
+
+#if CurEmMd == kEmMd_PB100
+ r.cmpmask = 0x00FFFFFF & ~ ((1 << kASC_ln2Spc) - 1);
+ r.cmpvalu = kASC_Block_Base;
+ r.usebase = nullpr;
+ r.Access = kATTA_mmdvmask;
+ r.MMDV = kMMDV_ASC;
+ AddToATTList(&r);
+#endif
+
+ r.cmpmask = 0x00FFFFFF & ~ ((1 << kSCSI_ln2Spc) - 1);
+ r.cmpvalu = kSCSI_Block_Base;
+ r.usebase = nullpr;
+ r.Access = kATTA_mmdvmask;
+ r.MMDV = kMMDV_SCSI;
+ AddToATTList(&r);
+
+ r.cmpmask = 0x00FFFFFF & ~ ((1 << kIWM_ln2Spc) - 1);
+ r.cmpvalu = kIWM_Block_Base;
+ r.usebase = nullpr;
+ r.Access = kATTA_mmdvmask;
+ r.MMDV = kMMDV_IWM;
+ AddToATTList(&r);
+}
+#endif
+
+LOCALPROC SetUpMemBanks(void)
+{
+ InitATTList();
+
+ SetUp_address();
+
+ FinishATTList();
+}
+
+#if 0
+LOCALPROC get_fail_realblock(ATTep p)
+{
+ p->cmpmask = 0;
+ p->cmpvalu = 0xFFFFFFFF;
+ p->usemask = 0;
+ p->usebase = nullpr;
+ p->Access = 0;
+}
+#endif
+
+GLOBALFUNC ui5b MMDV_Access(ATTep p, ui5b Data,
+ blnr WriteMem, blnr ByteSize, CPTR addr)
+{
+ switch (p->MMDV) {
+ case kMMDV_VIA1:
+ if (! ByteSize) {
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ if (WriteMem && (addr == 0xF40006)) {
+ /* for weirdness on shutdown in System 6 */
+#if 0
+ VIA1_Access((Data >> 8) & 0x00FF, WriteMem,
+ (addr >> 9) & kVIA1_Mask);
+ VIA1_Access((Data) & 0x00FF, WriteMem,
+ (addr >> 9) & kVIA1_Mask);
+#endif
+ } else
+#endif
+ {
+ ReportAbnormalID(0x1106, "access VIA1 word");
+ }
+ } else if ((addr & 1) != 0) {
+ ReportAbnormalID(0x1107, "access VIA1 odd");
+ } else {
+#if CurEmMd != kEmMd_PB100
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ if ((addr & 0x000001FE) != 0x00000000)
+#else
+ if ((addr & 0x000FE1FE) != 0x000FE1FE)
+#endif
+ {
+ ReportAbnormalID(0x1108,
+ "access VIA1 nonstandard address");
+ }
+#endif
+ Data = VIA1_Access(Data, WriteMem,
+ (addr >> 9) & kVIA1_Mask);
+ }
+
+ break;
+#if EmVIA2
+ case kMMDV_VIA2:
+ if (! ByteSize) {
+ if ((! WriteMem)
+ && ((0x3e00 == (addr & 0x1FFFF))
+ || (0x3e02 == (addr & 0x1FFFF))))
+ {
+ /* for weirdness at offset 0x71E in ROM */
+ Data =
+ (VIA2_Access(Data, WriteMem,
+ (addr >> 9) & kVIA2_Mask) << 8)
+ | VIA2_Access(Data, WriteMem,
+ (addr >> 9) & kVIA2_Mask);
+
+ } else {
+ ReportAbnormalID(0x1109, "access VIA2 word");
+ }
+ } else if ((addr & 1) != 0) {
+ if (0x3FFF == (addr & 0x1FFFF)) {
+ /*
+ for weirdness at offset 0x7C4 in ROM.
+ looks like bug.
+ */
+ Data = VIA2_Access(Data, WriteMem,
+ (addr >> 9) & kVIA2_Mask);
+ } else {
+ ReportAbnormalID(0x110A, "access VIA2 odd");
+ }
+ } else {
+ if ((addr & 0x000001FE) != 0x00000000) {
+ ReportAbnormalID(0x110B,
+ "access VIA2 nonstandard address");
+ }
+ Data = VIA2_Access(Data, WriteMem,
+ (addr >> 9) & kVIA2_Mask);
+ }
+ break;
+#endif
+ case kMMDV_SCC:
+
+#if (CurEmMd >= kEmMd_SE) \
+ && ! ((CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx))
+
+ if ((addr & 0x00100000) == 0) {
+ ReportAbnormalID(0x110C,
+ "access SCC unassigned address");
+ } else
+#endif
+ if (! ByteSize) {
+ ReportAbnormalID(0x110D, "Attemped Phase Adjust");
+ } else
+#if ! ((CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx))
+ if (WriteMem != ((addr & 1) != 0)) {
+ if (WriteMem) {
+#if CurEmMd >= kEmMd_512Ke
+#if CurEmMd != kEmMd_PB100
+ ReportAbnormalID(0x110E, "access SCC even/odd");
+ /*
+ This happens on boot with 64k ROM.
+ */
+#endif
+#endif
+ } else {
+ SCC_Reset();
+ }
+ } else
+#endif
+#if (CurEmMd != kEmMd_PB100) \
+ && ! ((CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx))
+
+ if (WriteMem != (addr >= kSCCWr_Block_Base)) {
+ ReportAbnormalID(0x110F, "access SCC wr/rd base wrong");
+ } else
+#endif
+ {
+#if CurEmMd != kEmMd_PB100
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ if ((addr & 0x1FF9) != 0x00000000)
+#else
+ if ((addr & 0x001FFFF8) != 0x001FFFF8)
+#endif
+ {
+ ReportAbnormalID(0x1110,
+ "access SCC nonstandard address");
+ }
+#endif
+ Data = SCC_Access(Data, WriteMem,
+ (addr >> 1) & kSCC_Mask);
+ }
+ break;
+ case kMMDV_Extn:
+ if (ByteSize) {
+ ReportAbnormalID(0x1111, "access Sony byte");
+ } else if ((addr & 1) != 0) {
+ ReportAbnormalID(0x1112, "access Sony odd");
+ } else if (! WriteMem) {
+ ReportAbnormalID(0x1113, "access Sony read");
+ } else {
+ Extn_Access(Data, (addr >> 1) & 0x0F);
+ }
+ break;
+#if EmASC
+ case kMMDV_ASC:
+ if (! ByteSize) {
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ if (WriteMem) {
+ (void) ASC_Access((Data >> 8) & 0x00FF,
+ WriteMem, addr & kASC_Mask);
+ Data = ASC_Access((Data) & 0x00FF,
+ WriteMem, (addr + 1) & kASC_Mask);
+ } else {
+ Data =
+ (ASC_Access((Data >> 8) & 0x00FF,
+ WriteMem, addr & kASC_Mask) << 8)
+ | ASC_Access((Data) & 0x00FF,
+ WriteMem, (addr + 1) & kASC_Mask);
+ }
+#else
+ ReportAbnormalID(0x1114, "access ASC word");
+#endif
+ } else {
+ Data = ASC_Access(Data, WriteMem, addr & kASC_Mask);
+ }
+ break;
+#endif
+ case kMMDV_SCSI:
+ if (! ByteSize) {
+ ReportAbnormalID(0x1115, "access SCSI word");
+ } else
+#if ! ((CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx))
+ if (WriteMem != ((addr & 1) != 0)) {
+ ReportAbnormalID(0x1116, "access SCSI even/odd");
+ } else
+#endif
+ {
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ if ((addr & 0x1F8F) != 0x00000000) {
+ ReportAbnormalID(0x1117,
+ "access SCSI nonstandard address");
+ }
+#endif
+ Data = SCSI_Access(Data, WriteMem, (addr >> 4) & 0x07);
+ }
+
+ break;
+ case kMMDV_IWM:
+#if (CurEmMd >= kEmMd_SE) \
+ && ! ((CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx))
+
+ if ((addr & 0x00100000) == 0) {
+ ReportAbnormalID(0x1118,
+ "access IWM unassigned address");
+ } else
+#endif
+ if (! ByteSize) {
+#if ExtraAbnormalReports
+ ReportAbnormalID(0x1119, "access IWM word");
+ /*
+ This happens when quitting 'Glider 3.1.2'.
+ perhaps a bad handle is being disposed of.
+ */
+#endif
+ } else
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ if ((addr & 1) != 0) {
+ ReportAbnormalID(0x111A, "access IWM odd");
+ } else
+#else
+ if ((addr & 1) == 0) {
+ ReportAbnormalID(0x111B, "access IWM even");
+ } else
+#endif
+ {
+#if (CurEmMd != kEmMd_PB100) \
+ && ! ((CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx))
+
+ if ((addr & 0x001FE1FF) != 0x001FE1FF) {
+ ReportAbnormalID(0x111C,
+ "access IWM nonstandard address");
+ }
+#endif
+ Data = IWM_Access(Data, WriteMem,
+ (addr >> 9) & kIWM_Mask);
+ }
+
+ break;
+ }
+
+ return Data;
+}
+
+GLOBALFUNC blnr MemAccessNtfy(ATTep pT)
+{
+ blnr v = falseblnr;
+
+ switch (pT->Ntfy) {
+#if CurEmMd >= kEmMd_SE
+ case kMAN_OverlayOff:
+ pT->Access = kATTA_readreadymask;
+
+ MemOverlay = 0;
+ SetUpMemBanks();
+
+ v = trueblnr;
+
+ break;
+#endif
+ }
+
+ return v;
+}
+
+GLOBALPROC MemOverlay_ChangeNtfy(void)
+{
+#if CurEmMd <= kEmMd_Plus
+ SetUpMemBanks();
+#elif (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ SetUpMemBanks();
+#endif
+}
+
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+GLOBALPROC Addr32_ChangeNtfy(void)
+{
+ SetUpMemBanks();
+}
+#endif
+
+LOCALFUNC ATTep get_address_realblock1(blnr WriteMem, CPTR addr)
+{
+ ATTep p;
+
+Label_Retry:
+ p = FindATTel(addr);
+ if (0 != (p->Access &
+ (WriteMem ? kATTA_writereadymask : kATTA_readreadymask)))
+ {
+ /* ok */
+ } else {
+ if (0 != (p->Access & kATTA_ntfymask)) {
+ if (MemAccessNtfy(p)) {
+ goto Label_Retry;
+ }
+ }
+ p = nullpr; /* fail */
+ }
+
+ return p;
+}
+
+GLOBALFUNC ui3p get_real_address0(ui5b L, blnr WritableMem, CPTR addr,
+ ui5b *actL)
+{
+ ui5b bankleft;
+ ui3p p;
+ ATTep q;
+
+ q = get_address_realblock1(WritableMem, addr);
+ if (nullpr == q) {
+ *actL = 0;
+ p = nullpr;
+ } else {
+ ui5r m2 = q->usemask & ~ q->cmpmask;
+ ui5r m3 = m2 & ~ (m2 + 1);
+ p = q->usebase + (addr & q->usemask);
+ bankleft = (m3 + 1) - (addr & m3);
+ if (bankleft >= L) {
+ /* this block is big enough (by far the most common case) */
+ *actL = L;
+ } else {
+ *actL = bankleft;
+ }
+ }
+
+ return p;
+}
+
+GLOBALVAR blnr InterruptButton = falseblnr;
+
+GLOBALPROC SetInterruptButton(blnr v)
+{
+ if (InterruptButton != v) {
+ InterruptButton = v;
+ VIAorSCCinterruptChngNtfy();
+ }
+}
+
+LOCALVAR ui3b CurIPL = 0;
+
+GLOBALPROC VIAorSCCinterruptChngNtfy(void)
+{
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ ui3b NewIPL;
+
+ if (InterruptButton) {
+ NewIPL = 7;
+ } else if (SCCInterruptRequest) {
+ NewIPL = 4;
+ } else if (VIA2_InterruptRequest) {
+ NewIPL = 2;
+ } else if (VIA1_InterruptRequest) {
+ NewIPL = 1;
+ } else {
+ NewIPL = 0;
+ }
+#else
+ ui3b VIAandNotSCC = VIA1_InterruptRequest
+ & ~ SCCInterruptRequest;
+ ui3b NewIPL = VIAandNotSCC
+ | (SCCInterruptRequest << 1)
+ | (InterruptButton << 2);
+#endif
+ if (NewIPL != CurIPL) {
+ CurIPL = NewIPL;
+ m68k_IPLchangeNtfy();
+ }
+}
+
+GLOBALFUNC blnr AddrSpac_Init(void)
+{
+ int i;
+
+ for (i = 0; i < kNumWires; i++) {
+ Wires[i] = 1;
+ }
+
+ MINEM68K_Init(
+ &CurIPL);
+ return trueblnr;
+}
+
+GLOBALPROC Memory_Reset(void)
+{
+ MemOverlay = 1;
+ SetUpMemBanks();
+}
+
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+EXPORTPROC PowerOff_ChangeNtfy(void);
+GLOBALPROC PowerOff_ChangeNtfy(void)
+{
+ if (! VIA2_iB2) {
+ ForceMacOff = trueblnr;
+ }
+}
+#endif
+
+/* user event queue utilities */
+
+#if HaveMasterMyEvtQLock
+GLOBALVAR ui4r MasterMyEvtQLock = 0;
+ /*
+ Takes a few ticks to process button event because
+ of debounce code of Mac. So have this mechanism
+ to prevent processing further events meanwhile.
+ */
+#endif
+
+GLOBALFUNC blnr FindKeyEvent(int *VirtualKey, blnr *KeyDown)
+{
+ MyEvtQEl *p;
+
+ if (
+#if HaveMasterMyEvtQLock
+ (0 == MasterMyEvtQLock) &&
+#endif
+ (nullpr != (p = MyEvtQOutP())))
+ {
+ if (MyEvtQElKindKey == p->kind) {
+ *VirtualKey = p->u.press.key;
+ *KeyDown = p->u.press.down;
+ MyEvtQOutDone();
+ return trueblnr;
+ }
+ }
+
+ return falseblnr;
+}
+
+/* task management */
+
+#ifdef _VIA_Debug
+#include <stdio.h>
+#endif
+
+GLOBALVAR uimr ICTactive;
+GLOBALVAR iCountt ICTwhen[kNumICTs];
+
+GLOBALPROC ICT_Zap(void)
+{
+ ICTactive = 0;
+}
+
+LOCALPROC InsertICT(int taskid, iCountt when)
+{
+ ICTwhen[taskid] = when;
+ ICTactive |= (1 << taskid);
+}
+
+GLOBALVAR iCountt NextiCount = 0;
+
+GLOBALFUNC iCountt GetCuriCount(void)
+{
+ return NextiCount - GetCyclesRemaining();
+}
+
+GLOBALPROC ICT_add(int taskid, ui5b n)
+{
+ /* n must be > 0 */
+ si5r x = GetCyclesRemaining();
+ ui5b when = NextiCount - x + n;
+
+#ifdef _VIA_Debug
+ fprintf(stderr, "ICT_add: %d, %d, %d\n", when, taskid, n);
+#endif
+ InsertICT(taskid, when);
+
+ if (x > (si5r)n) {
+ SetCyclesRemaining(n);
+ NextiCount = when;
+ }
+}
--- /dev/null
+++ b/src/GLOBGLUE.h
@@ -1,0 +1,276 @@
+/*
+ GLOBGLUE.h
+
+ Copyright (C) 2003 Bernd Schmidt, Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef GLOBGLUE_H
+#error "header already included"
+#else
+#define GLOBGLUE_H
+#endif
+
+
+#define kEmMd_Twig43 0
+#define kEmMd_Twiggy 1
+#define kEmMd_128K 2
+#define kEmMd_512Ke 3
+#define kEmMd_Plus 4
+#define kEmMd_SE 5
+#define kEmMd_SEFDHD 6
+#define kEmMd_Classic 7
+#define kEmMd_PB100 8
+#define kEmMd_II 9
+#define kEmMd_IIx 10
+
+#define RAMSafetyMarginFudge 4
+
+#define kRAM_Size (kRAMa_Size + kRAMb_Size)
+EXPORTVAR(ui3p, RAM)
+ /*
+ allocated by MYOSGLUE to be at least
+ kRAM_Size + RAMSafetyMarginFudge
+ bytes. Because of shortcuts taken in GLOBGLUE.c, it is in theory
+ possible for the emulator to write up to 3 bytes past kRAM_Size.
+ */
+
+#if EmVidCard
+EXPORTVAR(ui3p, VidROM)
+#endif
+
+#if IncludeVidMem
+EXPORTVAR(ui3p, VidMem)
+#endif
+
+EXPORTPROC MemOverlay_ChangeNtfy(void);
+
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+EXPORTPROC Addr32_ChangeNtfy(void);
+#endif
+
+/*
+ representation of pointer into memory of emulated computer.
+*/
+typedef ui5b CPTR;
+
+/*
+ mapping of address space to real memory
+*/
+
+EXPORTFUNC ui3p get_real_address0(ui5b L, blnr WritableMem, CPTR addr,
+ ui5b *actL);
+
+/*
+ memory access routines that can use when have address
+ that is known to be in RAM (and that is in the first
+ copy of the ram, not the duplicates, i.e. < kRAM_Size).
+*/
+
+#ifndef ln2mtb
+
+#define get_ram_byte(addr) do_get_mem_byte((addr) + RAM)
+#define get_ram_word(addr) do_get_mem_word((addr) + RAM)
+#define get_ram_long(addr) do_get_mem_long((addr) + RAM)
+
+#define put_ram_byte(addr, b) do_put_mem_byte((addr) + RAM, (b))
+#define put_ram_word(addr, w) do_put_mem_word((addr) + RAM, (w))
+#define put_ram_long(addr, l) do_put_mem_long((addr) + RAM, (l))
+
+#else
+
+#define get_ram_byte get_vm_byte
+#define get_ram_word get_vm_word
+#define get_ram_long get_vm_long
+
+#define put_ram_byte put_vm_byte
+#define put_ram_word put_vm_word
+#define put_ram_long put_vm_long
+
+#endif
+
+#define get_ram_address(addr) ((addr) + RAM)
+
+/*
+ accessing addresses that don't map to
+ real memory, i.e. memory mapped devices
+*/
+
+EXPORTFUNC blnr AddrSpac_Init(void);
+
+
+#define ui5r_FromSByte(x) ((ui5r)(si5r)(si3b)(ui3b)(x))
+#define ui5r_FromSWord(x) ((ui5r)(si5r)(si4b)(ui4b)(x))
+#define ui5r_FromSLong(x) ((ui5r)(si5r)(si5b)(ui5b)(x))
+
+#define ui5r_FromUByte(x) ((ui5r)(ui3b)(x))
+#define ui5r_FromUWord(x) ((ui5r)(ui4b)(x))
+#define ui5r_FromULong(x) ((ui5r)(ui5b)(x))
+
+
+#if WantDisasm
+EXPORTPROC dbglog_StartLine(void);
+#else
+#define dbglog_StartLine()
+#endif
+
+#if dbglog_HAVE
+EXPORTPROC dbglog_WriteMemArrow(blnr WriteMem);
+
+EXPORTPROC dbglog_WriteNote(char *s);
+EXPORTPROC dbglog_WriteSetBool(char *s, blnr v);
+EXPORTPROC dbglog_AddrAccess(char *s,
+ ui5r Data, blnr WriteMem, ui5r addr);
+EXPORTPROC dbglog_Access(char *s, ui5r Data, blnr WriteMem);
+#endif
+
+#if ! WantAbnormalReports
+#define ReportAbnormalID(id, s)
+#else
+#if dbglog_HAVE
+#define ReportAbnormalID DoReportAbnormalID
+#else
+#define ReportAbnormalID(id, s) DoReportAbnormalID(id)
+#endif
+EXPORTPROC DoReportAbnormalID(ui4r id
+#if dbglog_HAVE
+ , char *s
+#endif
+ );
+#endif /* WantAbnormalReports */
+
+EXPORTPROC VIAorSCCinterruptChngNtfy(void);
+
+EXPORTVAR(blnr, InterruptButton)
+EXPORTPROC SetInterruptButton(blnr v);
+
+enum {
+ kICT_SubTick,
+#if EmClassicKbrd
+ kICT_Kybd_ReceiveCommand,
+ kICT_Kybd_ReceiveEndCommand,
+#endif
+#if EmADB
+ kICT_ADB_NewState,
+#endif
+#if EmPMU
+ kICT_PMU_Task,
+#endif
+ kICT_VIA1_Timer1Check,
+ kICT_VIA1_Timer2Check,
+#if EmVIA2
+ kICT_VIA2_Timer1Check,
+ kICT_VIA2_Timer2Check,
+#endif
+
+ kNumICTs
+};
+
+EXPORTPROC ICT_add(int taskid, ui5b n);
+
+#define iCountt ui5b
+EXPORTFUNC iCountt GetCuriCount(void);
+EXPORTPROC ICT_Zap(void);
+
+EXPORTVAR(uimr, ICTactive)
+EXPORTVAR(iCountt, ICTwhen[kNumICTs])
+EXPORTVAR(iCountt, NextiCount)
+
+EXPORTVAR(ui3b, Wires[kNumWires])
+
+#define kLn2CycleScale 6
+#define kCycleScale (1 << kLn2CycleScale)
+
+#if WantCycByPriOp
+#define RdAvgXtraCyc /* 0 */ (kCycleScale + kCycleScale / 4)
+#define WrAvgXtraCyc /* 0 */ (kCycleScale + kCycleScale / 4)
+#endif
+
+#define kNumSubTicks 16
+
+
+#define HaveMasterMyEvtQLock EmClassicKbrd
+#if HaveMasterMyEvtQLock
+EXPORTVAR(ui4r, MasterMyEvtQLock)
+#endif
+EXPORTFUNC blnr FindKeyEvent(int *VirtualKey, blnr *KeyDown);
+
+
+/* minivmac extensions */
+
+#define ExtnDat_checkval 0
+#define ExtnDat_extension 2
+#define ExtnDat_commnd 4
+#define ExtnDat_result 6
+#define ExtnDat_params 8
+
+#define kCmndVersion 0
+#define ExtnDat_version 8
+
+enum {
+ kExtnFindExtn, /* must be first */
+
+ kExtnDisk,
+ kExtnSony,
+#if EmVidCard
+ kExtnVideo,
+#endif
+#if IncludeExtnPbufs
+ kExtnParamBuffers,
+#endif
+#if IncludeExtnHostTextClipExchange
+ kExtnHostTextClipExchange,
+#endif
+
+ kNumExtns
+};
+
+#define kcom_callcheck 0x5B17
+
+EXPORTVAR(ui5r, my_disk_icon_addr)
+
+EXPORTPROC Memory_Reset(void);
+
+EXPORTPROC Extn_Reset(void);
+
+EXPORTPROC customreset(void);
+
+struct ATTer {
+ struct ATTer *Next;
+ ui5r cmpmask;
+ ui5r cmpvalu;
+ ui5r Access;
+ ui5r usemask; /* Should be one less than a power of two. */
+ ui3p usebase;
+ ui3r MMDV;
+ ui3r Ntfy;
+ ui4r Pad0;
+ ui5r Pad1; /* make 32 byte structure, on 32 bit systems */
+};
+typedef struct ATTer ATTer;
+typedef ATTer *ATTep;
+
+#define kATTA_readreadybit 0
+#define kATTA_writereadybit 1
+#define kATTA_mmdvbit 2
+#define kATTA_ntfybit 3
+
+#define kATTA_readwritereadymask \
+ ((1 << kATTA_readreadybit) | (1 << kATTA_writereadybit))
+#define kATTA_readreadymask (1 << kATTA_readreadybit)
+#define kATTA_writereadymask (1 << kATTA_writereadybit)
+#define kATTA_mmdvmask (1 << kATTA_mmdvbit)
+#define kATTA_ntfymask (1 << kATTA_ntfybit)
+
+EXPORTFUNC ui5b MMDV_Access(ATTep p, ui5b Data,
+ blnr WriteMem, blnr ByteSize, CPTR addr);
+EXPORTFUNC blnr MemAccessNtfy(ATTep pT);
--- /dev/null
+++ b/src/HPMCHACK.h
@@ -1,0 +1,261 @@
+/*
+ HPMCHACK.c
+
+ Copyright (C) 2016 Steve Chamberlin, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ HaPpy MaCintosh Hack
+
+ Patch the ROM for alternatives to the
+ Happy Macintosh icon displayed on boot
+ when a disk is inserted.
+*/
+
+#define kAHM_aside 0
+#define kAHM_cheese 1
+#define kAHM_evil 2
+#define kAHM_horror 3
+#define kAHM_lady_mac 4
+#define kAHM_moustache 5
+#define kAHM_nerdy 6
+#define kAHM_pirate 7
+#define kAHM_sleepy 8
+#define kAHM_sly 9
+#define kAHM_sunglasses 10
+#define kAHM_surprise 11
+#define kAHM_tongue 12
+#define kAHM_yuck 13
+#define kAHM_zombie 14
+
+LOCALVAR const ui3b my_HappyMac_icon[] = {
+#if CurAltHappyMac == kAHM_aside
+ 0x00, 0x00,
+ 0x39, 0x38,
+ 0x21, 0x20,
+ 0x01, 0x00,
+ 0x01, 0x00,
+ 0x03, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x07, 0x80,
+ 0x00, 0x00
+#endif
+#if CurAltHappyMac == kAHM_cheese
+ 0x10, 0x10,
+ 0x28, 0x28,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x3F, 0xF8,
+ 0x20, 0x08,
+ 0x20, 0x08,
+ 0x20, 0x08,
+ 0x10, 0x10,
+ 0x0F, 0xE0,
+#endif
+#if CurAltHappyMac == kAHM_evil
+ 0x00, 0x00,
+ 0x10, 0x10,
+ 0x08, 0x20,
+ 0x0C, 0x60,
+ 0x00, 0x00,
+ 0x20, 0x08,
+ 0x20, 0x08,
+ 0x1F, 0xF0,
+ 0x00, 0x00,
+ 0x00, 0x00
+#endif
+#if CurAltHappyMac == kAHM_horror
+ 0x38, 0x38,
+ 0x44, 0x44,
+ 0x44, 0x44,
+ 0x44, 0x44,
+ 0x38, 0x38,
+ 0x03, 0x80,
+ 0x03, 0x80,
+ 0x03, 0x80,
+ 0x03, 0x80,
+ 0x03, 0x80
+#endif
+#if CurAltHappyMac == kAHM_lady_mac
+ 0x38, 0x38,
+ 0x45, 0x44,
+ 0x55, 0x54,
+ 0x45, 0x44,
+ 0x39, 0x38,
+ 0x03, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x07, 0x80,
+ 0x03, 0x00
+#endif
+#if CurAltHappyMac == kAHM_moustache
+ 0x00, 0x00,
+ 0x11, 0x10,
+ 0x11, 0x10,
+ 0x01, 0x00,
+ 0x01, 0x00,
+ 0x03, 0x00,
+ 0x1F, 0xE0,
+ 0x00, 0x00,
+ 0x08, 0x40,
+ 0x07, 0x80
+#endif
+#if CurAltHappyMac == kAHM_nerdy
+ 0x38, 0x38,
+ 0x45, 0x45,
+ 0xD7, 0xD6,
+ 0x45, 0x44,
+ 0x39, 0x38,
+ 0x03, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x0F, 0xC0,
+ 0x00, 0x00
+#endif
+#if CurAltHappyMac == kAHM_pirate
+ 0x00, 0x81,
+ 0x00, 0x7E,
+ 0x11, 0x7E,
+ 0x11, 0x3C,
+ 0x01, 0x3C,
+ 0x01, 0x18,
+ 0x03, 0x00,
+ 0x00, 0x00,
+ 0x08, 0x40,
+ 0x07, 0x80
+#endif
+#if CurAltHappyMac == kAHM_sleepy
+ 0x00, 0x00,
+ 0x1C, 0x70,
+ 0x22, 0x88,
+ 0x00, 0x00,
+ 0x1C, 0x70,
+ 0x08, 0x20,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x03, 0x80,
+ 0x00, 0x00
+#endif
+#if CurAltHappyMac == kAHM_sly
+ 0x00, 0x00,
+ 0x08, 0x20,
+ 0x14, 0x50,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x20, 0x08,
+ 0x3F, 0xF8,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00
+#endif
+#if CurAltHappyMac == kAHM_sunglasses
+ 0x00, 0x00,
+ 0xFF, 0xFE,
+ 0x7D, 0x7C,
+ 0x7D, 0x7C,
+ 0x39, 0x38,
+ 0x03, 0x00,
+ 0x00, 0x00,
+ 0x1F, 0xF0,
+ 0x00, 0x00,
+ 0x00, 0x00
+#endif
+#if CurAltHappyMac == kAHM_surprise
+ 0x1C, 0x70,
+ 0x22, 0x88,
+ 0x41, 0x04,
+ 0x49, 0x24,
+ 0x41, 0x04,
+ 0x22, 0x88,
+ 0x1C, 0x70,
+ 0x01, 0x00,
+ 0x03, 0x80,
+ 0x03, 0x80
+#endif
+#if CurAltHappyMac == kAHM_tongue
+ 0x00, 0x00,
+ 0x1E, 0x78,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x20, 0x04,
+ 0x3F, 0xFC,
+ 0x05, 0x40,
+ 0x05, 0x40,
+ 0x04, 0x40,
+ 0x03, 0x80
+#endif
+#if CurAltHappyMac == kAHM_yuck
+ 0x00, 0x00,
+ 0x18, 0x30,
+ 0x04, 0x40,
+ 0x02, 0x80,
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x1F, 0xF0,
+ 0x15, 0x50,
+ 0x04, 0x40,
+ 0x03, 0x80
+#endif
+#if CurAltHappyMac == kAHM_zombie
+ 0x70, 0x7C,
+ 0x88, 0x82,
+ 0x88, 0x8A,
+ 0xA8, 0x8A,
+ 0x70, 0x82,
+ 0x00, 0x42,
+ 0x00, 0x3C,
+ 0x1E, 0x00,
+ 0x3F, 0x00,
+ 0x3F, 0x00
+#endif
+};
+
+#if CurEmMd <= kEmMd_Twig43
+#define HappyMacBase 0xA34
+#elif CurEmMd <= kEmMd_Twiggy
+#define HappyMacBase 0x8F4
+#elif CurEmMd <= kEmMd_128K
+#define HappyMacBase 0x8A0
+#elif CurEmMd <= kEmMd_Plus
+#define HappyMacBase 0xFD2
+#elif CurEmMd <= kEmMd_Classic
+#define HappyMacBase 0x125C
+#elif CurEmMd <= kEmMd_PB100
+#define HappyMacBase 0x2BB0
+#elif (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+#define HappyMacBase 0x1948
+#endif
+
+LOCALPROC PatchHappyMac(void)
+{
+#if (CurEmMd == kEmMd_PB100) \
+ || (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+
+ int i;
+ ui3b *dst = HappyMacBase + ROM + 0x18;
+ ui3b *src = (ui3b *)my_HappyMac_icon;
+
+ for (i = 10; --i >= 0; ) {
+ ++dst;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ ++dst;
+ }
+
+#else
+ MyMoveBytes((anyp)my_HappyMac_icon,
+ (anyp)(HappyMacBase + ROM),
+ sizeof(my_HappyMac_icon));
+#endif
+}
--- /dev/null
+++ b/src/ICONAPPM.r
@@ -1,0 +1,192 @@
+/*
+ AppIcon.r
+
+ Copyright (C) 2003 Philip Cummins, Richard F. Bannister,
+ Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#if SmallIconAPIAvail
+resource 'ics#' (AppIconId, purgeable) {
+ { /* array: 2 elements */
+ /* [1] */
+ $"0000 1FF8 2004 2FF4 2814 2A94 2B14 2A14"
+ $"2814 2FF4 2004 2004 20F4 2004 1FF8 1FF8",
+ /* [2] */
+ $"0000 1FF8 3FFC 3FFC 3FFC 3FFC 3FFC 3FFC"
+ $"3FFC 3FFC 3FFC 3FFC 3FFC 3FFC 1FF8 1FF8"
+ }
+};
+#endif
+
+#if ColorIconAPIAvail
+resource 'ics8' (AppIconId, purgeable) {
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 00FF FFFF FFFF FFFF FFFF FF00 0000"
+ $"0000 FF2B 2B2B 2B2B 2B2B 2B2B 2BFF 0000"
+ $"0000 FF2B FCFC FCFC FCFC FCFC 2BFF 0000"
+ $"0000 FF2B FC2A 2A2A 2A2A 2A00 2BFF 0000"
+ $"0000 FF2B FC2A EC2A EC2A 2A00 2BFF 0000"
+ $"0000 FF2B FC2A ECEC 2A2A 2A00 2BFF 0000"
+ $"0000 FF2B FC2A EC2A 2A2A 2A00 2BFF 0000"
+ $"0000 FF2B FC2A 2A2A 2A2A 2A00 2BFF 0000"
+ $"0000 FF2B FA00 0000 0000 0000 2BFF 0000"
+ $"0000 FF2B 2B2B 2B2B 2B2B 2B2B 2BFF 0000"
+ $"0000 FF2B E32B 2B2B 2B2B 2B2B 2BFF 0000"
+ $"0000 FF2B D82B 2B2B FFFF FFFF 2BFF 0000"
+ $"0000 FF2B 2B2B 2B2B 2B2B 2B2B 2BFF 0000"
+ $"0000 00FD FDFD FDFD FDFF FFFF FF00 0000"
+ $"0000 00FF FFFF FFFF FFFF FFFF FF"
+};
+#endif
+
+#if ColorIconAPIAvail
+resource 'ics4' (AppIconId, purgeable) {
+ $"0000 0000 0000 0000 000F FFFF FFFF F000"
+ $"00FC CCCC CCCC CF00 00FC EEEE EEEE CF00"
+ $"00FC ED0D 0D0C CF00 00FC E060 60D0 CF00"
+ $"00FC ED66 0D0C CF00 00FC E060 D0D0 CF00"
+ $"00FC ED0D 0D0C CF00 00FC D0C0 C0C0 CF00"
+ $"00FC CCCC CCCC CF00 00FC 8CCC CCCC CF00"
+ $"00FC 3CCC FFFF CF00 00FC CCCC CCCC CF00"
+ $"000F FFFF FFFF F000 000F FFFF FFFF F0"
+};
+#endif
+
+resource 'ICN#' (AppIconId, purgeable) {
+ { /* array: 2 elements */
+ /* [1] */
+ $"0000 0000 07FF FFE0 0800 0010 0800 0010"
+ $"08FF FF10 0900 0090 0918 1890 0918 3090"
+ $"0918 6090 0918 C090 0919 8090 091B 0090"
+ $"091E 0090 091C 0090 0918 0090 0910 0090"
+ $"0900 0090 08FF FF10 0800 0010 0800 0010"
+ $"0800 0010 0800 0010 0800 FF10 0800 0010"
+ $"0800 0010 0800 0010 0800 0010 07FF FFE0"
+ $"0400 0020 0400 0020 0400 0020 07FF FFE0",
+ /* [2] */
+ $"0000 0000 07FF FFE0 0FFF FFF0 0FFF FFF0"
+ $"0FFF FFF0 0FFF FFF0 0FFF FFF0 0FFF FFF0"
+ $"0FFF FFF0 0FFF FFF0 0FFF FFF0 0FFF FFF0"
+ $"0FFF FFF0 0FFF FFF0 0FFF FFF0 0FFF FFF0"
+ $"0FFF FFF0 0FFF FFF0 0FFF FFF0 0FFF FFF0"
+ $"0FFF FFF0 0FFF FFF0 0FFF FFF0 0FFF FFF0"
+ $"0FFF FFF0 0FFF FFF0 0FFF FFF0 07FF FFE0"
+ $"07FF FFE0 07FF FFE0 07FF FFE0 07FF FFE0"
+ }
+};
+
+#if ColorIconAPIAvail
+resource 'icl8' (AppIconId, purgeable) {
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 00FF FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFFF FFFF FFFF FF00 0000 0000"
+ $"0000 0000 FF2B 2B2B 2B2B 2B2B 2B2B 2B2B"
+ $"2B2B 2B2B 2B2B 2B2B 2B2B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2B2B 2B2B 2B2B 2B2B 2B2B"
+ $"2B2B 2B2B 2B2B 2B2B 2B2B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2B2B FCFC FCFC FCFC FCFC"
+ $"FCFC FCFC FCFC FCFC 2B2B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BFC 2A2A 2A2A 2A2A 2A2A"
+ $"2A2A 2A2A 2A2A 2A2A 002B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BFC 2A2A 2AEC EC2A 2A2A"
+ $"2A2A 2AEC EC2A 2A2A 002B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BFC 2A2A 2AEC EC2A 2A2A"
+ $"2A2A ECEC 2A2A 2A2A 002B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BFC 2A2A 2AEC EC2A 2A2A"
+ $"2AEC EC2A 2A2A 2A2A 002B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BFC 2A2A 2AEC EC2A 2A2A"
+ $"ECEC 2A2A 2A2A 2A2A 002B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BFC 2A2A 2AEC EC2A 2AEC"
+ $"EC2A 2A2A 2A2A 2A2A 002B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BFC 2A2A 2AEC EC2A ECEC"
+ $"2A2A 2A2A 2A2A 2A2A 002B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BFC 2A2A 2AEC ECEC EC2A"
+ $"2A2A 2A2A 2A2A 2A2A 002B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BFC 2A2A 2AEC ECEC 2A2A"
+ $"2A2A 2A2A 2A2A 2A2A 002B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BFC 2A2A 2AEC EC2A 2A2A"
+ $"2A2A 2A2A 2A2A 2A2A 002B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BFC 2A2A 2AEC 2A2A 2A2A"
+ $"2A2A 2A2A 2A2A 2A2A 002B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BFC 2A2A 2A2A 2A2A 2A2A"
+ $"2A2A 2A2A 2A2A 2A2A 002B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2B2B 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 2B2B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2B2B 2B2B 2B2B 2B2B 2B2B"
+ $"2B2B 2B2B 2B2B 2B2B 2B2B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2B2B 2B2B 2B2B 2B2B 2B2B"
+ $"2B2B 2B2B 2B2B 2B2B 2B2B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2B2B 2B2B 2B2B 2B2B 2B2B"
+ $"2B2B 2B2B 2B2B 2B2B 2B2B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2B2B 2B2B 2B2B 2B2B 2B2B"
+ $"2B2B 2B2B 2B2B 2B2B 2B2B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2B2B 2B2B 2B2B 2B2B 2B2B"
+ $"FFFF FFFF FFFF FFFF 2B2B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2B2B 2B2B 2B2B 2B2B 2B2B"
+ $"0000 0000 0000 0000 2B2B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BE3 E32B 2B2B 2B2B 2B2B"
+ $"2B2B 2B2B 2B2B 2B2B 2B2B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2BD8 D82B 2B2B 2B2B 2B2B"
+ $"2B2B 2B2B 2B2B 2B2B 2B2B 2BFF 0000 0000"
+ $"0000 0000 FF2B 2B2B 2B2B 2B2B 2B2B 2B2B"
+ $"2B2B 2B2B 2B2B 2B2B 2B2B 2BFF 0000 0000"
+ $"0000 0000 00FF FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFFF FFFF FFFF FF00 0000 0000"
+ $"0000 0000 00FF FBFB FBFB FBFB FCFC FCFC"
+ $"FCFD FDFD FDFD FDFD FDFD FF00 0000 0000"
+ $"0000 0000 00FF FAFA FAFA FAFA FAFA FBFB"
+ $"FCFC FCFC FDFD FDFD FDFD FF00 0000 0000"
+ $"0000 0000 00FF F9F9 F9F9 F9F9 F9F9 FAFA"
+ $"FAFB FBFC FCFC FCFD FDFD FF00 0000 0000"
+ $"0000 0000 00FF FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFFF FFFF FFFF FF"
+};
+#endif
+
+#if ColorIconAPIAvail
+resource 'icl4' (AppIconId, purgeable) {
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0FFF FFFF FFFF FFFF FFFF FFF0 0000"
+ $"0000 FCCC CCCC CCCC CCCC CCCC CCCF 0000"
+ $"0000 FCCC CCCC CCCC CCCC CCCC CCCF 0000"
+ $"0000 FCCC EEEE EEEE EEEE EEEE CCCF 0000"
+ $"0000 FCCE 0D0D 0D0D 0D0D 0D0D 0CCF 0000"
+ $"0000 FCCE D0D6 60D0 D0D6 60D0 CCCF 0000"
+ $"0000 FCCE 0D06 6D0D 0D66 0D0D 0CCF 0000"
+ $"0000 FCCE D0D6 60D0 D660 D0D0 CCCF 0000"
+ $"0000 FCCE 0D06 6D0D 660D 0D0D 0CCF 0000"
+ $"0000 FCCE D0D6 60D6 60D0 D0D0 CCCF 0000"
+ $"0000 FCCE 0D06 6D66 0D0D 0D0D 0CCF 0000"
+ $"0000 FCCE D0D6 6660 D0D0 D0D0 CCCF 0000"
+ $"0000 FCCE 0D06 660D 0D0D 0D0D 0CCF 0000"
+ $"0000 FCCE D0D6 60D0 D0D0 D0D0 CCCF 0000"
+ $"0000 FCCE 0D06 0D0D 0D0D 0D0D 0CCF 0000"
+ $"0000 FCCE D0D0 D0D0 D0D0 D0D0 CCCF 0000"
+ $"0000 FCCC 0C0C 0C0C 0C0C 0C0C 0CCF 0000"
+ $"0000 FCCC CCCC CCCC CCCC CCCC CCCF 0000"
+ $"0000 FCCC CCCC CCCC CCCC CCCC CCCF 0000"
+ $"0000 FCCC CCCC CCCC CCCC CCCC CCCF 0000"
+ $"0000 FCCC CCCC CCCC CCCC CCCC CCCF 0000"
+ $"0000 FCCC CCCC CCCC FFFF FFFF CCCF 0000"
+ $"0000 FCCC CCCC CCCC 0C0C 0C0C CCCF 0000"
+ $"0000 FCC8 8CCC CCCC CCCC CCCC CCCF 0000"
+ $"0000 FCC3 3CCC CCCC CCCC CCCC CCCF 0000"
+ $"0000 FCCC CCCC CCCC CCCC CCCC CCCF 0000"
+ $"0000 0FFF FFFF FFFF FFFF FFFF FFF0 0000"
+ $"0000 0FEE EEEE EEEE EEFF FFFF FFF0 0000"
+ $"0000 0FDD DDDD DDEE EEEE EEFF FFF0 0000"
+ $"0000 0FDD DDDD DDDD DEEE EEEE EEF0 0000"
+ $"0000 0FFF FFFF FFFF FFFF FFFF FFF0"
+};
+#endif
binary files /dev/null b/src/ICONAPPO.icns differ
binary files /dev/null b/src/ICONAPPW.ico differ
--- /dev/null
+++ b/src/ICONDSKM.r
@@ -1,0 +1,192 @@
+/*
+ DskIcon.r
+
+ Copyright (C) 2003 Philip Cummins, Richard F. Bannister,
+ Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#if SmallIconAPIAvail
+resource 'ics#' (DskIconId, purgeable) {
+ { /* array: 2 elements */
+ /* [1] */
+ $"7FE0 4030 4028 403C 4004 4004 4004 4FC4"
+ $"4AA4 4BA4 4824 4BA4 4AA4 4FE4 4004 7FFC",
+ /* [2] */
+ $"7FE0 7FF0 7FF8 7FFC 7FFC 7FFC 7FFC 7FFC"
+ $"7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC"
+ }
+};
+#endif
+
+#if ColorIconAPIAvail
+resource 'ics8' (DskIconId, purgeable) {
+ $"00FF FFFF FFFF FFFF FFFF FF00 0000 0000"
+ $"00FF 0000 0000 0000 0000 FFFF 0000 0000"
+ $"00FF 0000 0000 0000 0000 FF2A FF00 0000"
+ $"00FF 0000 0000 0000 0000 FFFF FFFF 0000"
+ $"00FF 0000 0000 0000 0000 00FA FAFF 0000"
+ $"00FF 0000 0000 0000 0000 0000 00FF 0000"
+ $"00FF 0000 0000 0000 0000 0000 00FF 0000"
+ $"00FF 0000 E0E0 E0E0 E0E0 0000 00FF 0000"
+ $"00FF 0000 E054 AB2A AB54 E000 00FF 0000"
+ $"00FF 0000 E054 ABAB AB54 E000 00FF 0000"
+ $"00FF 0000 E054 5454 5454 E000 00FF 0000"
+ $"00FF 0000 E054 ABAB AB54 E000 00FF 0000"
+ $"00FF 0000 E054 AB2A AB54 E000 00FF 0000"
+ $"00FF 0000 E0FF E0E0 E0E0 E000 00FF 0000"
+ $"00FF 0000 0000 0000 0000 0000 00FF 0000"
+ $"00FF FFFF FFFF FFFF FFFF FFFF FFFF"
+};
+#endif
+
+#if ColorIconAPIAvail
+resource 'ics4' (DskIconId, purgeable) {
+ $"0FFF FFFF FFF0 0000 0F00 0000 00FF 0000"
+ $"0F00 0000 00FC F000 0F00 0000 00FF FF00"
+ $"0F00 0000 000D DF00 0F00 0000 0000 0F00"
+ $"0F00 0000 0000 0F00 0F00 FFFF FF00 0F00"
+ $"0F00 FCE0 ECF0 0F00 0F00 FCEE ECF0 0F00"
+ $"0F00 FCCC CCF0 0F00 0F00 FCEE ECF0 0F00"
+ $"0F00 FCE0 ECF0 0F00 0F00 FFFF FFF0 0F00"
+ $"0F00 0000 0000 0F00 0FFF FFFF FFFF FF"
+};
+#endif
+
+resource 'ICN#' (DskIconId, purgeable) {
+ { /* array: 2 elements */
+ /* [1] */
+ $"1FFF F800 1000 0C00 1000 0A00 1000 0900"
+ $"1000 0880 1000 0840 1000 0820 1000 0FF0"
+ $"1000 0010 1000 0010 1000 0010 1000 0010"
+ $"1000 0010 10FF FC10 1120 9210 1121 5110"
+ $"1121 5110 1121 5110 1120 9110 111F E110"
+ $"1100 0110 1100 0110 111F F110 1120 0910"
+ $"1120 0910 1122 8910 1123 0910 1122 0910"
+ $"1120 0910 10FF FE10 1000 0010 1FFF FFF0",
+ /* [2] */
+ $"1FFF F800 1FFF FC00 1FFF FE00 1FFF FF00"
+ $"1FFF FF80 1FFF FFC0 1FFF FFE0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ }
+};
+
+#if ColorIconAPIAvail
+resource 'icl8' (DskIconId, purgeable) {
+ $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FF00 0000 0000 0000 0000 0000"
+ $"0000 00FF 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 FFFF 0000 0000 0000 0000 0000"
+ $"0000 00FF 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 FF2A FF00 0000 0000 0000 0000"
+ $"0000 00FF 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 FF2A 2AFF 0000 0000 0000 0000"
+ $"0000 00FF 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 FF2A 2A2A FF00 0000 0000 0000"
+ $"0000 00FF 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 FF2A 2A2A 2AFF 0000 0000 0000"
+ $"0000 00FF 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 FF2A 2A2A 2A2A FF00 0000 0000"
+ $"0000 00FF 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 FFFF FFFF FFFF FFFF 0000 0000"
+ $"0000 00FF 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 00FA FAFA FAFA FAFF 0000 0000"
+ $"0000 00FF 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 00FF 0000 0000"
+ $"0000 00FF 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 00FF 0000 0000"
+ $"0000 00FF 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 00FF 0000 0000"
+ $"0000 00FF 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00F5 E0FF E0E0 E0E0 E0E0"
+ $"E0E0 E0E0 E0E0 0000 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 AB2A 2A2A 2AFA"
+ $"FFFA 2AAB 5454 E000 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 AB2A 2A2A 2AFF"
+ $"00FF 2AAB 5454 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 AB2A 2A2A 2AFF"
+ $"00FF 2AAB 5454 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 AB2A 2A2A 2AFF"
+ $"00FF 2AAB 5454 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 AB2A 2A2A 2AFA"
+ $"FFFA 2AAB 5454 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 54AB ABAB ABAB"
+ $"ABAB AB54 5454 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 5454 5454 5454"
+ $"5454 5454 5454 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 5454 5454 5454"
+ $"5454 5454 5454 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 54AB ABAB ABAB"
+ $"ABAB ABAB 5454 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 AB2A 2A2A 2A2A"
+ $"2A2A 2A2A AB54 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 AB2A 2A2A 2A2A"
+ $"2A2A 2A2A AB54 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 AB2A 2A2A EC2A"
+ $"EC2A 2A2A AB54 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 AB2A 2A2A ECEC"
+ $"2A2A 2A2A AB54 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 AB2A 2A2A EC2A"
+ $"2A2A 2A2A AB54 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00E0 5454 AB2A 2A2A 2A2A"
+ $"2A2A 2A2A AB54 54E0 0000 00FF 0000 0000"
+ $"0000 00FF 0000 00F5 FFFF E0E0 E0E0 E0E0"
+ $"E0E0 E0E0 FFE0 E0F5 0000 00FF 0000 0000"
+ $"0000 00FF 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 00FF 0000 0000"
+ $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFFF FFFF FFFF FFFF"
+};
+#endif
+
+#if ColorIconAPIAvail
+resource 'icl4' (DskIconId, purgeable) {
+ $"000F FFFF FFFF FFFF FFFF F000 0000 0000"
+ $"000F 0000 0000 0000 0000 FF00 0000 0000"
+ $"000F 0000 0000 0000 0000 F0F0 0000 0000"
+ $"000F 0000 0000 0000 0000 FC0F 0000 0000"
+ $"000F 0000 0000 0000 0000 F0C0 F000 0000"
+ $"000F 0000 0000 0000 0000 FC0C 0F00 0000"
+ $"000F 0000 0000 0000 0000 F0C0 C0F0 0000"
+ $"000F 0000 0000 0000 0000 FFFF FFFF 0000"
+ $"000F 0000 0000 0000 0000 0DDD DDDF 0000"
+ $"000F 0000 0000 0000 0000 0000 000F 0000"
+ $"000F 0000 0000 0000 0000 0000 000F 0000"
+ $"000F 0000 0000 0000 0000 0000 000F 0000"
+ $"000F 0000 0000 0000 0000 0000 000F 0000"
+ $"000F 0000 FFFF FFFF FFFF FF00 000F 0000"
+ $"000F 000F CCEC 0C0D FD0E CCF0 000F 0000"
+ $"000F 000F CCE0 C0CF 0FCE CCCF 000F 0000"
+ $"000F 000F CCEC 0C0F 0F0E CCCF 000F 0000"
+ $"000F 000F CCE0 C0CF 0FCE CCCF 000F 0000"
+ $"000F 000F CCEC 0C0D FD0E CCCF 000F 0000"
+ $"000F 000F CCCE EEEE EEEC CCCF 000F 0000"
+ $"000F 000F CCCC CCCC CCCC CCCF 000F 0000"
+ $"000F 000F CCCC CCCC CCCC CCCF 000F 0000"
+ $"000F 000F CCCE EEEE EEEE CCCF 000F 0000"
+ $"000F 000F CCEC 0C0C 0C0C ECCF 000F 0000"
+ $"000F 000F CCE0 C0C0 C0C0 ECCF 000F 0000"
+ $"000F 000F CCEC 0C6C 6C0C ECCF 000F 0000"
+ $"000F 000F CCE0 C066 C0C0 ECCF 000F 0000"
+ $"000F 000F CCEC 0C6C 0C0C ECCF 000F 0000"
+ $"000F 000F CCE0 C0C0 C0C0 ECCF 000F 0000"
+ $"000F 0000 FFFF FFFF FFFF FFF0 000F 0000"
+ $"000F 0000 0000 0000 0000 0000 000F 0000"
+ $"000F FFFF FFFF FFFF FFFF FFFF FFFF"
+};
+#endif
binary files /dev/null b/src/ICONDSKO.icns differ
binary files /dev/null b/src/ICONDSKW.ico differ
--- /dev/null
+++ b/src/ICONROMM.r
@@ -1,0 +1,192 @@
+/*
+ RomIcon.r
+
+ Copyright (C) 2003 Philip Cummins, Richard F. Bannister,
+ Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#if SmallIconAPIAvail
+resource 'ics#' (RomIconId, purgeable) {
+ { /* array: 2 elements */
+ /* [1] */
+ $"7FE0 4030 4028 403C 4004 5FC4 5FC4 5FC4"
+ $"5FC4 4004 5FC4 5FC4 5FC4 5FC4 4004 7FFC",
+ /* [2] */
+ $"7FE0 7FF0 7FF8 7FFC 7FFC 7FFC 7FFC 7FFC"
+ $"7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC 7FFC"
+ }
+};
+#endif
+
+#if ColorIconAPIAvail
+resource 'ics8' (RomIconId, purgeable) {
+ $"00FF FFFF FFFF FFFF FFFF FF00 0000 0000"
+ $"00FF F5F5 F5F5 F5F5 F5F5 FFFF 0000 0000"
+ $"00FF F5F5 F5F5 F5F5 F5F5 FF2B FF00 0000"
+ $"00FF F5F5 F5F5 F5F5 F5F5 FFFF FFFF 0000"
+ $"00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000"
+ $"00FF F5FF FFFF FFFF FFFF F5F5 F5FF 0000"
+ $"00FF F5FF FFFF FFFF FFFF F5F5 F5FF 0000"
+ $"00FF F5FF FFFF FFFF FFFF F5F5 F5FF 0000"
+ $"00FF F5FF FFFF FFFF FFFF F5F5 F5FF 0000"
+ $"00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000"
+ $"00FF F5FF FFFF FFFF FFFF F5F5 F5FF 0000"
+ $"00FF F5FF FFFF FFFF FFFF F5F5 F5FF 0000"
+ $"00FF F5FF FFFF FFFF FFFF F5F5 F5FF 0000"
+ $"00FF F5FF FFFF FFFF FFFF F5F5 F5FF 0000"
+ $"00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000"
+ $"00FF FFFF FFFF FFFF FFFF FFFF FFFF"
+};
+#endif
+
+#if ColorIconAPIAvail
+resource 'ics4' (RomIconId, purgeable) {
+ $"0FFF FFFF FFF0 0000 0F0C 0C0C 0CFF 0000"
+ $"0FC0 C0C0 C0FC F000 0F0C 0C0C 0CFF FF00"
+ $"0FC0 C0C0 C0C0 CF00 0F0F FFFF FF0C 0F00"
+ $"0FCF FFFF FFC0 CF00 0F0F FFFF FF0C 0F00"
+ $"0FCF FFFF FFC0 CF00 0F0C 0C0C 0C0C 0F00"
+ $"0FCF FFFF FFC0 CF00 0F0F FFFF FF0C 0F00"
+ $"0FCF FFFF FFC0 CF00 0F0F FFFF FF0C 0F00"
+ $"0FC0 C0C0 C0C0 CF00 0FFF FFFF FFFF FF"
+};
+#endif
+
+resource 'ICN#' (RomIconId, purgeable) {
+ { /* array: 2 elements */
+ /* [1] */
+ $"1FFF FC00 1000 0600 1000 0500 1000 0480"
+ $"1000 0440 1000 0420 1000 07F0 1000 0010"
+ $"1155 5010 12AA A810 13FF F810 13FF F810"
+ $"13FF F810 13FF F810 13FF F810 13FF F810"
+ $"12AA A810 1155 5010 1000 0010 1155 5010"
+ $"12AA A810 13FF F810 13FF F810 13FF F810"
+ $"13FF F810 13FF F810 13FF F810 12AA A810"
+ $"1155 5010 1000 0010 1000 0010 1FFF FFF0",
+ /* [2] */
+ $"1FFF FC00 1FFF FE00 1FFF FF00 1FFF FF80"
+ $"1FFF FFC0 1FFF FFE0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ $"1FFF FFF0 1FFF FFF0 1FFF FFF0 1FFF FFF0"
+ }
+};
+
+#if ColorIconAPIAvail
+resource 'icl8' (RomIconId, purgeable) {
+ $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFFF 0000 0000 0000 0000 0000"
+ $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5"
+ $"F5F5 F5F5 F5FF FF00 0000 0000 0000 0000"
+ $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5"
+ $"F5F5 F5F5 F5FF 2BFF 0000 0000 0000 0000"
+ $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5"
+ $"F5F5 F5F5 F5FF 2B2B FF00 0000 0000 0000"
+ $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5"
+ $"F5F5 F5F5 F5FF 2B2B 2BFF 0000 0000 0000"
+ $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5"
+ $"F5F5 F5F5 F5FF 2B2B 2B2B FF00 0000 0000"
+ $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5"
+ $"F5F5 F5F5 F5FF FFFF FFFF FFFF 0000 0000"
+ $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5"
+ $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 F5FF F5FF F5FF F5FF F5FF"
+ $"F5FF F5FF F5F5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FF00 FF00 FF00 FF00 FF00"
+ $"FF00 FF00 FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FF00 FF00 FF00 FF00 FF00"
+ $"FF00 FF00 FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 F5FF F5FF F5FF F5FF F5FF"
+ $"F5FF F5FF F5F5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5"
+ $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 F5FF F5FF F5FF F5FF F5FF"
+ $"F5FF F5FF F5F5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FF00 FF00 FF00 FF00 FF00"
+ $"FF00 FF00 FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 FF00 FF00 FF00 FF00 FF00"
+ $"FF00 FF00 FFF5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 F5FF F5FF F5FF F5FF F5FF"
+ $"F5FF F5FF F5F5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5"
+ $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF F5F5 F5F5 F5F5 F5F5 F5F5 F5F5"
+ $"F5F5 F5F5 F5F5 F5F5 F5F5 F5FF 0000 0000"
+ $"0000 00FF FFFF FFFF FFFF FFFF FFFF FFFF"
+ $"FFFF FFFF FFFF FFFF FFFF FFFF"
+};
+#endif
+
+#if ColorIconAPIAvail
+resource 'icl4' (RomIconId, purgeable) {
+ $"000F FFFF FFFF FFFF FFFF FF00 0000 0000"
+ $"000F 0C0C 0C0C 0C0C 0C0C 0FF0 0000 0000"
+ $"000F C0C0 C0C0 C0C0 C0C0 CFCF 0000 0000"
+ $"000F 0C0C 0C0C 0C0C 0C0C 0FCC F000 0000"
+ $"000F C0C0 C0C0 C0C0 C0C0 CFCC CF00 0000"
+ $"000F 0C0C 0C0C 0C0C 0C0C 0FCC CCF0 0000"
+ $"000F C0C0 C0C0 C0C0 C0C0 CFFF FFFF 0000"
+ $"000F 0C0C 0C0C 0C0C 0C0C 0C0C 0C0F 0000"
+ $"000F C0CF CFCF CFCF CFCF C0C0 C0CF 0000"
+ $"000F 0CF0 F0F0 F0F0 F0F0 FC0C 0C0F 0000"
+ $"000F C0FF FFFF FFFF FFFF F0C0 C0CF 0000"
+ $"000F 0CFF FFFF FFFF FFFF FC0C 0C0F 0000"
+ $"000F C0FF FFFF FFFF FFFF F0C0 C0CF 0000"
+ $"000F 0CFF FFFF FFFF FFFF FC0C 0C0F 0000"
+ $"000F C0FF FFFF FFFF FFFF F0C0 C0CF 0000"
+ $"000F 0CFF FFFF FFFF FFFF FC0C 0C0F 0000"
+ $"000F C0F0 F0F0 F0F0 F0F0 F0C0 C0CF 0000"
+ $"000F 0C0F 0F0F 0F0F 0F0F 0C0C 0C0F 0000"
+ $"000F C0C0 C0C0 C0C0 C0C0 C0C0 C0CF 0000"
+ $"000F 0C0F 0F0F 0F0F 0F0F 0C0C 0C0F 0000"
+ $"000F C0F0 F0F0 F0F0 F0F0 F0C0 C0CF 0000"
+ $"000F 0CFF FFFF FFFF FFFF FC0C 0C0F 0000"
+ $"000F C0FF FFFF FFFF FFFF F0C0 C0CF 0000"
+ $"000F 0CFF FFFF FFFF FFFF FC0C 0C0F 0000"
+ $"000F C0FF FFFF FFFF FFFF F0C0 C0CF 0000"
+ $"000F 0CFF FFFF FFFF FFFF FC0C 0C0F 0000"
+ $"000F C0FF FFFF FFFF FFFF F0C0 C0CF 0000"
+ $"000F 0CF0 F0F0 F0F0 F0F0 FC0C 0C0F 0000"
+ $"000F C0CF CFCF CFCF CFCF C0C0 C0CF 0000"
+ $"000F 0C0C 0C0C 0C0C 0C0C 0C0C 0C0F 0000"
+ $"000F C0C0 C0C0 C0C0 C0C0 C0C0 C0CF 0000"
+ $"000F FFFF FFFF FFFF FFFF FFFF FFFF"
+};
+#endif
binary files /dev/null b/src/ICONROMO.icns differ
binary files /dev/null b/src/ICONROMW.ico differ
--- /dev/null
+++ b/src/INTLCHAR.h
@@ -1,0 +1,2231 @@
+/*
+ INTLCHAR.h
+
+ Copyright (C) 2010 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ InterNaTionAL CHARacters
+*/
+
+/* master copy of private font data */
+/*
+ Data in commments:
+ Mini vMac Cell name
+ Mac Roman (Octal)
+ windows-1252 code page
+ Unicode
+ plain ascii
+ ClStrAppendSubstCStr encoding
+ HTML character entity
+*/
+LOCALVAR const ui3b CellData[] = {
+ /* kCellUpA 101 0x41 0x0041 'A' 'A' A */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x7E,
+ 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpB 102 0x42 0x0042 'B' 'B' B */
+ 0x00, 0x00, 0x00, 0x7C, 0x42, 0x42, 0x7C, 0x42,
+ 0x42, 0x42, 0x42, 0x7C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpC 103 0x43 0x0043 'C' 'C' C */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x40, 0x40,
+ 0x40, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpD 104 0x44 0x0044 'D' 'D' D */
+ 0x00, 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x7C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpE 105 0x45 0x0045 'E' 'E' E */
+ 0x00, 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x7C,
+ 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpF 106 0x46 0x0046 'F' 'F' F */
+ 0x00, 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x7C,
+ 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpG 107 0x47 0x0047 'G' 'G' G */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x40, 0x40, 0x4E,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpH 110 0x48 0x0048 'H' 'H' H */
+ 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x7E,
+ 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpI 111 0x49 0x0049 'I' 'I' I */
+ 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpJ 112 0x4A 0x004A 'J' 'J' J */
+ 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpK 113 0x4B 0x004B 'K' 'K' K */
+ 0x00, 0x00, 0x00, 0x42, 0x44, 0x48, 0x50, 0x60,
+ 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpL 114 0x4C 0x004C 'L' 'L' L */
+ 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpM 115 0x4D 0x004D 'M' 'M' M */
+ 0x00, 0x00, 0x00, 0x82, 0xC6, 0xAA, 0x92, 0x82,
+ 0x82, 0x82, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpN 116 0x4E 0x004E 'N' 'N' N */
+ 0x00, 0x00, 0x00, 0x42, 0x42, 0x62, 0x52, 0x4A,
+ 0x46, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpO 117 0x4F 0x004F 'O' 'O' O */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpP 120 0x50 0x0050 'P' 'P' P */
+ 0x00, 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x7C,
+ 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpQ 121 0x51 0x0051 'Q' 'Q' Q */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x10, 0x0C, 0x00, 0x00,
+ /* kCellUpR 122 0x52 0x0052 'R' 'R' R */
+ 0x00, 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x7C,
+ 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpS 123 0x53 0x0053 'S' 'S' S */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x40, 0x40, 0x3C,
+ 0x02, 0x02, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpT 124 0x54 0x0054 'T' 'T' T */
+ 0x00, 0x00, 0x00, 0x7F, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpU 125 0x55 0x0055 'U' 'U' U */
+ 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpV 126 0x56 0x0056 'V' 'V' V */
+ 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x44,
+ 0x48, 0x50, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpW 127 0x57 0x0057 'W' 'W' W */
+ 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x5A, 0x66, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpX 130 0x58 0x0058 'X' 'X' X */
+ 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x24, 0x18,
+ 0x24, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpY 131 0x59 0x0059 'Y' 'Y' Y */
+ 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x14,
+ 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpZ 132 0x5A 0x005A 'Z' 'Z' Z */
+ 0x00, 0x00, 0x00, 0x7E, 0x02, 0x04, 0x08, 0x10,
+ 0x20, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoA 141 0x61 0x0061 'a' 'a' a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoB 142 0x62 0x0062 'b' 'b' b */
+ 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7C, 0x42,
+ 0x42, 0x42, 0x42, 0x7C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoC 143 0x63 0x0063 'c' 'c' c */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42,
+ 0x40, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoD 144 0x64 0x0064 'd' 'd' d */
+ 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x3E, 0x42,
+ 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoE 145 0x65 0x0065 'e' 'e' e */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42,
+ 0x7E, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoF 146 0x66 0x0066 'f' 'f' f */
+ 0x00, 0x00, 0x00, 0x0E, 0x10, 0x10, 0x3C, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoG 147 0x67 0x0067 'g' 'g' g */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x42,
+ 0x42, 0x42, 0x42, 0x3E, 0x02, 0x42, 0x3C, 0x00,
+ /* kCellLoH 150 0x68 0x0068 'h' 'h' h */
+ 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7C, 0x42,
+ 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoI 151 0x69 0x0069 'i' 'i' i */
+ 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoJ 152 0x6A 0x006A 'j' 'j' j */
+ 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x70, 0x00,
+ /* kCellLoK 153 0x6B 0x006B 'k' 'k' k */
+ 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x44, 0x48,
+ 0x70, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoL 154 0x6C 0x006C 'l' 'l' l */
+ 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoM 155 0x6D 0x006D 'm' 'm' m */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x92,
+ 0x92, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoN 156 0x6E 0x006E 'n' 'n' n */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x42,
+ 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoO 157 0x6F 0x006F 'o' 'o' o */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoP 160 0x70 0x0070 'p' 'p' p */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x42,
+ 0x42, 0x42, 0x42, 0x7C, 0x40, 0x40, 0x00, 0x00,
+ /* kCellLoQ 161 0x71 0x0071 'q' 'q' q */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x42,
+ 0x42, 0x42, 0x42, 0x3E, 0x02, 0x02, 0x00, 0x00,
+ /* kCellLoR 162 0x72 0x0072 'r' 'r' r */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x62,
+ 0x42, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoS 163 0x73 0x0073 's' 's' s */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42,
+ 0x3C, 0x02, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoT 164 0x74 0x0074 't' 't' t */
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x78, 0x20,
+ 0x20, 0x20, 0x20, 0x1C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoU 165 0x75 0x0075 'u' 'u' u */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoV 166 0x76 0x0076 'v' 'v' v */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x44,
+ 0x48, 0x50, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoW 167 0x77 0x0077 'w' 'w' w */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x92,
+ 0x92, 0x92, 0x92, 0x6C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoX 170 0x78 0x0078 'x' 'x' x */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x24,
+ 0x18, 0x18, 0x24, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoY 171 0x79 0x0079 'y' 'y' y */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3E, 0x02, 0x42, 0x3C, 0x00,
+ /* kCellLoZ 172 0x7A 0x007A 'z' 'z' z */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x04,
+ 0x08, 0x10, 0x20, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellDigit0 060 0x30 0x0030 '0' '0' 0 */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellDigit1 061 0x31 0x0031 '1' '1' 1 */
+ 0x00, 0x00, 0x00, 0x08, 0x18, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ /* kCellDigit2 062 0x32 0x0032 '2' '2' 2 */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x02, 0x02, 0x04,
+ 0x08, 0x10, 0x20, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellDigit3 063 0x33 0x0033 '3' '3' 3 */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x02, 0x0C, 0x02,
+ 0x02, 0x02, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellDigit4 064 0x34 0x0034 '4' '4' 4 */
+ 0x00, 0x00, 0x00, 0x04, 0x0C, 0x14, 0x24, 0x7E,
+ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
+ /* kCellDigit5 065 0x35 0x0035 '5' '5' 5 */
+ 0x00, 0x00, 0x00, 0x7E, 0x40, 0x40, 0x7C, 0x02,
+ 0x02, 0x02, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellDigit6 066 0x36 0x0036 '6' '6' 6 */
+ 0x00, 0x00, 0x00, 0x1C, 0x20, 0x40, 0x7C, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellDigit7 067 0x37 0x0037 '7' '7' 7 */
+ 0x00, 0x00, 0x00, 0x7E, 0x02, 0x02, 0x04, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ /* kCellDigit8 070 0x38 0x0038 '8' '8' 8 */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x3C, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellDigit9 071 0x39 0x0039 '9' '9' 9 */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42,
+ 0x3E, 0x02, 0x04, 0x38, 0x00, 0x00, 0x00, 0x00,
+ /* kCellExclamation 041 0x21 0x0021 '!' '!' ! */
+ 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ /* kCellAmpersand 046 0x26 0x0026 '&' '&' amp */
+ 0x00, 0x00, 0x00, 0x30, 0x48, 0x48, 0x50, 0x20,
+ 0x50, 0x4A, 0x44, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellApostrophe 047 0x27 0x0027 '\047' ';la' #39 (apos) */
+ 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLeftParen 050 0x28 0x0028 '(' '(' ( */
+ 0x00, 0x00, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00,
+ /* kCellRightParen 051 0x29 0x0029 ')' ')' ) */
+ 0x00, 0x00, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00,
+ /* kCellComma 054 0x2C 0x002C ',' ',' , */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x08, 0x08, 0x08, 0x10, 0x00, 0x00,
+ /* kCellHyphen 055 0x2D 0x002D '-' '-' - */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* kCellPeriod 056 0x2E 0x002E '.' '.' . */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ /* kCellSlash 057 0x2F 0x002F '/' '/' / */
+ 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x08, 0x08,
+ 0x10, 0x10, 0x20, 0x20, 0x40, 0x00, 0x00, 0x00,
+ /* kCellColon 072 0x3A 0x003A ':' ':' : */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+ 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ /* kCellSemicolon 073 0x3B 0x003B ';' ';ls' #59 (semi) */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+ 0x00, 0x00, 0x08, 0x08, 0x08, 0x10, 0x00, 0x00,
+ /* kCellQuestion 077 0x3F 0x003F '?' '?' ? */
+ 0x00, 0x00, 0x00, 0x38, 0x44, 0x04, 0x08, 0x10,
+ 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ /* kCellEllipsis 311 0x85 0x2026 '_' ';ll' #8230 (mldr) */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUnderscore 137 0x5F 0x005F '_' '_' _ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLeftDQuote 322 0x93 0x201C '"' ';[' ldquo */
+ 0x00, 0x00, 0x00, 0x24, 0x48, 0x6C, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* kCellRightDQuote 323 0x94 0x201D '"' ';{' rdquo */
+ 0x00, 0x00, 0x00, 0x36, 0x12, 0x24, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLeftSQuote 324 0x91 0x2018 '\047' ';]' lsquo */
+ 0x00, 0x00, 0x00, 0x08, 0x10, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* kCellRightSQuote 325 0x92 0x2019 '\047' ';}' rsquo */
+ 0x00, 0x00, 0x00, 0x18, 0x08, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* kCellCopyright 251 0xA9 0x00A9 'c' ';g' copy */
+ 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x9A, 0xA2,
+ 0xA2, 0x9A, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00,
+ /* kCellSpace 040 0x20 0x0020 '\040' '' #32 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+#if NeedIntlChars
+ /* kCellUpADiaeresis 200 0xC4 0x00C4 'A' ';uA' Auml */
+ 0x00, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x7E,
+ 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpARing 201 0xC5 0x00C5 'A' ';A' Aring */
+ 0x3C, 0x42, 0x42, 0x3C, 0x42, 0x42, 0x42, 0x7E,
+ 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpCCedilla 202 0xC7 0x00C7 'C' ';C' Ccedil */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x40, 0x40,
+ 0x40, 0x40, 0x42, 0x3C, 0x08, 0x08, 0x10, 0x00,
+ /* kCellUpEAcute 203 0xC9 0x00C9 'E' ';eE' Eacute */
+ 0x08, 0x10, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x7C,
+ 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpNTilde 204 0xD1 0x00D1 'N' ';nN' Ntilde */
+ 0x32, 0x4C, 0x00, 0x42, 0x42, 0x62, 0x52, 0x4A,
+ 0x46, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpODiaeresis 205 0xD6 0x00D6 'O' ';uO' Ouml */
+ 0x00, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpUDiaeresis 206 0xDC 0x00DC 'U' ';uU' Uuml */
+ 0x00, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoAAcute 207 0xE1 0x00E1 'a' ';ea' aacute */
+ 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x3E, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoAGrave 210 0xE0 0x00E0 'a' ';`a' agrave */
+ 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x3E, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoACircumflex 211 0xE2 0x00E2 'a' ';ia' acirc */
+ 0x00, 0x00, 0x00, 0x18, 0x24, 0x00, 0x3E, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoADiaeresis 212 0xE4 0x00E4 'a' ';ua' auml */
+ 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x3E, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoATilde 213 0xE3 0x00E3 'a' ';na' atilde */
+ 0x00, 0x00, 0x00, 0x32, 0x4C, 0x00, 0x3E, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoARing 214 0xE5 0x00E5 'a' ';a' aring */
+ 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x3E, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoCCedilla 215 0xE7 0x00E7 'c' ';c' ccedil */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42,
+ 0x40, 0x40, 0x42, 0x3C, 0x08, 0x08, 0x10, 0x00,
+ /* kCellLoEAcute 216 0xE9 0x00E9 'e' ';ee' eacute */
+ 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x3C, 0x42,
+ 0x7E, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoEGrave 217 0xE8 0x00E8 'e' ';`e' egrave */
+ 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x3C, 0x42,
+ 0x7E, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoECircumflex 220 0xEA 0x00EA 'e' ';ie' ecirc */
+ 0x00, 0x00, 0x00, 0x18, 0x24, 0x00, 0x3C, 0x42,
+ 0x7E, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoEDiaeresis 221 0xEB 0x00EB 'e' ';ue' euml */
+ 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x3C, 0x42,
+ 0x7E, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoIAcute 222 0xED 0x00ED 'i' ';ei' iacute */
+ 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoIGrave 223 0xEC 0x00EC 'i' ';`i' igrave */
+ 0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoICircumflex 224 0xEE 0x00EE 'i' ';ii' icirc */
+ 0x00, 0x00, 0x00, 0x10, 0x28, 0x00, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoIDiaeresis 225 0xEF 0x00EF 'i' ';ui' iuml */
+ 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoNTilde 226 0xF1 0x00F1 'n' ';nn' ntilde */
+ 0x00, 0x00, 0x00, 0x32, 0x4C, 0x00, 0x7C, 0x42,
+ 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoOAcute 227 0xF3 0x00F3 'o' ';eo' oacute */
+ 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x3C, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoOGrave 230 0xF2 0x00F2 'o' ';`o' ograve */
+ 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x3C, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoOCircumflex 231 0xF4 0x00F4 'o' ';io' ocirc */
+ 0x00, 0x00, 0x00, 0x18, 0x24, 0x00, 0x3C, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoODiaeresis 232 0xF6 0x00F6 'o' ';uo' ouml */
+ 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x3C, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoOTilde 233 0xF5 0x00F5 'o' ';no' otilde */
+ 0x00, 0x00, 0x00, 0x32, 0x4C, 0x00, 0x3C, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoUAcute 234 0xFA 0x00FA 'u' ';eu' uacute */
+ 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x42, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoUGrave 235 0xF9 0x00F9 'u' ';`u' ugrave */
+ 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x42, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoUCircumflex 236 0xFB 0x00FB 'u' ';iu' ucirc */
+ 0x00, 0x00, 0x00, 0x18, 0x24, 0x00, 0x42, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoUDiaeresis 237 0xFC 0x00FC 'u' ';uu' uuml */
+ 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x42, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+
+ /* kCellUpAE 256 0xC6 0x00C6 '?' ';lE' AElig */
+ 0x00, 0x00, 0x00, 0x3E, 0x48, 0x48, 0x48, 0x7C,
+ 0x48, 0x48, 0x48, 0x4E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpOStroke 257 0xD8 0x00D8 'O' ';O' Oslash */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x46, 0x5A,
+ 0x62, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+
+ /* kCellLoAE 276 0xE6 0x00E6 '?' ';le' aelig */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x52,
+ 0x5E, 0x50, 0x52, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoOStroke 277 0xF8 0x00F8 'o' ';o' oslash */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x46,
+ 0x5A, 0x62, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellInvQuestion 300 0xBF 0x00BF '?' ';?' iquest */
+ 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10,
+ 0x20, 0x40, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00,
+ /* kCellInvExclam 301 0xA1 0x00A1 '!' ';1' iexcl */
+ 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+
+ /* kCellUpAGrave 313 0xC0 0x00C0 'A' ';`A' Agrave */
+ 0x10, 0x08, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42,
+ 0x7E, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpATilde 314 0xC3 0x00C3 'A' ';nA' Atilde */
+ 0x32, 0x4C, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42,
+ 0x7E, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpOTilde 315 0xD5 0x00D5 'O' ';nO' Otilde */
+ 0x32, 0x4C, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpLigatureOE 316 0x8C 0x0152 '?' ';Q' OElig */
+ 0x00, 0x00, 0x00, 0x3E, 0x48, 0x48, 0x48, 0x4E,
+ 0x48, 0x48, 0x48, 0x3E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoLigatureOE 317 0x9C 0x0153 '?' ';q' oelig */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x52,
+ 0x5E, 0x50, 0x52, 0x2C, 0x00, 0x00, 0x00, 0x00,
+
+ /* kCellLoYDiaeresis 330 0xFF 0x00FF 'y' ';uy' yuml */
+ 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3E, 0x02, 0x42, 0x3C, 0x00,
+ /* kCellUpYDiaeresis 331 0x9F 0x0178 'Y' ';uY' Yuml */
+ 0x00, 0x14, 0x00, 0x22, 0x22, 0x22, 0x22, 0x14,
+ 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+
+ /* kCellUpACircumflex 345 0xC2 0x00C2 'A' ';iA' Acirc */
+ 0x18, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x7E,
+ 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpECircumflex 346 0xCA 0x00CA 'E' ';iE' Ecirc */
+ 0x18, 0x24, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x7C,
+ 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpAAcute 347 0xC1 0x00C1 'A' ';eA' Aacute */
+ 0x08, 0x10, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42,
+ 0x7E, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpEDiaeresis 350 0xCB 0x00CB 'E' ';uE' Euml */
+ 0x00, 0x24, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x7C,
+ 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpEGrave 351 0xC8 0x00C8 'E' ';`E' Egrave */
+ 0x10, 0x08, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x7C,
+ 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpIAcute 352 0xCD 0x00CD 'A' ';eI' Iacute */
+ 0x04, 0x08, 0x00, 0x3E, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpICircumflex 353 0xCE 0x00CE 'I' ';iI' Icirc */
+ 0x08, 0x14, 0x00, 0x3E, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpIDiaeresis 354 0xCF 0x00CF 'I' ';uI' Iuml */
+ 0x00, 0x14, 0x00, 0x3E, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpIGrave 355 0xCC 0x00CC 'I' ';`I' Igrave */
+ 0x10, 0x08, 0x00, 0x3E, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpOAcute 356 0xD3 0x00D3 'O' ';eO' Oacute */
+ 0x08, 0x10, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpOCircumflex 357 0xD4 0x00D4 'O' ';iO' Ocirc */
+ 0x18, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+
+ /* kCellUpOGrave 361 0xD2 0x00D2 'O' ';`O' Ograve */
+ 0x10, 0x08, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpUAcute 362 0xDA 0x00DA 'U' ';eU' Uacute */
+ 0x08, 0x10, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpUCircumflex 363 0xDB 0x00DB 'U' ';iU' Ucirc */
+ 0x18, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpUGrave 364 0xD9 0x00D9 'U' ';`U' Ugrave */
+ 0x10, 0x08, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellSharpS 247 0xDF 0x00DF 'B' ';s' szlig */
+ 0x00, 0x00, 0x00, 0x1C, 0x22, 0x42, 0x44, 0x44,
+ 0x42, 0x42, 0x42, 0x5C, 0x40, 0x00, 0x00, 0x00,
+
+ /* kCellUpACedille 260 ? 0x0104 'A' ';dA' #260 (Aogon) */
+ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x7E,
+ 0x42, 0x42, 0x42, 0x42, 0x04, 0x04, 0x02, 0x00,
+ /* kCellLoACedille 261 ? 0x0105 'a' ';da' #261 (aogon) */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x04, 0x04, 0x02, 0x00,
+ /* kCellUpCAcute 262 ? 0x0106 'C' ';eC' #262 (Cacute) */
+ 0x08, 0x10, 0x00, 0x3C, 0x42, 0x42, 0x40, 0x40,
+ 0x40, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoCAcute 263 ? 0x0107 'c' ';ec' #263 (cacute) */
+ 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x3C, 0x42,
+ 0x40, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpECedille 264 ? 0x0118 'E' ';dE' #280 (Eogon) */
+ 0x00, 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x7C,
+ 0x40, 0x40, 0x40, 0x7E, 0x04, 0x04, 0x02, 0x00,
+ /* kCellLoECedille 265 ? 0x0119 'e' ';de' #281 (eogon) */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42,
+ 0x7E, 0x40, 0x42, 0x3C, 0x08, 0x08, 0x04, 0x00,
+ /* kCellUpLBar 266 ? 0x0141 'L' ';dL' #321 (Lstrok) */
+ 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x60, 0x40,
+ 0xC0, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoLBar 267 ? 0x0142 'l' ';dl' #322 (lstrok) */
+ 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x0C, 0x08,
+ 0x18, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpNAcute 270 ? 0x0143 'N' ';eN' #323 (Nacute) */
+ 0x08, 0x10, 0x00, 0x42, 0x42, 0x62, 0x52, 0x4A,
+ 0x46, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoNAcute 271 ? 0x0144 'n' ';en' #324 (nacute) */
+ 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x7C, 0x42,
+ 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpSAcute 272 ? 0x015A 'S' ';eS' #346 (Sacute) */
+ 0x08, 0x10, 0x00, 0x3C, 0x42, 0x40, 0x40, 0x3C,
+ 0x02, 0x02, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoSAcute 273 ? 0x015B 's' ';es' #347 (sacute) */
+ 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x3C, 0x42,
+ 0x3C, 0x02, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpZAcute 274 ? 0x0179 'Z' ';eZ' #377 (Zacute) */
+ 0x08, 0x10, 0x00, 0x7E, 0x02, 0x04, 0x08, 0x10,
+ 0x20, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoZAcute 275 ? 0x017A 'z' ';ez' #378 (zacute) */
+ 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x7E, 0x04,
+ 0x08, 0x10, 0x20, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpZDot 276 ? 0x017B 'Z' ';dZ' #379 (Zdot) */
+ 0x10, 0x00, 0x00, 0x7E, 0x02, 0x04, 0x08, 0x10,
+ 0x20, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoZDot 277 ? 0x017C 'z' ';dz' #380 (zdot) */
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x7E, 0x04,
+ 0x08, 0x10, 0x20, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellMidDot 341 0xB7 0x00B7 '.' ';l.' middot */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpCCaron 077 ? 0x010C 'C' ';vC' #268 (Ccaron) */
+ 0x14, 0x08, 0x00, 0x3C, 0x42, 0x42, 0x40, 0x40,
+ 0x40, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoCCaron 077 ? 0x010D 'c' ';vc' #269 (ccaron) */
+ 0x00, 0x00, 0x00, 0x14, 0x08, 0x00, 0x3C, 0x42,
+ 0x40, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoECaron 077 ? 0x011B 'e' ';ve' #283 (ecaron) */
+ 0x00, 0x00, 0x00, 0x14, 0x08, 0x00, 0x3C, 0x42,
+ 0x7E, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoRCaron 077 ? 0x0159 'r' ';vr' #345 (rcaron) */
+ 0x00, 0x00, 0x00, 0x14, 0x08, 0x00, 0x5C, 0x62,
+ 0x42, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoSCaron 077 0x9A 0x0161 's' ';vs' #353 (scaron) */
+ 0x00, 0x00, 0x00, 0x14, 0x08, 0x00, 0x3C, 0x42,
+ 0x3C, 0x02, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoTCaron 077 ? 0x0165 't' ';vt' #357 (tcaron) */
+ 0x00, 0x14, 0x08, 0x00, 0x20, 0x20, 0x78, 0x20,
+ 0x20, 0x20, 0x20, 0x1C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoZCaron 077 0x9E 0x017E 'z' ';vz' #382 (zcaron) */
+ 0x00, 0x00, 0x00, 0x14, 0x08, 0x00, 0x7E, 0x04,
+ 0x08, 0x10, 0x20, 0x7E, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpYAcute 077 0xDD 0x00DD 'Y' ';eY' Yacute */
+ 0x08, 0x10, 0x00, 0x22, 0x22, 0x22, 0x22, 0x14,
+ 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoYAcute 077 0xFD 0x00FD 'y' ';ey' yacute */
+ 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x3E, 0x02, 0x42, 0x3C, 0x00,
+ /* kCellLoUDblac 077 ? 0x0171 'u' ';Eu' #369 (udblac) */
+ 0x00, 0x00, 0x00, 0x12, 0x24, 0x00, 0x42, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoURing 077 ? 0x016F 'u' ';ru' #367 (uring) */
+ 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x42, 0x42,
+ 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x00,
+ /* kCellUpDStroke 077 ? 0x0110 'D' ';dD' #272 (Dstrok) */
+ 0x00, 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0xF2,
+ 0x42, 0x42, 0x42, 0x7C, 0x00, 0x00, 0x00, 0x00,
+ /* kCellLoDStroke 077 ? 0x0111 'd' ';dd' #273 (dstrok) */
+ 0x00, 0x00, 0x00, 0x02, 0x0F, 0x02, 0x3E, 0x42,
+ 0x42, 0x42, 0x42, 0x3E, 0x00, 0x00, 0x00, 0x00,
+#endif
+
+ /* kCellUpperLeft */
+ 0xFF, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ /* kCellUpperMiddle */
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* kCellMiddleLeft */
+ 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ /* kCellMiddleLeft */
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ /* kCellMiddleRight */
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ /* kCellLowerLeft */
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFF,
+ /* kCellLowerMiddle */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ /* kCellLowerRight */
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF,
+ /* kCellGraySep */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* kCellIcon00 */
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09,
+ /* kCellIcon01 */
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x18, 0x18,
+ /* kCellIcon02 */
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x18, 0x30,
+ /* kCellIcon03 */
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xE0, 0x10, 0x10, 0x10, 0x90, 0x90, 0x90,
+ /* kCellIcon10 */
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ /* kCellIcon11 */
+ 0x18, 0x18, 0x19, 0x1B, 0x1E, 0x1C, 0x18, 0x10,
+ 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* kCellIcon12 */
+ 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
+ /* kCellIcon13 */
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ /* kCellIcon20 */
+ 0x08, 0x08, 0x08, 0x07, 0x04, 0x04, 0x04, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* kCellIcon21 */
+ 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* kCellIcon22 */
+ 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* kCellIcon23 */
+ 0x10, 0x10, 0x10, 0xE0, 0x20, 0x20, 0x20, 0xE0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+#if EnableAltKeysMode
+ /* kInsertText00 */
+ 0xFF, 0x80, 0x80, 0x80, 0x80, 0x83, 0x80, 0x80,
+ 0x80, 0x80, 0x83, 0x80, 0x80, 0x80, 0x80, 0xFF,
+ /* kInsertText01 */
+ 0xFF, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x19,
+ 0x1B, 0x1E, 0x1C, 0x18, 0x10, 0x00, 0x00, 0xFF,
+ /* kInsertText02 */
+ 0xFF, 0x00, 0x00, 0x18, 0x30, 0x60, 0xC0, 0x80,
+ 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ /* kInsertText03 */
+ 0xFF, 0x01, 0x01, 0x01, 0x01, 0xC1, 0x01, 0x01,
+ 0x01, 0x01, 0xC1, 0x01, 0x01, 0x01, 0x01, 0xFF,
+ /* kInsertText04 */
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00,
+ 0x00, 0x00, 0xC3, 0x00, 0x00, 0x00, 0x00, 0xFF,
+#endif
+#if EnableDemoMsg
+ /* kCellDemo0 */
+ 0xFF, 0x80, 0x80, 0x80, 0x80, 0x83, 0x80, 0x80,
+ 0x80, 0x80, 0x83, 0x80, 0x80, 0x80, 0x80, 0xFF,
+ /* kCellDemo1 */
+ 0xFF, 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x42,
+ 0x42, 0x42, 0x42, 0x7C, 0x00, 0x00, 0x00, 0xFF,
+ /* kCellDemo2 */
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42,
+ 0x7E, 0x40, 0x42, 0x3C, 0x00, 0x00, 0x00, 0xFF,
+ /* kCellDemo3 */
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x92,
+ 0x92, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0xFF,
+ /* kCellDemo4 */
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x42,
+ 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0xFF,
+ /* kCellDemo5 */
+ 0xFF, 0x01, 0x01, 0x01, 0x01, 0xC1, 0x01, 0x01,
+ 0x01, 0x01, 0xC1, 0x01, 0x01, 0x01, 0x01, 0xFF,
+ /* kCellDemo6 */
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00,
+ 0x00, 0x00, 0xC3, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ /* kCellDemo7 */
+ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+#endif
+
+ 0x00 /* just so last above line can end in ',' */
+};
+
+enum {
+ kCellUpA,
+ kCellUpB,
+ kCellUpC,
+ kCellUpD,
+ kCellUpE,
+ kCellUpF,
+ kCellUpG,
+ kCellUpH,
+ kCellUpI,
+ kCellUpJ,
+ kCellUpK,
+ kCellUpL,
+ kCellUpM,
+ kCellUpN,
+ kCellUpO,
+ kCellUpP,
+ kCellUpQ,
+ kCellUpR,
+ kCellUpS,
+ kCellUpT,
+ kCellUpU,
+ kCellUpV,
+ kCellUpW,
+ kCellUpX,
+ kCellUpY,
+ kCellUpZ,
+ kCellLoA,
+ kCellLoB,
+ kCellLoC,
+ kCellLoD,
+ kCellLoE,
+ kCellLoF,
+ kCellLoG,
+ kCellLoH,
+ kCellLoI,
+ kCellLoJ,
+ kCellLoK,
+ kCellLoL,
+ kCellLoM,
+ kCellLoN,
+ kCellLoO,
+ kCellLoP,
+ kCellLoQ,
+ kCellLoR,
+ kCellLoS,
+ kCellLoT,
+ kCellLoU,
+ kCellLoV,
+ kCellLoW,
+ kCellLoX,
+ kCellLoY,
+ kCellLoZ,
+ kCellDigit0,
+ kCellDigit1,
+ kCellDigit2,
+ kCellDigit3,
+ kCellDigit4,
+ kCellDigit5,
+ kCellDigit6,
+ kCellDigit7,
+ kCellDigit8,
+ kCellDigit9,
+ kCellExclamation,
+ kCellAmpersand,
+ kCellApostrophe,
+ kCellLeftParen,
+ kCellRightParen,
+ kCellComma,
+ kCellHyphen,
+ kCellPeriod,
+ kCellSlash,
+ kCellColon,
+ kCellSemicolon,
+ kCellQuestion,
+ kCellEllipsis,
+ kCellUnderscore,
+ kCellLeftDQuote,
+ kCellRightDQuote,
+ kCellLeftSQuote,
+ kCellRightSQuote,
+ kCellCopyright,
+ kCellSpace,
+
+#if NeedIntlChars
+ kCellUpADiaeresis,
+ kCellUpARing,
+ kCellUpCCedilla,
+ kCellUpEAcute,
+ kCellUpNTilde,
+ kCellUpODiaeresis,
+ kCellUpUDiaeresis,
+ kCellLoAAcute,
+ kCellLoAGrave,
+ kCellLoACircumflex,
+ kCellLoADiaeresis,
+ kCellLoATilde,
+ kCellLoARing,
+ kCellLoCCedilla,
+ kCellLoEAcute,
+ kCellLoEGrave,
+ kCellLoECircumflex,
+ kCellLoEDiaeresis,
+ kCellLoIAcute,
+ kCellLoIGrave,
+ kCellLoICircumflex,
+ kCellLoIDiaeresis,
+ kCellLoNTilde,
+ kCellLoOAcute,
+ kCellLoOGrave,
+ kCellLoOCircumflex,
+ kCellLoODiaeresis,
+ kCellLoOTilde,
+ kCellLoUAcute,
+ kCellLoUGrave,
+ kCellLoUCircumflex,
+ kCellLoUDiaeresis,
+
+ kCellUpAE,
+ kCellUpOStroke,
+
+ kCellLoAE,
+ kCellLoOStroke,
+ kCellInvQuestion,
+ kCellInvExclam,
+
+ kCellUpAGrave,
+ kCellUpATilde,
+ kCellUpOTilde,
+ kCellUpLigatureOE,
+ kCellLoLigatureOE,
+
+ kCellLoYDiaeresis,
+ kCellUpYDiaeresis,
+
+ kCellUpACircumflex,
+ kCellUpECircumflex,
+ kCellUpAAcute,
+ kCellUpEDiaeresis,
+ kCellUpEGrave,
+ kCellUpIAcute,
+ kCellUpICircumflex,
+ kCellUpIDiaeresis,
+ kCellUpIGrave,
+ kCellUpOAcute,
+ kCellUpOCircumflex,
+
+ kCellUpOGrave,
+ kCellUpUAcute,
+ kCellUpUCircumflex,
+ kCellUpUGrave,
+ kCellSharpS,
+
+ kCellUpACedille,
+ kCellLoACedille,
+ kCellUpCAcute,
+ kCellLoCAcute,
+ kCellUpECedille,
+ kCellLoECedille,
+ kCellUpLBar,
+ kCellLoLBar,
+ kCellUpNAcute,
+ kCellLoNAcute,
+ kCellUpSAcute,
+ kCellLoSAcute,
+ kCellUpZAcute,
+ kCellLoZAcute,
+ kCellUpZDot,
+ kCellLoZDot,
+ kCellMidDot,
+ kCellUpCCaron,
+ kCellLoCCaron,
+ kCellLoECaron,
+ kCellLoRCaron,
+ kCellLoSCaron,
+ kCellLoTCaron,
+ kCellLoZCaron,
+ kCellUpYAcute,
+ kCellLoYAcute,
+ kCellLoUDblac,
+ kCellLoURing,
+ kCellUpDStroke,
+ kCellLoDStroke,
+#endif
+
+ kCellUpperLeft,
+ kCellUpperMiddle,
+ kCellUpperRight,
+ kCellMiddleLeft,
+ kCellMiddleRight,
+ kCellLowerLeft,
+ kCellLowerMiddle,
+ kCellLowerRight,
+ kCellGraySep,
+ kCellIcon00,
+ kCellIcon01,
+ kCellIcon02,
+ kCellIcon03,
+ kCellIcon10,
+ kCellIcon11,
+ kCellIcon12,
+ kCellIcon13,
+ kCellIcon20,
+ kCellIcon21,
+ kCellIcon22,
+ kCellIcon23,
+#if EnableAltKeysMode
+ kInsertText00,
+ kInsertText01,
+ kInsertText02,
+ kInsertText03,
+ kInsertText04,
+#endif
+#if EnableDemoMsg
+ kCellDemo0,
+ kCellDemo1,
+ kCellDemo2,
+ kCellDemo3,
+ kCellDemo4,
+ kCellDemo5,
+ kCellDemo6,
+ kCellDemo7,
+#endif
+
+ kNumCells
+};
+
+#if UseActvCode && 0
+#define UseActvFile 1
+#else
+#define UseActvFile 0
+#endif
+
+#ifndef NeedCell2MacAsciiMap
+#if 1 /* UseActvCode || EnableDemoMsg */
+#define NeedCell2MacAsciiMap 1
+#else
+#define NeedCell2MacAsciiMap 0
+#endif
+#endif
+
+#if NeedCell2MacAsciiMap
+/* Mac Roman character set */
+LOCALVAR const char Cell2MacAsciiMap[] = {
+ '\101', /* kCellUpA */
+ '\102', /* kCellUpB */
+ '\103', /* kCellUpC */
+ '\104', /* kCellUpD */
+ '\105', /* kCellUpE */
+ '\106', /* kCellUpF */
+ '\107', /* kCellUpG */
+ '\110', /* kCellUpH */
+ '\111', /* kCellUpI */
+ '\112', /* kCellUpJ */
+ '\113', /* kCellUpK */
+ '\114', /* kCellUpL */
+ '\115', /* kCellUpM */
+ '\116', /* kCellUpN */
+ '\117', /* kCellUpO */
+ '\120', /* kCellUpP */
+ '\121', /* kCellUpQ */
+ '\122', /* kCellUpR */
+ '\123', /* kCellUpS */
+ '\124', /* kCellUpT */
+ '\125', /* kCellUpU */
+ '\126', /* kCellUpV */
+ '\127', /* kCellUpW */
+ '\130', /* kCellUpX */
+ '\131', /* kCellUpY */
+ '\132', /* kCellUpZ */
+ '\141', /* kCellLoA */
+ '\142', /* kCellLoB */
+ '\143', /* kCellLoC */
+ '\144', /* kCellLoD */
+ '\145', /* kCellLoE */
+ '\146', /* kCellLoF */
+ '\147', /* kCellLoG */
+ '\150', /* kCellLoH */
+ '\151', /* kCellLoI */
+ '\152', /* kCellLoJ */
+ '\153', /* kCellLoK */
+ '\154', /* kCellLoL */
+ '\155', /* kCellLoM */
+ '\156', /* kCellLoN */
+ '\157', /* kCellLoO */
+ '\160', /* kCellLoP */
+ '\161', /* kCellLoQ */
+ '\162', /* kCellLoR */
+ '\163', /* kCellLoS */
+ '\164', /* kCellLoT */
+ '\165', /* kCellLoU */
+ '\166', /* kCellLoV */
+ '\167', /* kCellLoW */
+ '\170', /* kCellLoX */
+ '\171', /* kCellLoY */
+ '\172', /* kCellLoZ */
+ '\060', /* kCellDigit0 */
+ '\061', /* kCellDigit1 */
+ '\062', /* kCellDigit2 */
+ '\063', /* kCellDigit3 */
+ '\064', /* kCellDigit4 */
+ '\065', /* kCellDigit5 */
+ '\066', /* kCellDigit6 */
+ '\067', /* kCellDigit7 */
+ '\070', /* kCellDigit8 */
+ '\071', /* kCellDigit9 */
+ '\041', /* kCellExclamation */
+ '\046', /* kCellAmpersand */
+ '\047', /* kCellApostrophe */
+ '\050', /* kCellLeftParen */
+ '\051', /* kCellRightParen */
+ '\054', /* kCellComma */
+ '\055', /* kCellHyphen */
+ '\056', /* kCellPeriod */
+ '\057', /* kCellSlash */
+ '\072', /* kCellColon */
+ '\073', /* kCellSemicolon */
+ '\077', /* kCellQuestion */
+ '\311', /* kCellEllipsis */
+ '\137', /* kCellUnderscore */
+ '\322', /* kCellLeftDQuote */
+ '\323', /* kCellRightDQuote */
+ '\324', /* kCellLeftSQuote */
+ '\325', /* kCellRightSQuote */
+ '\251', /* kCellCopyright */
+ '\040', /* kCellSpace */
+
+#if NeedIntlChars
+ '\200', /* kCellUpADiaeresis */
+ '\201', /* kCellUpARing */
+ '\202', /* kCellUpCCedilla */
+ '\203', /* kCellUpEAcute */
+ '\204', /* kCellUpNTilde */
+ '\205', /* kCellUpODiaeresis */
+ '\206', /* kCellUpUDiaeresis */
+ '\207', /* kCellLoAAcute */
+ '\210', /* kCellLoAGrave */
+ '\211', /* kCellLoACircumflex */
+ '\212', /* kCellLoADiaeresis */
+ '\213', /* kCellLoATilde */
+ '\214', /* kCellLoARing */
+ '\215', /* kCellLoCCedilla */
+ '\216', /* kCellLoEAcute */
+ '\217', /* kCellLoEGrave */
+ '\220', /* kCellLoECircumflex */
+ '\221', /* kCellLoEDiaeresis */
+ '\222', /* kCellLoIAcute */
+ '\223', /* kCellLoIGrave */
+ '\224', /* kCellLoICircumflex */
+ '\225', /* kCellLoIDiaeresis */
+ '\226', /* kCellLoNTilde */
+ '\227', /* kCellLoOAcute */
+ '\230', /* kCellLoOGrave */
+ '\231', /* kCellLoOCircumflex */
+ '\232', /* kCellLoODiaeresis */
+ '\233', /* kCellLoOTilde */
+ '\234', /* kCellLoUAcute */
+ '\235', /* kCellLoUGrave */
+ '\236', /* kCellLoUCircumflex */
+ '\237', /* kCellLoUDiaeresis */
+
+ '\256', /* kCellUpAE */
+ '\257', /* kCellUpOStroke */
+
+ '\276', /* kCellLoAE */
+ '\277', /* kCellLoOStroke */
+ '\300', /* kCellInvQuestion */
+ '\301', /* kCellInvExclam */
+
+ '\313', /* kCellUpAGrave */
+ '\314', /* kCellUpATilde */
+ '\315', /* kCellUpOTilde */
+ '\316', /* kCellUpLigatureOE */
+ '\317', /* kCellLoLigatureOE */
+
+ '\330', /* kCellLoYDiaeresis */
+ '\331', /* kCellUpYDiaeresis */
+
+ '\345', /* kCellUpACircumflex */
+ '\346', /* kCellUpECircumflex */
+ '\347', /* kCellUpAAcute */
+ '\350', /* kCellUpEDiaeresis */
+ '\351', /* kCellUpEGrave */
+ '\352', /* kCellUpIAcute */
+ '\353', /* kCellUpICircumflex */
+ '\354', /* kCellUpIDiaeresis */
+ '\355', /* kCellUpIGrave */
+ '\356', /* kCellUpOAcute */
+ '\357', /* kCellUpOCircumflex */
+
+ '\361', /* kCellUpOGrave */
+ '\362', /* kCellUpUAcute */
+ '\363', /* kCellUpUCircumflex */
+ '\364', /* kCellUpUGrave */
+ '\247', /* kCellSharpS */
+
+ '\260', /* kCellUpACedille */
+ '\261', /* kCellLoACedille */
+ '\262', /* kCellUpCAcute */
+ '\263', /* kCellLoCAcute */
+ '\264', /* kCellUpECedille */
+ '\265', /* kCellLoECedille */
+ '\266', /* kCellUpLBar */
+ '\267', /* kCellLoLBar */
+ '\270', /* kCellUpNAcute */
+ '\271', /* kCellLoNAcute */
+ '\272', /* kCellUpSAcute */
+ '\273', /* kCellLoSAcute */
+ '\274', /* kCellUpZAcute */
+ '\275', /* kCellLoZAcute */
+ '\276', /* kCellUpZDot */
+ '\277', /* kCellLoZDot */
+ '\341', /* kCellMidDot */
+ '\103', /* kCellUpCCaron */
+ '\143', /* kCellLoCCaron */
+ '\145', /* kCellLoECaron */
+ '\162', /* kCellLoRCaron */
+ '\163', /* kCellLoSCaron */
+ '\164', /* kCellLoTCaron */
+ '\172', /* kCellLoZCaron */
+ '\131', /* kCellUpYAcute */
+ '\171', /* kCellLoYAcute */
+ '\165', /* kCellLoUDblac */
+ '\165', /* kCellLoURing */
+ '\104', /* kCellUpDStroke */
+ '\144', /* kCellLoDStroke */
+#endif
+
+ '\0' /* just so last above line can end in ',' */
+};
+#endif
+
+#ifndef NeedCell2WinAsciiMap
+#define NeedCell2WinAsciiMap 0
+#endif
+
+#if NeedCell2WinAsciiMap
+/* Windows character set (windows-1252 code page) */
+LOCALVAR const ui3b Cell2WinAsciiMap[] = {
+ 0x41, /* kCellUpA */
+ 0x42, /* kCellUpB */
+ 0x43, /* kCellUpC */
+ 0x44, /* kCellUpD */
+ 0x45, /* kCellUpE */
+ 0x46, /* kCellUpF */
+ 0x47, /* kCellUpG */
+ 0x48, /* kCellUpH */
+ 0x49, /* kCellUpI */
+ 0x4A, /* kCellUpJ */
+ 0x4B, /* kCellUpK */
+ 0x4C, /* kCellUpL */
+ 0x4D, /* kCellUpM */
+ 0x4E, /* kCellUpN */
+ 0x4F, /* kCellUpO */
+ 0x50, /* kCellUpP */
+ 0x51, /* kCellUpQ */
+ 0x52, /* kCellUpR */
+ 0x53, /* kCellUpS */
+ 0x54, /* kCellUpT */
+ 0x55, /* kCellUpU */
+ 0x56, /* kCellUpV */
+ 0x57, /* kCellUpW */
+ 0x58, /* kCellUpX */
+ 0x59, /* kCellUpY */
+ 0x5A, /* kCellUpZ */
+ 0x61, /* kCellLoA */
+ 0x62, /* kCellLoB */
+ 0x63, /* kCellLoC */
+ 0x64, /* kCellLoD */
+ 0x65, /* kCellLoE */
+ 0x66, /* kCellLoF */
+ 0x67, /* kCellLoG */
+ 0x68, /* kCellLoH */
+ 0x69, /* kCellLoI */
+ 0x6A, /* kCellLoJ */
+ 0x6B, /* kCellLoK */
+ 0x6C, /* kCellLoL */
+ 0x6D, /* kCellLoM */
+ 0x6E, /* kCellLoN */
+ 0x6F, /* kCellLoO */
+ 0x70, /* kCellLoP */
+ 0x71, /* kCellLoQ */
+ 0x72, /* kCellLoR */
+ 0x73, /* kCellLoS */
+ 0x74, /* kCellLoT */
+ 0x75, /* kCellLoU */
+ 0x76, /* kCellLoV */
+ 0x77, /* kCellLoW */
+ 0x78, /* kCellLoX */
+ 0x79, /* kCellLoY */
+ 0x7A, /* kCellLoZ */
+ 0x30, /* kCellDigit0 */
+ 0x31, /* kCellDigit1 */
+ 0x32, /* kCellDigit2 */
+ 0x33, /* kCellDigit3 */
+ 0x34, /* kCellDigit4 */
+ 0x35, /* kCellDigit5 */
+ 0x36, /* kCellDigit6 */
+ 0x37, /* kCellDigit7 */
+ 0x38, /* kCellDigit8 */
+ 0x39, /* kCellDigit9 */
+ 0x21, /* kCellExclamation */
+ 0x26, /* kCellAmpersand */
+ 0x27, /* kCellApostrophe */
+ 0x28, /* kCellLeftParen */
+ 0x29, /* kCellRightParen */
+ 0x2C, /* kCellComma */
+ 0x2D, /* kCellHyphen */
+ 0x2E, /* kCellPeriod */
+ 0x2F, /* kCellSlash */
+ 0x3A, /* kCellColon */
+ 0x3B, /* kCellSemicolon */
+ 0x3F, /* kCellQuestion */
+ 0x85, /* kCellEllipsis */
+ 0x5F, /* kCellUnderscore */
+ 0x93, /* kCellLeftDQuote */
+ 0x94, /* kCellRightDQuote */
+ 0x91, /* kCellLeftSQuote */
+ 0x92, /* kCellRightSQuote */
+ 0xA9, /* kCellCopyright */
+ 0x20, /* kCellSpace */
+
+#if NeedIntlChars
+ 0xC4, /* kCellUpADiaeresis */
+ 0xC5, /* kCellUpARing */
+ 0xC7, /* kCellUpCCedilla */
+ 0xC9, /* kCellUpEAcute */
+ 0xD1, /* kCellUpNTilde */
+ 0xD6, /* kCellUpODiaeresis */
+ 0xDC, /* kCellUpUDiaeresis */
+ 0xE1, /* kCellLoAAcute */
+ 0xE0, /* kCellLoAGrave */
+ 0xE2, /* kCellLoACircumflex */
+ 0xE4, /* kCellLoADiaeresis */
+ 0xE3, /* kCellLoATilde */
+ 0xE5, /* kCellLoARing */
+ 0xE7, /* kCellLoCCedilla */
+ 0xE9, /* kCellLoEAcute */
+ 0xE8, /* kCellLoEGrave */
+ 0xEA, /* kCellLoECircumflex */
+ 0xEB, /* kCellLoEDiaeresis */
+ 0xED, /* kCellLoIAcute */
+ 0xEC, /* kCellLoIGrave */
+ 0xEE, /* kCellLoICircumflex */
+ 0xEF, /* kCellLoIDiaeresis */
+ 0xF1, /* kCellLoNTilde */
+ 0xF3, /* kCellLoOAcute */
+ 0xF2, /* kCellLoOGrave */
+ 0xF4, /* kCellLoOCircumflex */
+ 0xF6, /* kCellLoODiaeresis */
+ 0xF5, /* kCellLoOTilde */
+ 0xFA, /* kCellLoUAcute */
+ 0xF9, /* kCellLoUGrave */
+ 0xFB, /* kCellLoUCircumflex */
+ 0xFC, /* kCellLoUDiaeresis */
+
+ 0xC6, /* kCellUpAE */
+ 0xD8, /* kCellUpOStroke */
+
+ 0xE6, /* kCellLoAE */
+ 0xF8, /* kCellLoOStroke */
+ 0xBF, /* kCellInvQuestion */
+ 0xA1, /* kCellInvExclam */
+
+ 0xC0, /* kCellUpAGrave */
+ 0xC3, /* kCellUpATilde */
+ 0xD5, /* kCellUpOTilde */
+ 0x8C, /* kCellUpLigatureOE */
+ 0x9C, /* kCellLoLigatureOE */
+
+ 0xFF, /* kCellLoYDiaeresis */
+ 0x9F, /* kCellUpYDiaeresis */
+
+ 0xC2, /* kCellUpACircumflex */
+ 0xCA, /* kCellUpECircumflex */
+ 0xC1, /* kCellUpAAcute */
+ 0xCB, /* kCellUpEDiaeresis */
+ 0xC8, /* kCellUpEGrave */
+ 0xCD, /* kCellUpIAcute */
+ 0xCE, /* kCellUpICircumflex */
+ 0xCF, /* kCellUpIDiaeresis */
+ 0xCC, /* kCellUpIGrave */
+ 0xD3, /* kCellUpOAcute */
+ 0xD4, /* kCellUpOCircumflex */
+
+ 0xD2, /* kCellUpOGrave */
+ 0xDA, /* kCellUpUAcute */
+ 0xDB, /* kCellUpUCircumflex */
+ 0xD9, /* kCellUpUGrave */
+ 0xDF, /* kCellSharpS */
+
+ 0x41, /* kCellUpACedille */
+ 0x61, /* kCellLoACedille */
+ 0x43, /* kCellUpCAcute */
+ 0x63, /* kCellLoCAcute */
+ 0x45, /* kCellUpECedille */
+ 0x65, /* kCellLoECedille */
+ 0x4C, /* kCellUpLBar */
+ 0x6C, /* kCellLoLBar */
+ 0x4E, /* kCellUpNAcute */
+ 0x6E, /* kCellLoNAcute */
+ 0x53, /* kCellUpSAcute */
+ 0x73, /* kCellLoSAcute */
+ 0x5A, /* kCellUpZAcute */
+ 0x7A, /* kCellLoZAcute */
+ 0x5A, /* kCellUpZDot */
+ 0x7A, /* kCellLoZDot */
+ 0xB7, /* kCellMidDot */
+ 0x43, /* kCellUpCCaron */
+ 0x63, /* kCellLoCCaron */
+ 0x65, /* kCellLoECaron */
+ 0x61, /* kCellLoRCaron */
+ 0x9A, /* kCellLoSCaron */
+ 0x74, /* kCellLoTCaron */
+ 0x9E, /* kCellLoZCaron */
+ 0xDD, /* kCellUpYAcute */
+ 0xFD, /* kCellLoYAcute */
+ 0x75, /* kCellLoUDblac */
+ 0x75, /* kCellLoURing */
+ 0x44, /* kCellUpDStroke */
+ 0x64, /* kCellLoDStroke */
+#endif
+
+ '\0' /* just so last above line can end in ',' */
+};
+#endif
+
+#ifndef NeedCell2PlainAsciiMap
+#define NeedCell2PlainAsciiMap 0
+#endif
+
+#if NeedCell2PlainAsciiMap
+/* Plain ascii - remove accents when possible */
+LOCALVAR const char Cell2PlainAsciiMap[] = {
+ 'A', /* kCellUpA */
+ 'B', /* kCellUpB */
+ 'C', /* kCellUpC */
+ 'D', /* kCellUpD */
+ 'E', /* kCellUpE */
+ 'F', /* kCellUpF */
+ 'G', /* kCellUpG */
+ 'H', /* kCellUpH */
+ 'I', /* kCellUpI */
+ 'J', /* kCellUpJ */
+ 'K', /* kCellUpK */
+ 'L', /* kCellUpL */
+ 'M', /* kCellUpM */
+ 'N', /* kCellUpN */
+ 'O', /* kCellUpO */
+ 'P', /* kCellUpP */
+ 'Q', /* kCellUpQ */
+ 'R', /* kCellUpR */
+ 'S', /* kCellUpS */
+ 'T', /* kCellUpT */
+ 'U', /* kCellUpU */
+ 'V', /* kCellUpV */
+ 'W', /* kCellUpW */
+ 'X', /* kCellUpX */
+ 'Y', /* kCellUpY */
+ 'Z', /* kCellUpZ */
+ 'a', /* kCellLoA */
+ 'b', /* kCellLoB */
+ 'c', /* kCellLoC */
+ 'd', /* kCellLoD */
+ 'e', /* kCellLoE */
+ 'f', /* kCellLoF */
+ 'g', /* kCellLoG */
+ 'h', /* kCellLoH */
+ 'i', /* kCellLoI */
+ 'j', /* kCellLoJ */
+ 'k', /* kCellLoK */
+ 'l', /* kCellLoL */
+ 'm', /* kCellLoM */
+ 'n', /* kCellLoN */
+ 'o', /* kCellLoO */
+ 'p', /* kCellLoP */
+ 'q', /* kCellLoQ */
+ 'r', /* kCellLoR */
+ 's', /* kCellLoS */
+ 't', /* kCellLoT */
+ 'u', /* kCellLoU */
+ 'v', /* kCellLoV */
+ 'w', /* kCellLoW */
+ 'x', /* kCellLoX */
+ 'y', /* kCellLoY */
+ 'z', /* kCellLoZ */
+ '0', /* kCellDigit0 */
+ '1', /* kCellDigit1 */
+ '2', /* kCellDigit2 */
+ '3', /* kCellDigit3 */
+ '4', /* kCellDigit4 */
+ '5', /* kCellDigit5 */
+ '6', /* kCellDigit6 */
+ '7', /* kCellDigit7 */
+ '8', /* kCellDigit8 */
+ '9', /* kCellDigit9 */
+ '!', /* kCellExclamation */
+ '&', /* kCellAmpersand */
+ '\047', /* kCellApostrophe */
+ '(', /* kCellLeftParen */
+ ')', /* kCellRightParen */
+ ',', /* kCellComma */
+ '-', /* kCellHyphen */
+ '.', /* kCellPeriod */
+ '/', /* kCellSlash */
+ ':', /* kCellColon */
+ ';', /* kCellSemicolon */
+ '?', /* kCellQuestion */
+ '_', /* kCellEllipsis */
+ '_', /* kCellUnderscore */
+ '"', /* kCellLeftDQuote */
+ '"', /* kCellRightDQuote */
+ '\047', /* kCellLeftSQuote */
+ '\047', /* kCellRightSQuote */
+ 'c', /* kCellCopyright */
+ ' ', /* kCellSpace */
+
+#if NeedIntlChars
+ 'A', /* kCellUpADiaeresis */
+ 'A', /* kCellUpARing */
+ 'C', /* kCellUpCCedilla */
+ 'E', /* kCellUpEAcute */
+ 'N', /* kCellUpNTilde */
+ 'O', /* kCellUpODiaeresis */
+ 'U', /* kCellUpUDiaeresis */
+ 'a', /* kCellLoAAcute */
+ 'a', /* kCellLoAGrave */
+ 'a', /* kCellLoACircumflex */
+ 'a', /* kCellLoADiaeresis */
+ 'a', /* kCellLoATilde */
+ 'a', /* kCellLoARing */
+ 'c', /* kCellLoCCedilla */
+ 'e', /* kCellLoEAcute */
+ 'e', /* kCellLoEGrave */
+ 'e', /* kCellLoECircumflex */
+ 'e', /* kCellLoEDiaeresis */
+ 'i', /* kCellLoIAcute */
+ 'i', /* kCellLoIGrave */
+ 'i', /* kCellLoICircumflex */
+ 'i', /* kCellLoIDiaeresis */
+ 'n', /* kCellLoNTilde */
+ 'o', /* kCellLoOAcute */
+ 'o', /* kCellLoOGrave */
+ 'o', /* kCellLoOCircumflex */
+ 'o', /* kCellLoODiaeresis */
+ 'o', /* kCellLoOTilde */
+ 'u', /* kCellLoUAcute */
+ 'u', /* kCellLoUGrave */
+ 'u', /* kCellLoUCircumflex */
+ 'u', /* kCellLoUDiaeresis */
+
+ '?', /* kCellUpAE */
+ 'O', /* kCellUpOStroke */
+
+ '?', /* kCellLoAE */
+ 'o', /* kCellLoOStroke */
+ '?', /* kCellInvQuestion */
+ '!', /* kCellInvExclam */
+
+ 'A', /* kCellUpAGrave */
+ 'A', /* kCellUpATilde */
+ 'O', /* kCellUpOTilde */
+ '?', /* kCellUpLigatureOE */
+ '?', /* kCellLoLigatureOE */
+
+ 'y', /* kCellLoYDiaeresis */
+ 'Y', /* kCellUpYDiaeresis */
+
+ 'A', /* kCellUpACircumflex */
+ 'E', /* kCellUpECircumflex */
+ 'A', /* kCellUpAAcute */
+ 'E', /* kCellUpEDiaeresis */
+ 'E', /* kCellUpEGrave */
+ 'A', /* kCellUpIAcute */
+ 'I', /* kCellUpICircumflex */
+ 'I', /* kCellUpIDiaeresis */
+ 'I', /* kCellUpIGrave */
+ 'O', /* kCellUpOAcute */
+ 'O', /* kCellUpOCircumflex */
+
+ 'O', /* kCellUpOGrave */
+ 'U', /* kCellUpUAcute */
+ 'U', /* kCellUpUCircumflex */
+ 'U', /* kCellUpUGrave */
+ 'B', /* kCellSharpS */
+
+ 'A', /* kCellUpACedille */
+ 'a', /* kCellLoACedille */
+ 'C', /* kCellUpCAcute */
+ 'c', /* kCellLoCAcute */
+ 'E', /* kCellUpECedille */
+ 'e', /* kCellLoECedille */
+ 'L', /* kCellUpLBar */
+ 'l', /* kCellLoLBar */
+ 'N', /* kCellUpNAcute */
+ 'n', /* kCellLoNAcute */
+ 'S', /* kCellUpSAcute */
+ 's', /* kCellLoSAcute */
+ 'Z', /* kCellUpZAcute */
+ 'z', /* kCellLoZAcute */
+ 'Z', /* kCellUpZDot */
+ 'z', /* kCellLoZDot */
+ '.', /* kCellMidDot */
+ 'C', /* kCellUpCCaron */
+ 'c', /* kCellLoCCaron */
+ 'e', /* kCellLoECaron */
+ 'r', /* kCellLoRCaron */
+ 's', /* kCellLoSCaron */
+ 't', /* kCellLoTCaron */
+ 'z', /* kCellLoZCaron */
+ 'Y', /* kCellUpYAcute */
+ 'y', /* kCellLoYAcute */
+ 'u', /* kCellLoUDblac */
+ 'u', /* kCellLoURing */
+ 'D', /* kCellUpDStroke */
+ 'd', /* kCellLoDStroke */
+#endif
+
+ '\0' /* just so last above line can end in ',' */
+};
+#endif
+
+#ifndef NeedCell2UnicodeMap
+#define NeedCell2UnicodeMap 0
+#endif
+
+#if NeedCell2UnicodeMap
+/* Unicode character set */
+LOCALVAR const ui4b Cell2UnicodeMap[] = {
+ 0x0041, /* kCellUpA */
+ 0x0042, /* kCellUpB */
+ 0x0043, /* kCellUpC */
+ 0x0044, /* kCellUpD */
+ 0x0045, /* kCellUpE */
+ 0x0046, /* kCellUpF */
+ 0x0047, /* kCellUpG */
+ 0x0048, /* kCellUpH */
+ 0x0049, /* kCellUpI */
+ 0x004A, /* kCellUpJ */
+ 0x004B, /* kCellUpK */
+ 0x004C, /* kCellUpL */
+ 0x004D, /* kCellUpM */
+ 0x004E, /* kCellUpN */
+ 0x004F, /* kCellUpO */
+ 0x0050, /* kCellUpP */
+ 0x0051, /* kCellUpQ */
+ 0x0052, /* kCellUpR */
+ 0x0053, /* kCellUpS */
+ 0x0054, /* kCellUpT */
+ 0x0055, /* kCellUpU */
+ 0x0056, /* kCellUpV */
+ 0x0057, /* kCellUpW */
+ 0x0058, /* kCellUpX */
+ 0x0059, /* kCellUpY */
+ 0x005A, /* kCellUpZ */
+ 0x0061, /* kCellLoA */
+ 0x0062, /* kCellLoB */
+ 0x0063, /* kCellLoC */
+ 0x0064, /* kCellLoD */
+ 0x0065, /* kCellLoE */
+ 0x0066, /* kCellLoF */
+ 0x0067, /* kCellLoG */
+ 0x0068, /* kCellLoH */
+ 0x0069, /* kCellLoI */
+ 0x006A, /* kCellLoJ */
+ 0x006B, /* kCellLoK */
+ 0x006C, /* kCellLoL */
+ 0x006D, /* kCellLoM */
+ 0x006E, /* kCellLoN */
+ 0x006F, /* kCellLoO */
+ 0x0070, /* kCellLoP */
+ 0x0071, /* kCellLoQ */
+ 0x0072, /* kCellLoR */
+ 0x0073, /* kCellLoS */
+ 0x0074, /* kCellLoT */
+ 0x0075, /* kCellLoU */
+ 0x0076, /* kCellLoV */
+ 0x0077, /* kCellLoW */
+ 0x0078, /* kCellLoX */
+ 0x0079, /* kCellLoY */
+ 0x007A, /* kCellLoZ */
+ 0x0030, /* kCellDigit0 */
+ 0x0031, /* kCellDigit1 */
+ 0x0032, /* kCellDigit2 */
+ 0x0033, /* kCellDigit3 */
+ 0x0034, /* kCellDigit4 */
+ 0x0035, /* kCellDigit5 */
+ 0x0036, /* kCellDigit6 */
+ 0x0037, /* kCellDigit7 */
+ 0x0038, /* kCellDigit8 */
+ 0x0039, /* kCellDigit9 */
+ 0x0021, /* kCellExclamation */
+ 0x0026, /* kCellAmpersand */
+ 0x0027, /* kCellApostrophe */
+ 0x0028, /* kCellLeftParen */
+ 0x0029, /* kCellRightParen */
+ 0x002C, /* kCellComma */
+ 0x002D, /* kCellHyphen */
+ 0x002E, /* kCellPeriod */
+ 0x002F, /* kCellSlash */
+ 0x003A, /* kCellColon */
+ 0x003B, /* kCellSemicolon */
+ 0x003F, /* kCellQuestion */
+ 0x2026, /* kCellEllipsis */
+ 0x005F, /* kCellUnderscore */
+ 0x201C, /* kCellLeftDQuote */
+ 0x201D, /* kCellRightDQuote */
+ 0x2018, /* kCellLeftSQuote */
+ 0x2019, /* kCellRightSQuote */
+ 0x00A9, /* kCellCopyright */
+ 0x0020, /* kCellSpace */
+
+#if NeedIntlChars
+ 0x00C4, /* kCellUpADiaeresis */
+ 0x00C5, /* kCellUpARing */
+ 0x00C7, /* kCellUpCCedilla */
+ 0x00C9, /* kCellUpEAcute */
+ 0x00D1, /* kCellUpNTilde */
+ 0x00D6, /* kCellUpODiaeresis */
+ 0x00DC, /* kCellUpUDiaeresis */
+ 0x00E1, /* kCellLoAAcute */
+ 0x00E0, /* kCellLoAGrave */
+ 0x00E2, /* kCellLoACircumflex */
+ 0x00E4, /* kCellLoADiaeresis */
+ 0x00E3, /* kCellLoATilde */
+ 0x00E5, /* kCellLoARing */
+ 0x00E7, /* kCellLoCCedilla */
+ 0x00E9, /* kCellLoEAcute */
+ 0x00E8, /* kCellLoEGrave */
+ 0x00EA, /* kCellLoECircumflex */
+ 0x00EB, /* kCellLoEDiaeresis */
+ 0x00ED, /* kCellLoIAcute */
+ 0x00EC, /* kCellLoIGrave */
+ 0x00EE, /* kCellLoICircumflex */
+ 0x00EF, /* kCellLoIDiaeresis */
+ 0x00F1, /* kCellLoNTilde */
+ 0x00F3, /* kCellLoOAcute */
+ 0x00F2, /* kCellLoOGrave */
+ 0x00F4, /* kCellLoOCircumflex */
+ 0x00F6, /* kCellLoODiaeresis */
+ 0x00F5, /* kCellLoOTilde */
+ 0x00FA, /* kCellLoUAcute */
+ 0x00F9, /* kCellLoUGrave */
+ 0x00FB, /* kCellLoUCircumflex */
+ 0x00FC, /* kCellLoUDiaeresis */
+
+ 0x00C6, /* kCellUpAE */
+ 0x00D8, /* kCellUpOStroke */
+
+ 0x00E6, /* kCellLoAE */
+ 0x00F8, /* kCellLoOStroke */
+ 0x00BF, /* kCellInvQuestion */
+ 0x00A1, /* kCellInvExclam */
+
+ 0x00C0, /* kCellUpAGrave */
+ 0x00C3, /* kCellUpATilde */
+ 0x00D5, /* kCellUpOTilde */
+ 0x0152, /* kCellUpLigatureOE */
+ 0x0153, /* kCellLoLigatureOE */
+
+ 0x00FF, /* kCellLoYDiaeresis */
+ 0x0178, /* kCellUpYDiaeresis */
+
+ 0x00C2, /* kCellUpACircumflex */
+ 0x00CA, /* kCellUpECircumflex */
+ 0x00C1, /* kCellUpAAcute */
+ 0x00CB, /* kCellUpEDiaeresis */
+ 0x00C8, /* kCellUpEGrave */
+ 0x00CD, /* kCellUpIAcute */
+ 0x00CE, /* kCellUpICircumflex */
+ 0x00CF, /* kCellUpIDiaeresis */
+ 0x00CC, /* kCellUpIGrave */
+ 0x00D3, /* kCellUpOAcute */
+ 0x00D4, /* kCellUpOCircumflex */
+
+ 0x00D2, /* kCellUpOGrave */
+ 0x00DA, /* kCellUpUAcute */
+ 0x00DB, /* kCellUpUCircumflex */
+ 0x00D9, /* kCellUpUGrave */
+ 0x00DF, /* kCellSharpS */
+
+ 0x0104, /* kCellUpACedille */
+ 0x0105, /* kCellLoACedille */
+ 0x0106, /* kCellUpCAcute */
+ 0x0107, /* kCellLoCAcute */
+ 0x0118, /* kCellUpECedille */
+ 0x0119, /* kCellLoECedille */
+ 0x0141, /* kCellUpLBar */
+ 0x0142, /* kCellLoLBar */
+ 0x0143, /* kCellUpNAcute */
+ 0x0144, /* kCellLoNAcute */
+ 0x015A, /* kCellUpSAcute */
+ 0x015B, /* kCellLoSAcute */
+ 0x0179, /* kCellUpZAcute */
+ 0x017A, /* kCellLoZAcute */
+ 0x017B, /* kCellUpZDot */
+ 0x017C, /* kCellLoZDot */
+ 0x00B7, /* kCellMidDot */
+ 0x010C, /* kCellUpCCaron */
+ 0x010D, /* kCellLoCCaron */
+ 0x011B, /* kCellLoECaron */
+ 0x0159, /* kCellLoRCaron */
+ 0x0161, /* kCellLoSCaron */
+ 0x0165, /* kCellLoTCaron */
+ 0x017E, /* kCellLoZCaron */
+ 0x00DD, /* kCellUpYAcute */
+ 0x00FD, /* kCellLoYAcute */
+ 0x0171, /* kCellLoUDblac */
+ 0x016F, /* kCellLoURing */
+ 0x0110, /* kCellUpDStroke */
+ 0x0111, /* kCellLoDStroke */
+#endif
+
+ '\0' /* just so last above line can end in ',' */
+};
+#endif
+
+LOCALVAR blnr SpeedStopped = falseblnr;
+
+LOCALVAR blnr RunInBackground = (WantInitRunInBackground != 0);
+
+#if VarFullScreen
+LOCALVAR blnr WantFullScreen = (WantInitFullScreen != 0);
+#endif
+
+#if EnableMagnify
+LOCALVAR blnr WantMagnify = (WantInitMagnify != 0);
+#endif
+
+#if NeedRequestInsertDisk
+LOCALVAR blnr RequestInsertDisk = falseblnr;
+#endif
+
+#ifndef NeedRequestIthDisk
+#define NeedRequestIthDisk 0
+#endif
+
+#if NeedRequestIthDisk
+LOCALVAR ui3r RequestIthDisk = 0;
+#endif
+
+#if UseControlKeys
+LOCALVAR blnr ControlKeyPressed = falseblnr;
+#endif
+
+#ifndef kStrCntrlKyName
+#define kStrCntrlKyName "control"
+#endif
+
+#ifndef kControlModeKey
+#define kControlModeKey kStrCntrlKyName
+#endif
+
+#ifndef kUnMappedKey
+#define kUnMappedKey kStrCntrlKyName
+#endif
+
+LOCALFUNC char * GetSubstitutionStr(char x)
+{
+ char *s;
+
+ switch (x) {
+ case 'w':
+ s = kStrHomePage;
+ break;
+ case 'y':
+ s = kStrCopyrightYear;
+ break;
+ case 'p':
+ s = kStrAppName;
+ break;
+ case 'v':
+ s = kAppVariationStr;
+ break;
+ case 'r':
+ s = RomFileName;
+ break;
+ case 'c':
+ s = kControlModeKey;
+ break;
+ case 'm':
+ s = kUnMappedKey;
+ break;
+#if UseControlKeys
+ case 'k':
+ if (ControlKeyPressed) {
+ s = kStrPressed;
+ } else {
+ s = kStrReleased;
+ }
+ break;
+#endif
+#if EnableMagnify
+ case 'g':
+ if (WantMagnify) {
+ s = kStrOn;
+ } else {
+ s = kStrOff;
+ }
+ break;
+#endif
+#if VarFullScreen
+ case 'f':
+ if (WantFullScreen) {
+ s = kStrOn;
+ } else {
+ s = kStrOff;
+ }
+ break;
+#endif
+ case 'b':
+ if (RunInBackground) {
+ s = kStrOn;
+ } else {
+ s = kStrOff;
+ }
+ break;
+ case 'h':
+ if (SpeedStopped) {
+ s = kStrStoppedOn;
+ } else {
+ s = kStrStoppedOff;
+ }
+ break;
+#if EnableAutoSlow
+ case 'l':
+ if (WantNotAutoSlow) {
+ s = kStrStoppedOff;
+ } else {
+ s = kStrStoppedOn;
+ }
+ break;
+#endif
+ case 's':
+ switch (SpeedValue) {
+ case 0:
+ s = "1x";
+ break;
+ case 1:
+ s = "2x";
+ break;
+ case 2:
+ s = "4x";
+ break;
+ case 3:
+ s = "8x";
+ break;
+ case 4:
+ s = "16x";
+ break;
+ case 5:
+ s = "32x";
+ break;
+ default:
+ s = kStrSpeedValueAllOut;
+ break;
+ }
+ break;
+ default:
+ s = "???";
+ break;
+ }
+ return s;
+}
+
+LOCALFUNC int ClStrSizeSubstCStr(char *s)
+{
+ /* must match ClStrAppendSubstCStr ! */
+
+ char *p = s;
+ char c;
+ int L = 0;
+
+ while (0 != (c = *p++)) {
+ if ('^' == c) {
+ if (0 == (c = *p++)) {
+ goto l_exit; /* oops, unexpected end of string, abort */
+ } else if ('^' == c) {
+ ++L;
+ } else {
+ L += ClStrSizeSubstCStr(GetSubstitutionStr(c));
+ }
+ } else if (';' == c) {
+ if (0 == (c = *p++)) {
+ goto l_exit; /* oops, unexpected end of string, abort */
+ }
+
+ switch (c) {
+ case 'l':
+#if NeedIntlChars
+ case '`':
+ case 'd':
+ case 'e':
+ case 'i':
+ case 'n':
+ case 'u':
+ case 'v':
+ case 'E':
+ case 'r':
+#endif
+ if (0 == (c = *p++)) {
+ /* oops, unexpected end of string, abort */
+ goto l_exit;
+ }
+ break;
+ default:
+ break;
+ }
+ ++L;
+ } else {
+ ++L;
+ }
+ }
+
+l_exit:
+ return L;
+}
+
+LOCALPROC ClStrAppendChar(int *L0, ui3b *r, ui3b c)
+{
+ int L = *L0;
+
+ r[L] = c;
+ L++;
+ *L0 = L;
+}
+
+LOCALPROC ClStrAppendSubstCStr(int *L, ui3b *r, char *s)
+{
+ /* must match ClStrSizeSubstCStr ! */
+
+ char *p = s;
+ char c;
+ ui3b x;
+
+ while (0 != (c = *p++)) {
+ if ('^' == c) {
+ if (0 == (c = *p++)) {
+ return; /* oops, unexpected end of string, abort */
+ } else if ('^' == c) {
+ ClStrAppendChar(L, r, c);
+ } else {
+ ClStrAppendSubstCStr(L, r, GetSubstitutionStr(c));
+ }
+ } else if (';' == c) {
+ if (0 == (c = *p++)) {
+ return; /* oops, unexpected end of string, abort */
+ }
+
+ switch (c) {
+ case 'g': x = kCellCopyright; break;
+ case 'l':
+ if (0 == (c = *p++)) {
+ /* oops, unexpected end of string, abort */
+ return;
+ }
+
+ switch (c) {
+ case 'a': x = kCellApostrophe; break;
+ case 'l': x = kCellEllipsis; break;
+ case 's': x = kCellSemicolon; break;
+#if NeedIntlChars
+ case 'E': x = kCellUpAE; break;
+ case 'e': x = kCellLoAE; break;
+ case '.': x = kCellMidDot; break;
+#endif
+ default: x = kCellQuestion; break;
+ }
+ break;
+ case '[': x = kCellLeftDQuote; break;
+ case '{': x = kCellRightDQuote; break;
+ case ']': x = kCellLeftSQuote; break;
+ case '}': x = kCellRightSQuote; break;
+#if NeedIntlChars
+ case '?': x = kCellInvQuestion; break;
+ case 'A': x = kCellUpARing; break;
+ case 'C': x = kCellUpCCedilla; break;
+ case 'O': x = kCellUpOStroke; break;
+ case 'Q': x = kCellUpLigatureOE; break;
+ case '`':
+ if (0 == (c = *p++)) {
+ /* oops, unexpected end of string, abort */
+ return;
+ }
+
+ switch (c) {
+ case 'A': x = kCellUpAGrave; break;
+ case 'E': x = kCellUpEGrave; break;
+ case 'I': x = kCellUpIGrave; break;
+ case 'O': x = kCellUpOGrave; break;
+ case 'U': x = kCellUpUGrave; break;
+ case 'a': x = kCellLoAGrave; break;
+ case 'e': x = kCellLoEGrave; break;
+ case 'i': x = kCellLoIGrave; break;
+ case 'o': x = kCellLoOGrave; break;
+ case 'u': x = kCellLoUGrave; break;
+ default: x = kCellQuestion; break;
+ }
+ break;
+ case 'a': x = kCellLoARing; break;
+ case 'c': x = kCellLoCCedilla; break;
+ case 'd':
+ if (0 == (c = *p++)) {
+ /* oops, unexpected end of string, abort */
+ return;
+ }
+
+ switch (c) {
+ case 'A': x = kCellUpACedille; break;
+ case 'a': x = kCellLoACedille; break;
+ case 'D': x = kCellUpDStroke; break;
+ case 'd': x = kCellLoDStroke; break;
+ case 'E': x = kCellUpECedille; break;
+ case 'e': x = kCellLoECedille; break;
+ case 'L': x = kCellUpLBar; break;
+ case 'l': x = kCellLoLBar; break;
+ case 'Z': x = kCellUpZDot; break;
+ case 'z': x = kCellLoZDot; break;
+ default: x = kCellQuestion; break;
+ }
+ break;
+ case 'e':
+ if (0 == (c = *p++)) {
+ /* oops, unexpected end of string, abort */
+ return;
+ }
+
+ switch (c) {
+ case 'A': x = kCellUpAAcute; break;
+ case 'E': x = kCellUpEAcute; break;
+ case 'I': x = kCellUpIAcute; break;
+ case 'O': x = kCellUpOAcute; break;
+ case 'U': x = kCellUpUAcute; break;
+ case 'a': x = kCellLoAAcute; break;
+ case 'e': x = kCellLoEAcute; break;
+ case 'i': x = kCellLoIAcute; break;
+ case 'o': x = kCellLoOAcute; break;
+ case 'u': x = kCellLoUAcute; break;
+
+ case 'C': x = kCellUpCAcute; break;
+ case 'c': x = kCellLoCAcute; break;
+ case 'N': x = kCellUpNAcute; break;
+ case 'n': x = kCellLoNAcute; break;
+ case 'S': x = kCellUpSAcute; break;
+ case 's': x = kCellLoSAcute; break;
+ case 'Z': x = kCellUpZAcute; break;
+ case 'z': x = kCellLoZAcute; break;
+ case 'Y': x = kCellUpYAcute; break;
+ case 'y': x = kCellLoYAcute; break;
+
+ default: x = kCellQuestion; break;
+ }
+ break;
+ case 'i':
+ if (0 == (c = *p++)) {
+ /* oops, unexpected end of string, abort */
+ return;
+ }
+
+ switch (c) {
+ case 'A': x = kCellUpACircumflex; break;
+ case 'E': x = kCellUpECircumflex; break;
+ case 'I': x = kCellUpICircumflex; break;
+ case 'O': x = kCellUpOCircumflex; break;
+ case 'U': x = kCellUpUCircumflex; break;
+ case 'a': x = kCellLoACircumflex; break;
+ case 'e': x = kCellLoECircumflex; break;
+ case 'i': x = kCellLoICircumflex; break;
+ case 'o': x = kCellLoOCircumflex; break;
+ case 'u': x = kCellLoUCircumflex; break;
+ default: x = kCellQuestion; break;
+ }
+ break;
+ case 'n':
+ if (0 == (c = *p++)) {
+ /* oops, unexpected end of string, abort */
+ return;
+ }
+
+ switch (c) {
+ case 'A': x = kCellUpATilde; break;
+ case 'N': x = kCellUpNTilde; break;
+ case 'O': x = kCellUpOTilde; break;
+ case 'a': x = kCellLoATilde; break;
+ case 'n': x = kCellLoNTilde; break;
+ case 'o': x = kCellLoOTilde; break;
+ default: x = kCellQuestion; break;
+ }
+ break;
+ case 'o': x = kCellLoOStroke; break;
+ case 'q': x = kCellLoLigatureOE; break;
+ case 's': x = kCellSharpS; break;
+ case 'u':
+ if (0 == (c = *p++)) {
+ /* oops, unexpected end of string, abort */
+ return;
+ }
+
+ switch (c) {
+ case 'A': x = kCellUpADiaeresis; break;
+ case 'E': x = kCellUpEDiaeresis; break;
+ case 'I': x = kCellUpIDiaeresis; break;
+ case 'O': x = kCellUpODiaeresis; break;
+ case 'U': x = kCellUpUDiaeresis; break;
+ case 'Y': x = kCellUpYDiaeresis; break;
+ case 'a': x = kCellLoADiaeresis; break;
+ case 'e': x = kCellLoEDiaeresis; break;
+ case 'i': x = kCellLoIDiaeresis; break;
+ case 'o': x = kCellLoODiaeresis; break;
+ case 'u': x = kCellLoUDiaeresis; break;
+ case 'y': x = kCellLoYDiaeresis; break;
+ default: x = kCellQuestion; break;
+ }
+ break;
+ case 'v':
+ if (0 == (c = *p++)) {
+ /* oops, unexpected end of string, abort */
+ return;
+ }
+
+ switch (c) {
+ case 'C': x = kCellUpCCaron; break;
+ case 'c': x = kCellLoCCaron; break;
+ case 'e': x = kCellLoECaron; break;
+ case 'r': x = kCellLoRCaron; break;
+ case 's': x = kCellLoSCaron; break;
+ case 't': x = kCellLoTCaron; break;
+ case 'z': x = kCellLoZCaron; break;
+ default: x = kCellQuestion; break;
+ }
+ break;
+ case 'E':
+ if (0 == (c = *p++)) {
+ /* oops, unexpected end of string, abort */
+ return;
+ }
+
+ switch (c) {
+ case 'u': x = kCellLoUDblac; break;
+ default: x = kCellQuestion; break;
+ }
+ break;
+ case 'r':
+ if (0 == (c = *p++)) {
+ /* oops, unexpected end of string, abort */
+ return;
+ }
+
+ switch (c) {
+ case 'u': x = kCellLoURing; break;
+ default: x = kCellQuestion; break;
+ }
+ break;
+#endif
+ default: x = kCellQuestion; break;
+ }
+ ClStrAppendChar(L, r, x);
+ } else {
+ switch (c) {
+ case 'A': x = kCellUpA; break;
+ case 'B': x = kCellUpB; break;
+ case 'C': x = kCellUpC; break;
+ case 'D': x = kCellUpD; break;
+ case 'E': x = kCellUpE; break;
+ case 'F': x = kCellUpF; break;
+ case 'G': x = kCellUpG; break;
+ case 'H': x = kCellUpH; break;
+ case 'I': x = kCellUpI; break;
+ case 'J': x = kCellUpJ; break;
+ case 'K': x = kCellUpK; break;
+ case 'L': x = kCellUpL; break;
+ case 'M': x = kCellUpM; break;
+ case 'N': x = kCellUpN; break;
+ case 'O': x = kCellUpO; break;
+ case 'P': x = kCellUpP; break;
+ case 'Q': x = kCellUpQ; break;
+ case 'R': x = kCellUpR; break;
+ case 'S': x = kCellUpS; break;
+ case 'T': x = kCellUpT; break;
+ case 'U': x = kCellUpU; break;
+ case 'V': x = kCellUpV; break;
+ case 'W': x = kCellUpW; break;
+ case 'X': x = kCellUpX; break;
+ case 'Y': x = kCellUpY; break;
+ case 'Z': x = kCellUpZ; break;
+ case 'a': x = kCellLoA; break;
+ case 'b': x = kCellLoB; break;
+ case 'c': x = kCellLoC; break;
+ case 'd': x = kCellLoD; break;
+ case 'e': x = kCellLoE; break;
+ case 'f': x = kCellLoF; break;
+ case 'g': x = kCellLoG; break;
+ case 'h': x = kCellLoH; break;
+ case 'i': x = kCellLoI; break;
+ case 'j': x = kCellLoJ; break;
+ case 'k': x = kCellLoK; break;
+ case 'l': x = kCellLoL; break;
+ case 'm': x = kCellLoM; break;
+ case 'n': x = kCellLoN; break;
+ case 'o': x = kCellLoO; break;
+ case 'p': x = kCellLoP; break;
+ case 'q': x = kCellLoQ; break;
+ case 'r': x = kCellLoR; break;
+ case 's': x = kCellLoS; break;
+ case 't': x = kCellLoT; break;
+ case 'u': x = kCellLoU; break;
+ case 'v': x = kCellLoV; break;
+ case 'w': x = kCellLoW; break;
+ case 'x': x = kCellLoX; break;
+ case 'y': x = kCellLoY; break;
+ case 'z': x = kCellLoZ; break;
+ case '0': x = kCellDigit0; break;
+ case '1': x = kCellDigit1; break;
+ case '2': x = kCellDigit2; break;
+ case '3': x = kCellDigit3; break;
+ case '4': x = kCellDigit4; break;
+ case '5': x = kCellDigit5; break;
+ case '6': x = kCellDigit6; break;
+ case '7': x = kCellDigit7; break;
+ case '8': x = kCellDigit8; break;
+ case '9': x = kCellDigit9; break;
+ case '!': x = kCellExclamation; break;
+ case '&': x = kCellAmpersand; break;
+ case '(': x = kCellLeftParen; break;
+ case ')': x = kCellRightParen; break;
+ case ',': x = kCellComma; break;
+ case '-': x = kCellHyphen; break;
+ case '.': x = kCellPeriod; break;
+ case '/': x = kCellSlash; break;
+ case ':': x = kCellColon; break;
+ case ';': x = kCellSemicolon; break;
+ case '?': x = kCellQuestion; break;
+ case '_': x = kCellUnderscore; break;
+ case ' ': x = kCellSpace; break;
+ case '\047': x = kCellApostrophe; break;
+
+ default: x = kCellQuestion; break;
+ }
+ ClStrAppendChar(L, r, x);
+ }
+ }
+}
+
+#define ClStrMaxLength 512
+
+LOCALPROC ClStrFromSubstCStr(int *L, ui3b *r, char *s)
+{
+ int n = ClStrSizeSubstCStr(s);
+
+ *L = 0;
+ if (n <= ClStrMaxLength) {
+ ClStrAppendSubstCStr(L, r, s);
+
+ if (n != *L) {
+ /* try to ensure mismatch is noticed */
+ *L = 0;
+ }
+ }
+}
--- /dev/null
+++ b/src/IWMEMDEV.c
@@ -1,0 +1,214 @@
+/*
+ IWMEVDEV.c
+
+ Copyright (C) 2006 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Integrated Woz Machine EMulated DEVice
+
+ Emulates the IWM found in the Mac Plus.
+
+ This code is adapted from "IWM.c" in vMac by Philip Cummins.
+*/
+
+/*
+ This is the emulation for the IWM, the Integrated Woz Machine.
+ It's basically a serial to parallel converter with some timing
+ in-built into it to perform handshaking. Emulation so far just
+ includes Status and Mode Register Accesses.
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+
+#include "MYOSGLUE.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#endif
+
+#include "IWMEMDEV.h"
+
+/*
+ ReportAbnormalID unused 0x0603 - 0x06FF
+*/
+
+#define kph0L 0x00 /* CA0 off (0) */
+#define kph0H 0x01 /* CA0 on (1) */
+#define kph1L 0x02 /* CA1 off (0) */
+#define kph1H 0x03 /* CA1 on (1) */
+#define kph2L 0x04 /* CA2 off (0) */
+#define kph2H 0x05 /* CA2 on (1) */
+#define kph3L 0x06 /* LSTRB off (low) */
+#define kph3H 0x07 /* LSTRB on (high) */
+#define kmtrOff 0x08 /* disk enable off */
+#define kmtrOn 0x09 /* disk enable on */
+#define kintDrive 0x0A /* select internal drive */
+#define kextDrive 0x0B /* select external drive */
+#define kq6L 0x0C /* Q6 off */
+#define kq6H 0x0D /* Q6 on */
+#define kq7L 0x0E /* Q7 off */
+#define kq7H 0x0F /* Q7 on */
+
+#define kph0 0x01
+#define kph1 0x02
+#define kph2 0x04
+#define kph3 0x08
+#define kmtr 0x10
+#define kdrv 0x20
+#define kq6 0x40
+#define kq7 0x80
+
+typedef struct
+{
+ ui3b DataIn; /* Read Data Register */
+ ui3b Handshake; /* Read Handshake Register */
+ ui3b Status; /* Read Status Register */
+ ui3b Mode;
+ /* Drive Off : Write Mode Register */
+ /* Drive On : Write Data Register */
+ ui3b DataOut; /* Write Data Register */
+ ui3b Lines; /* Used to Access Disk Drive Registers */
+} IWM_Ty;
+
+IWM_Ty IWM;
+
+GLOBALPROC IWM_Reset(void)
+{
+ IWM.DataIn = IWM.Handshake = IWM.Status = IWM.Mode =
+ IWM.DataOut = IWM.Lines = 0;
+}
+
+typedef enum {On, Off} Mode_Ty;
+
+LOCALPROC IWM_Set_Lines(ui3b line, Mode_Ty the_mode)
+{
+ if (the_mode == Off) {
+ IWM.Lines &= (0xFF - line);
+ } else {
+ IWM.Lines |= line;
+ }
+}
+
+LOCALFUNC ui3b IWM_Read_Reg(void)
+{
+ switch ((IWM.Lines & (kq6 + kq7)) >> 6) {
+ case 0 :
+#if (CurEmMd >= kEmMd_SE) && (CurEmMd <= kEmMd_IIx)
+ /* don't report */
+#else
+ ReportAbnormalID(0x0601, "IWM Data Read");
+#endif
+#ifdef _IWM_Debug
+ printf("IWM Data Read\n");
+#endif
+ return IWM.DataIn;
+ break;
+ case 1 :
+#ifdef _IWM_Debug
+ printf("IWM Status Read\n");
+#endif
+ return IWM.Status;
+ break;
+ case 2 :
+ ReportAbnormalID(0x0602, "IWM Handshake Read");
+#ifdef _IWM_Debug
+ printf("IWM Handshake Read\n");
+#endif
+ return IWM.Handshake;
+ break;
+ case 3 :
+ default :
+ /*
+ should alway be in 0-3,
+ but compiler warnings don't know that
+ */
+ return 0;
+ break;
+ }
+}
+
+LOCALPROC IWM_Write_Reg(ui3b in)
+{
+ if (((IWM.Lines & kmtr) >> 4) == 0) {
+#ifdef _IWM_Debug
+ printf("IWM Mode Register Write\n");
+#endif
+ IWM.Mode = in;
+ IWM.Status = ((IWM.Status & 0xE0) + (IWM.Mode & 0x1F));
+ }
+}
+
+GLOBALFUNC ui5b IWM_Access(ui5b Data, blnr WriteMem, CPTR addr)
+{
+ switch (addr) {
+ case kph0L :
+ IWM_Set_Lines(kph0, Off);
+ break;
+ case kph0H :
+ IWM_Set_Lines(kph0, On);
+ break;
+ case kph1L :
+ IWM_Set_Lines(kph1, Off);
+ break;
+ case kph1H :
+ IWM_Set_Lines(kph1, On);
+ break;
+ case kph2L :
+ IWM_Set_Lines(kph2, Off);
+ break;
+ case kph2H :
+ IWM_Set_Lines(kph2, On);
+ break;
+ case kph3L :
+ IWM_Set_Lines(kph3, Off);
+ break;
+ case kph3H :
+ IWM_Set_Lines(kph3, On);
+ break;
+ case kmtrOff :
+ IWM.Status &= 0xDF;
+ IWM_Set_Lines(kmtr, Off);
+ break;
+ case kmtrOn :
+ IWM.Status |= 0x20;
+ IWM_Set_Lines(kmtr, On);
+ break;
+ case kintDrive :
+ IWM_Set_Lines(kdrv, Off);
+ break;
+ case kextDrive :
+ IWM_Set_Lines(kdrv, On);
+ break;
+ case kq6L :
+ IWM_Set_Lines(kq6, Off);
+ break;
+ case kq6H :
+ IWM_Set_Lines(kq6, On);
+ break;
+ case kq7L :
+ if (! WriteMem) {
+ Data = IWM_Read_Reg();
+ }
+ IWM_Set_Lines(kq7, Off);
+ break;
+ case kq7H :
+ if (WriteMem) {
+ IWM_Write_Reg(Data);
+ }
+ IWM_Set_Lines(kq7, On);
+ break;
+ }
+
+ return Data;
+}
--- /dev/null
+++ b/src/IWMEMDEV.h
@@ -1,0 +1,25 @@
+/*
+ IWMEVDEV.h
+
+ Copyright (C) 2004 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef IWMEVDEV_H
+#error "header already included"
+#else
+#define IWMEVDEV_H
+#endif
+
+EXPORTPROC IWM_Reset(void);
+
+EXPORTFUNC ui5b IWM_Access(ui5b Data, blnr WriteMem, CPTR addr);
--- /dev/null
+++ b/src/KBRDEMDV.c
@@ -1,0 +1,214 @@
+/*
+ KBRDEMDV.c
+
+ Copyright (C) 2006 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ KeyBoaRD EMulated DeVice
+
+ Emulation of the keyboard in the Mac Plus.
+
+ This code adapted from "Keyboard.c" in vMac by Philip Cummins.
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+#include "MYOSGLUE.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#endif
+
+#include "KBRDEMDV.h"
+
+#ifdef _VIA_Debug
+#include <stdio.h>
+#endif
+
+/*
+ ReportAbnormalID unused 0x0B03 - 0x0BFF
+*/
+
+IMPORTPROC KYBD_ShiftOutData(ui3b v);
+IMPORTFUNC ui3b KYBD_ShiftInData(void);
+
+enum {
+ kKybdStateIdle,
+ kKybdStateRecievingCommand,
+ kKybdStateRecievedCommand,
+ kKybdStateRecievingEndCommand,
+
+ kKybdStates
+};
+
+LOCALVAR int KybdState = kKybdStateIdle;
+
+LOCALVAR blnr HaveKeyBoardResult = falseblnr;
+LOCALVAR ui3b KeyBoardResult;
+
+LOCALPROC GotKeyBoardData(ui3b v)
+{
+ if (KybdState != kKybdStateIdle) {
+ HaveKeyBoardResult = trueblnr;
+ KeyBoardResult = v;
+ } else {
+ KYBD_ShiftOutData(v);
+ VIA1_iCB2 = 1;
+ }
+}
+
+LOCALVAR ui3b InstantCommandData = 0x7B;
+
+LOCALFUNC blnr AttemptToFinishInquiry(void)
+{
+ int i;
+ blnr KeyDown;
+ ui3b Keyboard_Data;
+
+ if (FindKeyEvent(&i, &KeyDown)) {
+ if (i < 64) {
+ Keyboard_Data = i << 1;
+ if (! KeyDown) {
+ Keyboard_Data += 128;
+ }
+ } else {
+ Keyboard_Data = 121;
+ InstantCommandData = (i - 64) << 1;
+ if (! KeyDown) {
+ InstantCommandData += 128;
+ }
+ }
+ GotKeyBoardData(Keyboard_Data);
+ return trueblnr;
+ } else {
+ return falseblnr;
+ }
+}
+
+#define MaxKeyboardWait 16 /* in 60ths of a second */
+ /*
+ Code in the mac rom will reset the keyboard if
+ it hasn't been heard from in 32/60th of a second.
+ So time out and send something before that
+ to keep connection.
+ */
+
+LOCALVAR int InquiryCommandTimer = 0;
+
+GLOBALPROC DoKybd_ReceiveCommand(void)
+{
+ if (KybdState != kKybdStateRecievingCommand) {
+ ReportAbnormalID(0x0B01,
+ "KybdState != kKybdStateRecievingCommand");
+ } else {
+ ui3b in = KYBD_ShiftInData();
+
+ KybdState = kKybdStateRecievedCommand;
+
+ switch (in) {
+ case 0x10 : /* Inquiry Command */
+ if (! AttemptToFinishInquiry()) {
+ InquiryCommandTimer = MaxKeyboardWait;
+ }
+ break;
+ case 0x14 : /* Instant Command */
+ GotKeyBoardData(InstantCommandData);
+ InstantCommandData = 0x7B;
+ break;
+ case 0x16 : /* Model Command */
+ GotKeyBoardData(0x0b /* 0x01 */);
+ /* Test value, means Model 0, no extra devices */
+ /*
+ Fixed by Hoshi Takanori -
+ it uses the proper keyboard type now
+ */
+ break;
+ case 0x36 : /* Test Command */
+ GotKeyBoardData(0x7D);
+ break;
+ case 0x00:
+ GotKeyBoardData(0);
+ break;
+ default :
+ /* Debugger(); */
+ GotKeyBoardData(0);
+ break;
+ }
+ }
+}
+
+GLOBALPROC DoKybd_ReceiveEndCommand(void)
+{
+ if (KybdState != kKybdStateRecievingEndCommand) {
+ ReportAbnormalID(0x0B02,
+ "KybdState != kKybdStateRecievingEndCommand");
+ } else {
+ KybdState = kKybdStateIdle;
+#ifdef _VIA_Debug
+ fprintf(stderr, "enter DoKybd_ReceiveEndCommand\n");
+#endif
+ if (HaveKeyBoardResult) {
+#ifdef _VIA_Debug
+ fprintf(stderr, "HaveKeyBoardResult: %d\n", KeyBoardResult);
+#endif
+ HaveKeyBoardResult = falseblnr;
+ KYBD_ShiftOutData(KeyBoardResult);
+ VIA1_iCB2 = 1;
+ }
+ }
+}
+
+GLOBALPROC Kybd_DataLineChngNtfy(void)
+{
+ switch (KybdState) {
+ case kKybdStateIdle:
+ if (VIA1_iCB2 == 0) {
+ KybdState = kKybdStateRecievingCommand;
+#ifdef _VIA_Debug
+ fprintf(stderr, "posting kICT_Kybd_ReceiveCommand\n");
+#endif
+ ICT_add(kICT_Kybd_ReceiveCommand,
+ 6800UL * kCycleScale / 64 * kMyClockMult);
+
+ if (InquiryCommandTimer != 0) {
+ InquiryCommandTimer = 0; /* abort Inquiry */
+ }
+ }
+ break;
+ case kKybdStateRecievedCommand:
+ if (VIA1_iCB2 == 1) {
+ KybdState = kKybdStateRecievingEndCommand;
+#ifdef _VIA_Debug
+ fprintf(stderr,
+ "posting kICT_Kybd_ReceiveEndCommand\n");
+#endif
+ ICT_add(kICT_Kybd_ReceiveEndCommand,
+ 6800UL * kCycleScale / 64 * kMyClockMult);
+ }
+ break;
+ }
+}
+
+GLOBALPROC KeyBoard_Update(void)
+{
+ if (InquiryCommandTimer != 0) {
+ if (AttemptToFinishInquiry()) {
+ InquiryCommandTimer = 0;
+ } else {
+ --InquiryCommandTimer;
+ if (InquiryCommandTimer == 0) {
+ GotKeyBoardData(0x7B);
+ }
+ }
+ }
+}
--- /dev/null
+++ b/src/KBRDEMDV.h
@@ -1,0 +1,27 @@
+/*
+ KBRDEMDV.h
+
+ Copyright (C) 2003 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef KBRDEMDV_H
+#error "header already included"
+#else
+#define KBRDEMDV_H
+#endif
+
+
+EXPORTPROC Kybd_DataLineChngNtfy(void);
+EXPORTPROC DoKybd_ReceiveEndCommand(void);
+EXPORTPROC DoKybd_ReceiveCommand(void);
+EXPORTPROC KeyBoard_Update(void);
--- /dev/null
+++ b/src/M68KITAB.c
@@ -1,0 +1,3072 @@
+/*
+ M68KITAB.c
+
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Motorola 68K Instructions TABle
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+#endif
+
+#include "MYOSGLUE.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+
+#include "M68KITAB.h"
+
+struct WorkR {
+ /* expected size : 8 bytes */
+ ui5b opcode;
+ ui5b opsize;
+ ui4r MainClass;
+#if WantCycByPriOp
+ ui4r Cycles;
+#endif
+ DecOpR DecOp;
+};
+typedef struct WorkR WorkR;
+
+#define b76(p) ((p->opcode >> 6) & 3)
+#define b8(p) ((p->opcode >> 8) & 1)
+#define mode(p) ((p->opcode >> 3) & 7)
+#define reg(p) (p->opcode & 7)
+#define md6(p) ((p->opcode >> 6) & 7)
+#define rg9(p) ((p->opcode >> 9) & 7)
+
+enum {
+ kAddrValidAny,
+ kAddrValidData,
+ kAddrValidDataAlt,
+ kAddrValidControl,
+ kAddrValidControlAlt,
+ kAddrValidAltMem,
+ kAddrValidDataNoCn, /* no constants (immediate data) */
+
+ kNumAddrValids
+};
+
+#define kAddrValidMaskAny (1 << kAddrValidAny)
+#define kAddrValidMaskData (1 << kAddrValidData)
+#define kAddrValidMaskDataAlt (1 << kAddrValidDataAlt)
+#define kAddrValidMaskControl (1 << kAddrValidControl)
+#define kAddrValidMaskControlAlt (1 << kAddrValidControlAlt)
+#define kAddrValidMaskAltMem (1 << kAddrValidAltMem)
+#define kAddrValidMaskDataNoCn (1 << kAddrValidDataNoCn)
+
+#define CheckInSet(v, m) (0 != ((1 << (v)) & (m)))
+
+#define kMyAvgCycPerInstr (10 * kCycleScale + (40 * kCycleScale / 64))
+
+LOCALFUNC ui3r GetAMdRegSz(WorkR *p)
+{
+ ui3r CurAMd;
+
+ switch (p->opsize) {
+ case 1:
+ CurAMd = kAMdRegB;
+ break;
+ case 2:
+ default: /* keep compiler happy */
+ CurAMd = kAMdRegW;
+ break;
+ case 4:
+ CurAMd = kAMdRegL;
+ break;
+ }
+
+ return CurAMd;
+}
+
+LOCALFUNC ui3r GetAMdIndirectSz(WorkR *p)
+{
+ ui3r CurAMd;
+
+ switch (p->opsize) {
+ case 1:
+ CurAMd = kAMdIndirectB;
+ break;
+ case 2:
+ default: /* keep compiler happy */
+ CurAMd = kAMdIndirectW;
+ break;
+ case 4:
+ CurAMd = kAMdIndirectL;
+ break;
+ }
+
+ return CurAMd;
+}
+
+#if WantCycByPriOp
+LOCALFUNC ui4r OpEACalcCyc(WorkR *p, ui3r m, ui3r r)
+{
+ ui4r v;
+
+ switch (m) {
+ case 0:
+ case 1:
+ v = 0;
+ break;
+ case 2:
+ v = ((4 == p->opsize)
+ ? (8 * kCycleScale + 2 * RdAvgXtraCyc)
+ : (4 * kCycleScale + RdAvgXtraCyc));
+ break;
+ case 3:
+ v = ((4 == p->opsize)
+ ? (8 * kCycleScale + 2 * RdAvgXtraCyc)
+ : (4 * kCycleScale + RdAvgXtraCyc));
+ break;
+ case 4:
+ v = ((4 == p->opsize)
+ ? (10 * kCycleScale + 2 * RdAvgXtraCyc)
+ : (6 * kCycleScale + RdAvgXtraCyc));
+ break;
+ case 5:
+ v = ((4 == p->opsize)
+ ? (12 * kCycleScale + 3 * RdAvgXtraCyc)
+ : (8 * kCycleScale + 2 * RdAvgXtraCyc));
+ break;
+ case 6:
+ v = ((4 == p->opsize)
+ ? (14 * kCycleScale + 3 * RdAvgXtraCyc)
+ : (10 * kCycleScale + 2 * RdAvgXtraCyc));
+ break;
+ case 7:
+ switch (r) {
+ case 0:
+ v = ((4 == p->opsize)
+ ? (12 * kCycleScale + 3 * RdAvgXtraCyc)
+ : (8 * kCycleScale + 2 * RdAvgXtraCyc));
+ break;
+ case 1:
+ v = ((4 == p->opsize)
+ ? (16 * kCycleScale + 4 * RdAvgXtraCyc)
+ : (12 * kCycleScale + 3 * RdAvgXtraCyc));
+ break;
+ case 2:
+ v = ((4 == p->opsize)
+ ? (12 * kCycleScale + 3 * RdAvgXtraCyc)
+ : (8 * kCycleScale + 2 * RdAvgXtraCyc));
+ break;
+ case 3:
+ v = ((4 == p->opsize)
+ ? (14 * kCycleScale + 3 * RdAvgXtraCyc)
+ : (10 * kCycleScale + 2 * RdAvgXtraCyc));
+ break;
+ case 4:
+ v = ((4 == p->opsize)
+ ? (8 * kCycleScale + 2 * RdAvgXtraCyc)
+ : (4 * kCycleScale + RdAvgXtraCyc));
+ break;
+ default:
+ v = 0;
+ break;
+ }
+ break;
+ default: /* keep compiler happy */
+ v = 0;
+ break;
+ }
+
+ return v;
+}
+#endif
+
+#if WantCycByPriOp
+LOCALFUNC ui4r OpEADestCalcCyc(WorkR *p, ui3r m, ui3r r)
+{
+ ui4r v;
+
+ switch (m) {
+ case 0:
+ case 1:
+ v = 0;
+ break;
+ case 2:
+ v = ((4 == p->opsize)
+ ? (8 * kCycleScale + 2 * WrAvgXtraCyc)
+ : (4 * kCycleScale + WrAvgXtraCyc));
+ break;
+ case 3:
+ v = ((4 == p->opsize)
+ ? (8 * kCycleScale + 2 * WrAvgXtraCyc)
+ : (4 * kCycleScale + WrAvgXtraCyc));
+ break;
+ case 4:
+ v = ((4 == p->opsize)
+ ? (8 * kCycleScale + 2 * WrAvgXtraCyc)
+ : (4 * kCycleScale + WrAvgXtraCyc));
+ break;
+ case 5:
+ v = ((4 == p->opsize)
+ ? (12 * kCycleScale + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (8 * kCycleScale + RdAvgXtraCyc + WrAvgXtraCyc));
+ break;
+ case 6:
+ v = ((4 == p->opsize)
+ ? (14 * kCycleScale + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (10 * kCycleScale + RdAvgXtraCyc + WrAvgXtraCyc));
+ break;
+ case 7:
+ switch (r) {
+ case 0:
+ v = ((4 == p->opsize)
+ ? (12 * kCycleScale
+ + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc));
+ break;
+ case 1:
+ v = ((4 == p->opsize)
+ ? (16 * kCycleScale
+ + 2 * RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (12 * kCycleScale
+ + 2 * RdAvgXtraCyc + WrAvgXtraCyc));
+ break;
+ default:
+ v = 0;
+ break;
+ }
+ break;
+ default: /* keep compiler happy */
+ v = 0;
+ break;
+ }
+
+ return v;
+}
+#endif
+
+LOCALPROC SetDcoArgFields(WorkR *p, blnr src,
+ ui3r CurAMd, ui3r CurArgDat)
+{
+ if (src) {
+ p->DecOp.y.v[0].AMd = CurAMd;
+ p->DecOp.y.v[0].ArgDat = CurArgDat;
+ } else {
+ p->DecOp.y.v[1].AMd = CurAMd;
+ p->DecOp.y.v[1].ArgDat = CurArgDat;
+ }
+}
+
+LOCALFUNC blnr CheckValidAddrMode(WorkR *p,
+ ui3r m, ui3r r, ui3r v, blnr src)
+{
+ ui3r CurAMd = 0; /* init to keep compiler happy */
+ ui3r CurArgDat = 0;
+ blnr IsOk;
+
+ switch (m) {
+ case 0:
+ CurAMd = GetAMdRegSz(p);
+ CurArgDat = r;
+ IsOk = CheckInSet(v,
+ kAddrValidMaskAny | kAddrValidMaskData
+ | kAddrValidMaskDataAlt | kAddrValidMaskDataNoCn);
+ break;
+ case 1:
+ CurAMd = GetAMdRegSz(p);
+ CurArgDat = r + 8;
+ IsOk = CheckInSet(v, kAddrValidMaskAny);
+ break;
+ case 2:
+ CurAMd = GetAMdIndirectSz(p);
+ CurArgDat = r + 8;
+ IsOk = CheckInSet(v,
+ kAddrValidMaskAny | kAddrValidMaskData
+ | kAddrValidMaskDataAlt | kAddrValidMaskControl
+ | kAddrValidMaskControlAlt | kAddrValidMaskAltMem
+ | kAddrValidMaskDataNoCn);
+ break;
+ case 3:
+ switch (p->opsize) {
+ case 1:
+ if (7 == r) {
+ CurAMd = kAMdAPosInc7B;
+ } else {
+ CurAMd = kAMdAPosIncB;
+ }
+ break;
+ case 2:
+ default: /* keep compiler happy */
+ CurAMd = kAMdAPosIncW;
+ break;
+ case 4:
+ CurAMd = kAMdAPosIncL;
+ break;
+ }
+ CurArgDat = r + 8;
+ IsOk = CheckInSet(v,
+ kAddrValidMaskAny | kAddrValidMaskData
+ | kAddrValidMaskDataAlt | kAddrValidMaskAltMem
+ | kAddrValidMaskDataNoCn);
+ break;
+ case 4:
+ switch (p->opsize) {
+ case 1:
+ if (7 == r) {
+ CurAMd = kAMdAPreDec7B;
+ } else {
+ CurAMd = kAMdAPreDecB;
+ }
+ break;
+ case 2:
+ default: /* keep compiler happy */
+ CurAMd = kAMdAPreDecW;
+ break;
+ case 4:
+ CurAMd = kAMdAPreDecL;
+ break;
+ }
+ CurArgDat = r + 8;
+ IsOk = CheckInSet(v,
+ kAddrValidMaskAny | kAddrValidMaskData
+ | kAddrValidMaskDataAlt | kAddrValidMaskAltMem
+ | kAddrValidMaskDataNoCn);
+ break;
+ case 5:
+ switch (p->opsize) {
+ case 1:
+ CurAMd = kAMdADispB;
+ break;
+ case 2:
+ default: /* keep compiler happy */
+ CurAMd = kAMdADispW;
+ break;
+ case 4:
+ CurAMd = kAMdADispL;
+ break;
+ }
+ CurArgDat = r + 8;
+ IsOk = CheckInSet(v,
+ kAddrValidMaskAny | kAddrValidMaskData
+ | kAddrValidMaskDataAlt | kAddrValidMaskControl
+ | kAddrValidMaskControlAlt | kAddrValidMaskAltMem
+ | kAddrValidMaskDataNoCn);
+ break;
+ case 6:
+ switch (p->opsize) {
+ case 1:
+ CurAMd = kAMdAIndexB;
+ break;
+ case 2:
+ default: /* keep compiler happy */
+ CurAMd = kAMdAIndexW;
+ break;
+ case 4:
+ CurAMd = kAMdAIndexL;
+ break;
+ }
+ CurArgDat = r + 8;
+ IsOk = CheckInSet(v,
+ kAddrValidMaskAny | kAddrValidMaskData
+ | kAddrValidMaskDataAlt | kAddrValidMaskControl
+ | kAddrValidMaskControlAlt | kAddrValidMaskAltMem
+ | kAddrValidMaskDataNoCn);
+ break;
+ case 7:
+ switch (r) {
+ case 0:
+ switch (p->opsize) {
+ case 1:
+ CurAMd = kAMdAbsWB;
+ break;
+ case 2:
+ default: /* keep compiler happy */
+ CurAMd = kAMdAbsWW;
+ break;
+ case 4:
+ CurAMd = kAMdAbsWL;
+ break;
+ }
+ IsOk = CheckInSet(v,
+ kAddrValidMaskAny | kAddrValidMaskData
+ | kAddrValidMaskDataAlt
+ | kAddrValidMaskControl
+ | kAddrValidMaskControlAlt
+ | kAddrValidMaskAltMem
+ | kAddrValidMaskDataNoCn);
+ break;
+ case 1:
+ switch (p->opsize) {
+ case 1:
+ CurAMd = kAMdAbsLB;
+ break;
+ case 2:
+ default: /* keep compiler happy */
+ CurAMd = kAMdAbsLW;
+ break;
+ case 4:
+ CurAMd = kAMdAbsLL;
+ break;
+ }
+ IsOk = CheckInSet(v,
+ kAddrValidMaskAny | kAddrValidMaskData
+ | kAddrValidMaskDataAlt
+ | kAddrValidMaskControl
+ | kAddrValidMaskControlAlt
+ | kAddrValidMaskAltMem
+ | kAddrValidMaskDataNoCn);
+ break;
+ case 2:
+ switch (p->opsize) {
+ case 1:
+ CurAMd = kAMdPCDispB;
+ break;
+ case 2:
+ default: /* keep compiler happy */
+ CurAMd = kAMdPCDispW;
+ break;
+ case 4:
+ CurAMd = kAMdPCDispL;
+ break;
+ }
+ IsOk = CheckInSet(v,
+ kAddrValidMaskAny | kAddrValidMaskData
+ | kAddrValidMaskControl
+ | kAddrValidMaskDataNoCn);
+ break;
+ case 3:
+ switch (p->opsize) {
+ case 1:
+ CurAMd = kAMdPCIndexB;
+ break;
+ case 2:
+ default: /* keep compiler happy */
+ CurAMd = kAMdPCIndexW;
+ break;
+ case 4:
+ CurAMd = kAMdPCIndexL;
+ break;
+ }
+ IsOk = CheckInSet(v,
+ kAddrValidMaskAny | kAddrValidMaskData
+ | kAddrValidMaskControl
+ | kAddrValidMaskDataNoCn);
+ break;
+ case 4:
+ switch (p->opsize) {
+ case 1:
+ CurAMd = kAMdImmedB;
+ break;
+ case 2:
+ default: /* keep compiler happy */
+ CurAMd = kAMdImmedW;
+ break;
+ case 4:
+ CurAMd = kAMdImmedL;
+ break;
+ }
+ IsOk = CheckInSet(v,
+ kAddrValidMaskAny | kAddrValidMaskData);
+ break;
+ default:
+ IsOk = falseblnr;
+ break;
+ }
+ break;
+ default: /* keep compiler happy */
+ IsOk = falseblnr;
+ break;
+ }
+
+ if (IsOk) {
+ SetDcoArgFields(p, src, CurAMd, CurArgDat);
+ }
+
+ return IsOk;
+}
+
+#if WantCycByPriOp
+LOCALFUNC blnr LeaPeaEACalcCyc(WorkR *p, ui3r m, ui3r r)
+{
+ ui4r v;
+
+ UnusedParam(p);
+ switch (m) {
+ case 2:
+ v = 0;
+ break;
+ case 5:
+ v = (4 * kCycleScale + RdAvgXtraCyc);
+ break;
+ case 6:
+ v = (8 * kCycleScale + RdAvgXtraCyc);
+ break;
+ case 7:
+ switch (r) {
+ case 0:
+ v = (4 * kCycleScale + RdAvgXtraCyc);
+ break;
+ case 1:
+ v = (8 * kCycleScale + 2 * RdAvgXtraCyc);
+ break;
+ case 2:
+ v = (4 * kCycleScale + RdAvgXtraCyc);
+ break;
+ case 3:
+ v = (8 * kCycleScale + RdAvgXtraCyc);
+ break;
+ default:
+ v = 0;
+ break;
+ }
+ break;
+ default: /* keep compiler happy */
+ v = 0;
+ break;
+ }
+
+ return v;
+}
+#endif
+
+LOCALFUNC blnr IsValidAddrMode(WorkR *p)
+{
+ return CheckValidAddrMode(p,
+ mode(p), reg(p), kAddrValidAny, falseblnr);
+}
+
+LOCALFUNC blnr CheckDataAltAddrMode(WorkR *p)
+{
+ return CheckValidAddrMode(p,
+ mode(p), reg(p), kAddrValidDataAlt, falseblnr);
+}
+
+LOCALFUNC blnr CheckDataAddrMode(WorkR *p)
+{
+ return CheckValidAddrMode(p,
+ mode(p), reg(p), kAddrValidData, falseblnr);
+}
+
+LOCALFUNC blnr CheckControlAddrMode(WorkR *p)
+{
+ return CheckValidAddrMode(p,
+ mode(p), reg(p), kAddrValidControl, falseblnr);
+}
+
+LOCALFUNC blnr CheckControlAltAddrMode(WorkR *p)
+{
+ return CheckValidAddrMode(p,
+ mode(p), reg(p), kAddrValidControlAlt, falseblnr);
+}
+
+LOCALFUNC blnr CheckAltMemAddrMode(WorkR *p)
+{
+ return CheckValidAddrMode(p,
+ mode(p), reg(p), kAddrValidAltMem, falseblnr);
+}
+
+LOCALPROC FindOpSizeFromb76(WorkR *p)
+{
+ p->opsize = 1 << b76(p);
+#if 0
+ switch (b76(p)) {
+ case 0 :
+ p->opsize = 1;
+ break;
+ case 1 :
+ p->opsize = 2;
+ break;
+ case 2 :
+ p->opsize = 4;
+ break;
+ }
+#endif
+}
+
+LOCALFUNC ui3r OpSizeOffset(WorkR *p)
+{
+ ui3r v;
+
+ switch (p->opsize) {
+ case 1 :
+ v = 0;
+ break;
+ case 2 :
+ v = 1;
+ break;
+ case 4 :
+ default :
+ v = 2;
+ break;
+ }
+
+ return v;
+}
+
+
+LOCALFUNC ui5r octdat(ui5r x)
+{
+ if (x == 0) {
+ return 8;
+ } else {
+ return x;
+ }
+}
+
+LOCALPROCUSEDONCE DeCode0(WorkR *p)
+{
+ if (b8(p) == 1) {
+ if (mode(p) == 1) {
+ /* MoveP 0000ddd1mm001aaa */
+#if WantCycByPriOp
+ switch (b76(p)) {
+ case 0:
+ p->Cycles = (16 * kCycleScale + 4 * RdAvgXtraCyc);
+ break;
+ case 1:
+ p->Cycles = (24 * kCycleScale + 6 * RdAvgXtraCyc);
+ break;
+ case 2:
+ p->Cycles = (16 * kCycleScale
+ + 2 * RdAvgXtraCyc + 2 * WrAvgXtraCyc);
+ break;
+ case 3:
+ default: /* keep compiler happy */
+ p->Cycles = (24 * kCycleScale
+ + 2 * RdAvgXtraCyc + 4 * WrAvgXtraCyc);
+ break;
+ }
+#endif
+ if (CheckValidAddrMode(p, 1, reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+ p->MainClass = kIKindMoveP0 + b76(p);
+ }
+ } else {
+ /* dynamic bit, Opcode = 0000ddd1ttmmmrrr */
+ if (mode(p) == 0) {
+ p->opsize = 4;
+#if WantCycByPriOp
+ switch (b76(p)) {
+ case 0: /* BTst */
+ p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
+ break;
+ case 1: /* BChg */
+ p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
+ break;
+ case 2: /* BClr */
+ p->Cycles = (10 * kCycleScale + RdAvgXtraCyc);
+ break;
+ case 3: /* BSet */
+ p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
+ break;
+ }
+#endif
+ p->MainClass = kIKindBTstL + b76(p);
+ SetDcoArgFields(p, trueblnr, kAMdRegL, rg9(p));
+ SetDcoArgFields(p, falseblnr, kAMdRegL, reg(p));
+ } else {
+ p->opsize = 1;
+ p->MainClass = kIKindBTstB + b76(p);
+ SetDcoArgFields(p, trueblnr, kAMdRegB, rg9(p));
+ if (b76(p) == 0) { /* BTst */
+ if (CheckDataAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ }
+ } else {
+ if (CheckDataAltAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles = (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ }
+ }
+ }
+ }
+ } else {
+ if (rg9(p) == 4) {
+ /* static bit 00001010ssmmmrrr */
+ if (mode(p) == 0) {
+ p->opsize = 4;
+#if WantCycByPriOp
+ switch (b76(p)) {
+ case 0: /* BTst */
+ p->Cycles =
+ (10 * kCycleScale + 2 * RdAvgXtraCyc);
+ break;
+ case 1: /* BChg */
+ p->Cycles =
+ (12 * kCycleScale + 2 * RdAvgXtraCyc);
+ break;
+ case 2: /* BClr */
+ p->Cycles =
+ (14 * kCycleScale + 2 * RdAvgXtraCyc);
+ break;
+ case 3: /* BSet */
+ p->Cycles =
+ (12 * kCycleScale + 2 * RdAvgXtraCyc);
+ break;
+ }
+#endif
+ SetDcoArgFields(p, trueblnr, kAMdImmedB, 0);
+ SetDcoArgFields(p, falseblnr, kAMdRegL, reg(p));
+ p->MainClass = kIKindBTstL + b76(p);
+ } else {
+ p->opsize = 1;
+ SetDcoArgFields(p, trueblnr, kAMdImmedB, 0);
+ p->MainClass = kIKindBTstB + b76(p);
+ if (b76(p) == 0) { /* BTst */
+ if (CheckValidAddrMode(p,
+ mode(p), reg(p), kAddrValidDataNoCn, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles =
+ (8 * kCycleScale + 2 * RdAvgXtraCyc);
+ p->Cycles +=
+ OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ }
+ } else {
+ if (CheckDataAltAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles = (12 * kCycleScale
+ + 2 * RdAvgXtraCyc + WrAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ }
+ }
+ }
+ } else
+ if (b76(p) == 3) {
+#if Use68020
+ if (rg9(p) < 3) {
+ /* CHK2 or CMP2 00000ss011mmmrrr */
+ switch ((p->opcode >> 9) & 3) {
+ case 0 :
+ p->opsize = 1;
+ break;
+ case 1 :
+ p->opsize = 2;
+ break;
+ case 2 :
+ p->opsize = 4;
+ break;
+ }
+ p->DecOp.y.v[0].ArgDat = p->opsize;
+ /* size */
+ if (CheckControlAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindCHK2orCMP2;
+ }
+ } else
+ if (rg9(p) >= 5) {
+ switch ((p->opcode >> 9) & 3) {
+ case 1 :
+ p->opsize = 1;
+ break;
+ case 2 :
+ p->opsize = 2;
+ break;
+ case 3 :
+ p->opsize = 4;
+ break;
+ }
+ p->DecOp.y.v[0].ArgDat = p->opsize;
+ if ((mode(p) == 7) && (reg(p) == 4)) {
+ /* CAS2 00001ss011111100 */
+ p->MainClass = kIKindCAS2;
+ } else {
+ /* CAS 00001ss011mmmrrr */
+ if (CheckDataAltAddrMode(p)) {
+ p->MainClass = kIKindCAS;
+ }
+ }
+ } else
+ if (rg9(p) == 3) {
+ /* CALLM or RTM 0000011011mmmrrr */
+ p->MainClass = kIKindCallMorRtm;
+ } else
+#endif
+ {
+ p->MainClass = kIKindIllegal;
+ }
+ } else
+ if (rg9(p) == 6) {
+ /* CMPI 00001100ssmmmrrr */
+#if 0
+ if (CheckDataAltAddrMode(p)) {
+ p->MainClass = kIKindCmpI;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 7, 4, kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p,
+ mode(p), reg(p), kAddrValidDataNoCn, falseblnr))
+ {
+#if WantCycByPriOp
+ if (0 == mode(p)) {
+ p->Cycles = (4 == p->opsize)
+ ? (14 * kCycleScale + 3 * RdAvgXtraCyc)
+ : (8 * kCycleScale + 2 * RdAvgXtraCyc);
+ } else {
+ p->Cycles = (4 == p->opsize)
+ ? (12 * kCycleScale + 3 * RdAvgXtraCyc)
+ : (8 * kCycleScale + 2 * RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindCmpB + OpSizeOffset(p);
+ }
+ } else if (rg9(p) == 7) {
+#if Use68020
+ /* MoveS 00001110ssmmmrrr */
+ FindOpSizeFromb76(p);
+ p->DecOp.y.v[0].ArgDat = p->opsize;
+ if (CheckAltMemAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindMoveS;
+ }
+#else
+ p->MainClass = kIKindIllegal;
+#endif
+ } else {
+ if ((mode(p) == 7) && (reg(p) == 4)) {
+ switch (rg9(p)) {
+ case 0:
+#if WantCycByPriOp
+ p->Cycles =
+ (20 * kCycleScale + 3 * RdAvgXtraCyc);
+#endif
+ p->MainClass = (0 != b76(p))
+ ? kIKindOrISR : kIKindOrICCR;
+ break;
+ case 1:
+#if WantCycByPriOp
+ p->Cycles =
+ (20 * kCycleScale + 3 * RdAvgXtraCyc);
+#endif
+ p->MainClass = (0 != b76(p))
+ ? kIKindAndISR : kIKindAndICCR;
+ break;
+ case 5:
+#if WantCycByPriOp
+ p->Cycles =
+ (20 * kCycleScale + 3 * RdAvgXtraCyc);
+#endif
+ p->MainClass = (0 != b76(p))
+ ? kIKindEorISR : kIKindEorICCR;
+ break;
+ default:
+ p->MainClass = kIKindIllegal;
+ break;
+ }
+ } else {
+ switch (rg9(p)) {
+ case 0:
+#if 0
+ if (CheckDataAltAddrMode(p)) {
+ p->MainClass = kIKindOrI;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 7, 4,
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidDataAlt, falseblnr))
+ {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (4 == p->opsize)
+ ? (20 * kCycleScale
+ + 3 * RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc)
+ : (12 * kCycleScale
+ + 2 * RdAvgXtraCyc
+ + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (4 == p->opsize)
+ ? (16 * kCycleScale
+ + 3 * RdAvgXtraCyc)
+ : (8 * kCycleScale
+ + 2 * RdAvgXtraCyc);
+ }
+ p->Cycles +=
+ OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindOrI;
+ }
+ break;
+ case 1:
+#if 0
+ if (CheckDataAltAddrMode(p)) {
+ p->MainClass = kIKindAndI;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 7, 4,
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidDataAlt, falseblnr))
+ {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (4 == p->opsize)
+ ? (20 * kCycleScale
+ + 3 * RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc)
+ : (12 * kCycleScale
+ + 2 * RdAvgXtraCyc
+ + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (4 == p->opsize)
+ ? (14 * kCycleScale
+ + 3 * RdAvgXtraCyc)
+ : (8 * kCycleScale
+ + 2 * RdAvgXtraCyc);
+ }
+ p->Cycles +=
+ OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindAndI;
+ }
+ break;
+ case 2:
+#if 0
+ if (CheckDataAltAddrMode(p)) {
+ p->MainClass = kIKindSubI;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 7, 4,
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidDataAlt, falseblnr))
+ {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (4 == p->opsize)
+ ? (20 * kCycleScale
+ + 3 * RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc)
+ : (12 * kCycleScale
+ + 2 * RdAvgXtraCyc
+ + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (4 == p->opsize)
+ ? (16 * kCycleScale
+ + 3 * RdAvgXtraCyc)
+ : (8 * kCycleScale
+ + 2 * RdAvgXtraCyc);
+ }
+ p->Cycles +=
+ OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindSubB + OpSizeOffset(p);
+ }
+ break;
+ case 3:
+#if 0
+ if (CheckDataAltAddrMode(p)) {
+ p->MainClass = kIKindAddI;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 7, 4,
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidDataAlt, falseblnr))
+ {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (4 == p->opsize)
+ ? (20 * kCycleScale
+ + 3 * RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc)
+ : (12 * kCycleScale
+ + 2 * RdAvgXtraCyc
+ + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (4 == p->opsize)
+ ? (16 * kCycleScale
+ + 3 * RdAvgXtraCyc)
+ : (8 * kCycleScale
+ + 2 * RdAvgXtraCyc);
+ }
+ p->Cycles +=
+ OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindAddB + OpSizeOffset(p);
+ }
+ break;
+ case 5:
+#if 0
+ if (CheckDataAltAddrMode(p)) {
+ p->MainClass = kIKindEorI;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 7, 4,
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidDataAlt, falseblnr))
+ {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (4 == p->opsize)
+ ? (20 * kCycleScale
+ + 3 * RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc)
+ : (12 * kCycleScale
+ + 2 * RdAvgXtraCyc
+ + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (4 == p->opsize)
+ ? (16 * kCycleScale
+ + 3 * RdAvgXtraCyc)
+ : (8 * kCycleScale
+ + 2 * RdAvgXtraCyc);
+ }
+ p->Cycles +=
+ OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindEorI;
+ }
+ break;
+ default:
+ /* for compiler. should be 0, 1, 2, 3, or 5 */
+ p->MainClass = kIKindIllegal;
+ break;
+ }
+ }
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DeCode1(WorkR *p)
+{
+ p->opsize = 1;
+ if (md6(p) == 1) { /* MOVEA */
+ p->MainClass = kIKindIllegal;
+ } else if (mode(p) == 1) {
+ /* not allowed for byte sized move */
+ p->MainClass = kIKindIllegal;
+ } else {
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, md6(p), rg9(p),
+ kAddrValidDataAlt, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+ p->Cycles += OpEADestCalcCyc(p, md6(p), rg9(p));
+#endif
+ p->MainClass = kIKindMoveB;
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DeCode2(WorkR *p)
+{
+ p->opsize = 4;
+ if (md6(p) == 1) { /* MOVEA */
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 1, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindMoveAL;
+ p->DecOp.y.v[1].ArgDat = rg9(p);
+ }
+ } else {
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, md6(p), rg9(p),
+ kAddrValidDataAlt, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+ p->Cycles += OpEADestCalcCyc(p, md6(p), rg9(p));
+#endif
+ p->MainClass = kIKindMoveL;
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DeCode3(WorkR *p)
+{
+ p->opsize = 2;
+ if (md6(p) == 1) { /* MOVEA */
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 1, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindMoveAW;
+ p->DecOp.y.v[1].ArgDat = rg9(p);
+ }
+ } else {
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, md6(p), rg9(p),
+ kAddrValidDataAlt, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+ p->Cycles += OpEADestCalcCyc(p, md6(p), rg9(p));
+#endif
+ p->MainClass = kIKindMoveW;
+ }
+ }
+}
+
+#if WantCycByPriOp
+
+#if WantCloserCyc
+#define MoveAvgN 0
+#else
+#define MoveAvgN 3
+#endif
+
+LOCALFUNC ui4r MoveMEACalcCyc(WorkR *p, ui3r m, ui3r r)
+{
+ ui4r v;
+
+ UnusedParam(p);
+ switch (m) {
+ case 2:
+ case 3:
+ case 4:
+ v = (8 * kCycleScale + 2 * RdAvgXtraCyc);
+ break;
+ case 5:
+ v = (12 * kCycleScale + 3 * RdAvgXtraCyc);
+ break;
+ case 6:
+ v = (14 * kCycleScale + 3 * RdAvgXtraCyc);
+ break;
+ case 7:
+ switch (r) {
+ case 0:
+ v = (12 * kCycleScale + 3 * RdAvgXtraCyc);
+ break;
+ case 1:
+ v = (16 * kCycleScale + 4 * RdAvgXtraCyc);
+ break;
+ default:
+ v = 0;
+ break;
+ }
+ break;
+ default: /* keep compiler happy */
+ v = 0;
+ break;
+ }
+
+ return v;
+}
+
+#endif
+
+LOCALPROCUSEDONCE DeCode4(WorkR *p)
+{
+ if (b8(p) != 0) {
+ switch (b76(p)) {
+ case 0:
+#if Use68020
+ /* Chk.L 0100ddd100mmmrrr */
+ p->opsize = 4;
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidData, falseblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, trueblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindChkL;
+ }
+#else
+ p->MainClass = kIKindIllegal;
+#endif
+ break;
+ case 1:
+ p->MainClass = kIKindIllegal;
+ break;
+ case 2:
+ /* Chk.W 0100ddd110mmmrrr */
+ p->opsize = 2;
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidData, falseblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, trueblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (10 * kCycleScale + RdAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindChkW;
+ }
+ break;
+ case 3:
+ default: /* keep compiler happy */
+#if Use68020
+ if ((0 == mode(p)) && (4 == rg9(p))) {
+ /* EXTB.L */
+ SetDcoArgFields(p, falseblnr,
+ kAMdRegL, reg(p));
+ p->MainClass = kIKindEXTBL;
+ } else
+#endif
+ {
+ /* Lea 0100aaa111mmmrrr */
+ if (CheckControlAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
+ p->Cycles +=
+ LeaPeaEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindLea;
+ p->DecOp.y.v[0].ArgDat = rg9(p);
+ }
+ }
+ break;
+ }
+ } else {
+ switch (rg9(p)) {
+ case 0:
+ if (b76(p) != 3) {
+ /* NegX 01000000ssmmmrrr */
+ FindOpSizeFromb76(p);
+ if (CheckDataAltAddrMode(p)) {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (4 == p->opsize)
+ ? (12 * kCycleScale
+ + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (4 == p->opsize)
+ ? (6 * kCycleScale + RdAvgXtraCyc)
+ : (4 * kCycleScale + RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindNegXB + OpSizeOffset(p);
+ }
+ } else {
+#if Use68020
+/* reference seems incorrect to say not for 68000 */
+#endif
+ /* Move from SR 0100000011mmmrrr */
+ p->opsize = 2;
+ if (CheckDataAltAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles =
+ (12 * kCycleScale + 2 * RdAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindMoveSREa;
+ }
+ }
+ break;
+ case 1:
+ if (b76(p) != 3) {
+ /* Clr 01000010ssmmmrrr */
+ FindOpSizeFromb76(p);
+ if (CheckDataAltAddrMode(p)) {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (4 == p->opsize)
+ ? (12 * kCycleScale
+ + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (4 == p->opsize)
+ ? (6 * kCycleScale + RdAvgXtraCyc)
+ : (4 * kCycleScale + RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindClr;
+ }
+ } else {
+#if Use68020
+ /* Move from CCR 0100001011mmmrrr */
+ p->opsize = 2;
+ if (CheckDataAltAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindMoveCCREa;
+ }
+#else
+ p->MainClass = kIKindIllegal;
+#endif
+ }
+ break;
+ case 2:
+ if (b76(p) != 3) {
+ /* Neg 01000100ssmmmrrr */
+ FindOpSizeFromb76(p);
+ if (CheckDataAltAddrMode(p)) {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (4 == p->opsize)
+ ? (12 * kCycleScale
+ + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (4 == p->opsize)
+ ? (6 * kCycleScale + RdAvgXtraCyc)
+ : (4 * kCycleScale + RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindNegB + OpSizeOffset(p);
+ }
+ } else {
+ /* Move to CCR 0100010011mmmrrr */
+ p->opsize = 2;
+ if (CheckDataAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles = (12 * kCycleScale + RdAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindMoveEaCCR;
+ }
+ }
+ break;
+ case 3:
+ if (b76(p) != 3) {
+ /* Not 01000110ssmmmrrr */
+ FindOpSizeFromb76(p);
+ if (CheckDataAltAddrMode(p)) {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (4 == p->opsize)
+ ? (12 * kCycleScale
+ + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (4 == p->opsize)
+ ? (6 * kCycleScale + RdAvgXtraCyc)
+ : (4 * kCycleScale + RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindNot;
+ }
+ } else {
+ /* Move from SR 0100011011mmmrrr */
+ p->opsize = 2;
+ if (CheckDataAddrMode(p)) {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ } else {
+ p->Cycles =
+ (6 * kCycleScale + RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindMoveEaSR;
+ }
+ }
+ break;
+ case 4:
+ switch (b76(p)) {
+ case 0:
+#if Use68020
+ if (mode(p) == 1) {
+ /* Link.L 0100100000001rrr */
+ SetDcoArgFields(p, falseblnr,
+ kAMdRegL, reg(p) + 8);
+ p->MainClass = kIKindLinkL;
+ } else
+#endif
+ {
+ /* Nbcd 0100100000mmmrrr */
+ p->opsize = 1;
+ if (CheckDataAltAddrMode(p)) {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (6 * kCycleScale
+ + RdAvgXtraCyc);
+ }
+ p->Cycles +=
+ OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindNbcd;
+ }
+ }
+ break;
+ case 1:
+ if (mode(p) == 0) {
+ /* Swap 0100100001000rrr */
+#if WantCycByPriOp
+ p->Cycles =
+ (4 * kCycleScale + RdAvgXtraCyc);
+#endif
+ p->MainClass = kIKindSwap;
+ SetDcoArgFields(p, falseblnr,
+ kAMdRegL, reg(p));
+ } else
+#if Use68020
+ if (mode(p) == 1) {
+ p->MainClass = kIKindBkpt;
+ } else
+#endif
+ {
+ /* PEA 0100100001mmmrrr */
+ if (CheckControlAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles = (12 * kCycleScale
+ + RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc);
+ p->Cycles +=
+ LeaPeaEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindPEA;
+ }
+ }
+ break;
+ case 2:
+ if (mode(p) == 0) {
+ /* EXT.W */
+#if WantCycByPriOp
+ p->Cycles =
+ (4 * kCycleScale + RdAvgXtraCyc);
+#endif
+ SetDcoArgFields(p, falseblnr,
+ kAMdRegW, reg(p));
+ p->MainClass = kIKindEXTW;
+ } else {
+ /* MOVEM reg to mem 01001d001ssmmmrrr */
+ p->opsize = 2;
+ if (mode(p) == 4) {
+#if WantCycByPriOp
+ p->Cycles =
+ MoveMEACalcCyc(p, mode(p), reg(p));
+ p->Cycles += MoveAvgN * 4 * kCycleScale
+ + MoveAvgN * WrAvgXtraCyc;
+#endif
+ SetDcoArgFields(p, falseblnr,
+ kAMdAPreDecL, reg(p) + 8);
+ p->MainClass = kIKindMOVEMRmMW;
+ } else {
+ if (CheckControlAltAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles = MoveMEACalcCyc(p,
+ mode(p), reg(p));
+ p->Cycles +=
+ MoveAvgN * 4 * kCycleScale
+ + MoveAvgN * WrAvgXtraCyc;
+#endif
+ p->MainClass = kIKindMOVEMrmW;
+ }
+ }
+ }
+ break;
+ case 3:
+ default: /* keep compiler happy */
+ if (mode(p) == 0) {
+ /* EXT.L */
+#if WantCycByPriOp
+ p->Cycles =
+ (4 * kCycleScale + RdAvgXtraCyc);
+#endif
+ SetDcoArgFields(p, falseblnr,
+ kAMdRegL, reg(p));
+ p->MainClass = kIKindEXTL;
+ } else {
+ /* MOVEM reg to mem 01001d001ssmmmrrr */
+#if WantCycByPriOp
+ p->Cycles = MoveMEACalcCyc(p,
+ mode(p), reg(p));
+ p->Cycles += MoveAvgN * 8 * kCycleScale
+ + MoveAvgN * 2 * WrAvgXtraCyc;
+#endif
+ p->opsize = 4;
+ if (mode(p) == 4) {
+ SetDcoArgFields(p, falseblnr,
+ kAMdAPreDecL, reg(p) + 8);
+ p->MainClass = kIKindMOVEMRmML;
+ } else {
+ if (CheckControlAltAddrMode(p)) {
+ p->MainClass = kIKindMOVEMrmL;
+ }
+ }
+ }
+ break;
+ }
+ break;
+ case 5:
+ if (b76(p) == 3) {
+ if ((mode(p) == 7) && (reg(p) == 4)) {
+ /* the ILLEGAL instruction */
+ p->MainClass = kIKindIllegal;
+ } else {
+ /* Tas 0100101011mmmrrr */
+ p->opsize = 1;
+ if (CheckDataAltAddrMode(p)) {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (14 * kCycleScale
+ + 2 * RdAvgXtraCyc + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (4 * kCycleScale
+ + RdAvgXtraCyc);
+ }
+ p->Cycles +=
+ OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindTas;
+ }
+ }
+ } else {
+ /* Tst 01001010ssmmmrrr */
+ FindOpSizeFromb76(p);
+ if (b76(p) == 0) {
+ if (CheckDataAltAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles =
+ (4 * kCycleScale + RdAvgXtraCyc);
+ p->Cycles +=
+ OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindTst;
+ }
+ } else {
+ if (IsValidAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles =
+ (4 * kCycleScale + RdAvgXtraCyc);
+ p->Cycles +=
+ OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindTst;
+ }
+ }
+ }
+ break;
+ case 6:
+ if (((p->opcode >> 7) & 1) == 1) {
+ /* MOVEM mem to reg 0100110011smmmrrr */
+ p->opsize = 2 * b76(p) - 2;
+ if (mode(p) == 3) {
+#if WantCycByPriOp
+ p->Cycles = 4 * kCycleScale + RdAvgXtraCyc;
+ p->Cycles += MoveMEACalcCyc(p, mode(p), reg(p));
+ if (4 == p->opsize) {
+ p->Cycles += MoveAvgN * 8 * kCycleScale
+ + 2 * MoveAvgN * RdAvgXtraCyc;
+ } else {
+ p->Cycles += MoveAvgN * 4 * kCycleScale
+ + MoveAvgN * RdAvgXtraCyc;
+ }
+#endif
+ SetDcoArgFields(p, falseblnr,
+ kAMdAPosIncL, reg(p) + 8);
+ if (b76(p) == 2) {
+ p->MainClass = kIKindMOVEMApRW;
+ } else {
+ p->MainClass = kIKindMOVEMApRL;
+ }
+ } else {
+ if (CheckControlAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles = 4 * kCycleScale + RdAvgXtraCyc;
+ p->Cycles += MoveMEACalcCyc(p,
+ mode(p), reg(p));
+ if (4 == p->opsize) {
+ p->Cycles += MoveAvgN * 8 * kCycleScale
+ + 2 * MoveAvgN * RdAvgXtraCyc;
+ } else {
+ p->Cycles += MoveAvgN * 4 * kCycleScale
+ + MoveAvgN * RdAvgXtraCyc;
+ }
+#endif
+ if (4 == p->opsize) {
+ p->MainClass = kIKindMOVEMmrL;
+ } else {
+ p->MainClass = kIKindMOVEMmrW;
+ }
+ }
+ }
+ } else {
+#if Use68020
+ p->opsize = 4;
+
+ if (CheckDataAddrMode(p)) {
+ if (((p->opcode >> 6) & 1) == 1) {
+ /* DIVU 0100110001mmmrrr 0rrr0s0000000rrr */
+ /* DIVS 0100110001mmmrrr 0rrr1s0000000rrr */
+ p->MainClass = kIKindDivL;
+ } else {
+ /* MULU 0100110000mmmrrr 0rrr0s0000000rrr */
+ /* MULS 0100110000mmmrrr 0rrr1s0000000rrr */
+ p->MainClass = kIKindMulL;
+ }
+ }
+#else
+ p->MainClass = kIKindIllegal;
+#endif
+ }
+ break;
+ case 7:
+ default: /* keep compiler happy */
+ switch (b76(p)) {
+ case 0:
+ p->MainClass = kIKindIllegal;
+ break;
+ case 1:
+ switch (mode(p)) {
+ case 0:
+ case 1:
+ /* Trap 010011100100vvvv */
+#if WantCycByPriOp
+ p->Cycles = (34 * kCycleScale
+ + 4 * RdAvgXtraCyc
+ + 3 * WrAvgXtraCyc);
+#endif
+ SetDcoArgFields(p, falseblnr,
+ kAMdDat4, (p->opcode & 15) + 32);
+ p->MainClass = kIKindTrap;
+ break;
+ case 2:
+ /* Link */
+#if WantCycByPriOp
+ p->Cycles = (16 * kCycleScale
+ + 2 * RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc);
+#endif
+ SetDcoArgFields(p, falseblnr,
+ kAMdRegL, reg(p) + 8);
+ if (reg(p) == 6) {
+ p->MainClass = kIKindLinkA6;
+ } else {
+ p->MainClass = kIKindLink;
+ }
+ break;
+ case 3:
+ /* Unlk */
+#if WantCycByPriOp
+ p->Cycles = (12 * kCycleScale
+ + 3 * RdAvgXtraCyc);
+#endif
+ SetDcoArgFields(p, falseblnr,
+ kAMdRegL, reg(p) + 8);
+ if (reg(p) == 6) {
+ p->MainClass = kIKindUnlkA6;
+ } else {
+ p->MainClass = kIKindUnlk;
+ }
+ break;
+ case 4:
+ /* MOVE USP 0100111001100aaa */
+#if WantCycByPriOp
+ p->Cycles =
+ (4 * kCycleScale + RdAvgXtraCyc);
+#endif
+ SetDcoArgFields(p, falseblnr,
+ kAMdRegL, reg(p) + 8);
+ p->MainClass = kIKindMoveRUSP;
+ break;
+ case 5:
+ /* MOVE USP 0100111001101aaa */
+#if WantCycByPriOp
+ p->Cycles =
+ (4 * kCycleScale + RdAvgXtraCyc);
+#endif
+ SetDcoArgFields(p, falseblnr,
+ kAMdRegL, reg(p) + 8);
+ p->MainClass = kIKindMoveUSPR;
+ break;
+ case 6:
+ switch (reg(p)) {
+ case 0:
+ /* Reset 0100111001100000 */
+#if WantCycByPriOp
+ p->Cycles = (132 * kCycleScale
+ + RdAvgXtraCyc);
+#endif
+ p->MainClass = kIKindReset;
+ break;
+ case 1:
+ /* Nop = 0100111001110001 */
+#if WantCycByPriOp
+ p->Cycles = (4 * kCycleScale
+ + RdAvgXtraCyc);
+#endif
+ p->MainClass = kIKindNop;
+ break;
+ case 2:
+ /* Stop 0100111001110010 */
+#if WantCycByPriOp
+ p->Cycles = (4 * kCycleScale);
+#endif
+ p->MainClass = kIKindStop;
+ break;
+ case 3:
+ /* Rte 0100111001110011 */
+#if WantCycByPriOp
+ p->Cycles = (20 * kCycleScale
+ + 5 * RdAvgXtraCyc);
+#endif
+ p->MainClass = kIKindRte;
+ break;
+ case 4:
+ /* Rtd 0100111001110100 */
+#if Use68020
+ p->MainClass = kIKindRtd;
+#else
+ p->MainClass = kIKindIllegal;
+#endif
+ break;
+ case 5:
+ /* Rts 0100111001110101 */
+#if WantCycByPriOp
+ p->Cycles = (16 * kCycleScale
+ + 4 * RdAvgXtraCyc);
+#endif
+ p->MainClass = kIKindRts;
+ break;
+ case 6:
+ /* TrapV 0100111001110110 */
+#if WantCycByPriOp
+ p->Cycles = (4 * kCycleScale
+ + RdAvgXtraCyc);
+#endif
+ p->MainClass = kIKindTrapV;
+ break;
+ case 7:
+ default: /* keep compiler happy */
+ /* Rtr 0100111001110111 */
+#if WantCycByPriOp
+ p->Cycles = (20 * kCycleScale
+ + 2 * RdAvgXtraCyc);
+#endif
+ p->MainClass = kIKindRtr;
+ break;
+ }
+ break;
+ case 7:
+ default: /* keep compiler happy */
+#if Use68020
+ /* MOVEC 010011100111101m */
+ switch (reg(p)) {
+ case 2:
+ p->MainClass = kIKindMoveCEa;
+ break;
+ case 3:
+ p->MainClass = kIKindMoveEaC;
+ break;
+ default:
+ p->MainClass = kIKindIllegal;
+ break;
+ }
+#else
+ p->MainClass = kIKindIllegal;
+#endif
+ break;
+ }
+ break;
+ case 2:
+ /* Jsr 0100111010mmmrrr */
+ if (CheckControlAddrMode(p)) {
+#if WantCycByPriOp
+ switch (mode(p)) {
+ case 2:
+ p->Cycles = (16 * kCycleScale
+ + 2 * RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc);
+ break;
+ case 5:
+ p->Cycles = (18 * kCycleScale
+ + 2 * RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc);
+ break;
+ case 6:
+ p->Cycles = (22 * kCycleScale
+ + 2 * RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc);
+ break;
+ case 7:
+ default: /* keep compiler happy */
+ switch (reg(p)) {
+ case 0:
+ p->Cycles =
+ (18 * kCycleScale
+ + 2 * RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc);
+ break;
+ case 1:
+ p->Cycles =
+ (20 * kCycleScale
+ + 3 * RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc);
+ break;
+ case 2:
+ p->Cycles =
+ (18 * kCycleScale
+ + 2 * RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc);
+ break;
+ case 3:
+ default:
+ /* keep compiler happy */
+ p->Cycles =
+ (22 * kCycleScale
+ + 2 * RdAvgXtraCyc
+ + 2 * WrAvgXtraCyc);
+ break;
+ }
+ break;
+ }
+#endif
+ p->MainClass = kIKindJsr;
+ }
+ break;
+ case 3:
+ default: /* keep compiler happy */
+ /* JMP 0100111011mmmrrr */
+ if (CheckControlAddrMode(p)) {
+#if WantCycByPriOp
+ switch (mode(p)) {
+ case 2:
+ p->Cycles = (8 * kCycleScale
+ + 2 * RdAvgXtraCyc);
+ break;
+ case 5:
+ p->Cycles = (10 * kCycleScale
+ + 2 * RdAvgXtraCyc);
+ break;
+ case 6:
+ p->Cycles = (14 * kCycleScale
+ + 2 * RdAvgXtraCyc);
+ break;
+ case 7:
+ default: /* keep compiler happy */
+ switch (reg(p)) {
+ case 0:
+ p->Cycles =
+ (10 * kCycleScale
+ + 2 * RdAvgXtraCyc);
+ break;
+ case 1:
+ p->Cycles =
+ (12 * kCycleScale
+ + 3 * RdAvgXtraCyc);
+ break;
+ case 2:
+ p->Cycles =
+ (10 * kCycleScale
+ + 2 * RdAvgXtraCyc);
+ break;
+ case 3:
+ default:
+ /* keep compiler happy */
+ p->Cycles =
+ (14 * kCycleScale
+ + 3 * RdAvgXtraCyc);
+ break;
+ }
+ break;
+ }
+#endif
+ p->MainClass = kIKindJmp;
+ }
+ break;
+ }
+ break;
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DeCode5(WorkR *p)
+{
+ if (b76(p) == 3) {
+ p->DecOp.y.v[0].ArgDat = (p->opcode >> 8) & 15;
+ if (mode(p) == 1) {
+ /* DBcc 0101cccc11001ddd */
+#if WantCycByPriOp
+#if WantCloserCyc
+ p->Cycles = 0;
+#else
+ p->Cycles = (11 * kCycleScale + 2 * RdAvgXtraCyc);
+ /*
+ average of cc true 12(2/0),
+ cc false taken 10(2/0),
+ and not 14(3/0)
+ */
+#endif
+#endif
+ SetDcoArgFields(p, falseblnr, kAMdRegW, reg(p));
+ if (1 == ((p->opcode >> 8) & 15)) {
+ p->MainClass = kIKindDBF;
+ } else {
+ p->MainClass = kIKindDBcc;
+ }
+ } else {
+#if Use68020
+ if ((mode(p) == 7) && (reg(p) >= 2)) {
+ /* TRAPcc 0101cccc11111sss */
+ p->DecOp.y.v[1].ArgDat = reg(p);
+ p->MainClass = kIKindTRAPcc;
+ } else
+#endif
+ {
+ p->opsize = 1;
+ /* Scc 0101cccc11mmmrrr */
+ if (CheckDataAltAddrMode(p)) {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ } else {
+#if WantCloserCyc
+ p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
+#else
+ p->Cycles = (5 * kCycleScale + RdAvgXtraCyc);
+ /* 4 when false, 6 when true */
+#endif
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindScc;
+ }
+ }
+ }
+ } else {
+ if (mode(p) == 1) {
+ p->opsize = b8(p) * 2 + 2;
+ SetDcoArgFields(p, trueblnr, kAMdDat4,
+ octdat(rg9(p)));
+ SetDcoArgFields(p, falseblnr, kAMdRegL,
+ reg(p) + 8);
+ /* always long, regardless of opsize */
+ if (b8(p) == 0) {
+#if WantCycByPriOp
+ p->Cycles = (4 == p->opsize)
+ ? (8 * kCycleScale + RdAvgXtraCyc)
+ : (4 * kCycleScale + RdAvgXtraCyc);
+#endif
+ p->MainClass = kIKindAddQA; /* AddQA 0101nnn0ss001rrr */
+ } else {
+#if WantCycByPriOp
+ p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
+#endif
+ p->MainClass = kIKindSubQA; /* SubQA 0101nnn1ss001rrr */
+ }
+ } else {
+ FindOpSizeFromb76(p);
+ SetDcoArgFields(p, trueblnr, kAMdDat4,
+ octdat(rg9(p)));
+ if (CheckValidAddrMode(p,
+ mode(p), reg(p), kAddrValidDataAlt, falseblnr))
+ {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (4 == p->opsize)
+ ? (12 * kCycleScale
+ + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (4 == p->opsize)
+ ? (8 * kCycleScale + RdAvgXtraCyc)
+ : (4 * kCycleScale + RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ if (b8(p) == 0) {
+ /* AddQ 0101nnn0ssmmmrrr */
+#if 0
+ if (CheckDataAltAddrMode(p)) {
+ p->MainClass = kIKindAddQ;
+ }
+#endif
+ p->MainClass = kIKindAddB + OpSizeOffset(p);
+ } else {
+ /* SubQ 0101nnn1ssmmmrrr */
+#if 0
+ if (CheckDataAltAddrMode(p)) {
+ p->MainClass = kIKindSubQ;
+ }
+#endif
+ p->MainClass = kIKindSubB + OpSizeOffset(p);
+ }
+ }
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DeCode6(WorkR *p)
+{
+ ui5b cond = (p->opcode >> 8) & 15;
+
+ if (cond == 1) {
+ /* Bsr 01100001nnnnnnnn */
+#if WantCycByPriOp
+ p->Cycles = (18 * kCycleScale
+ + 2 * RdAvgXtraCyc + 2 * WrAvgXtraCyc);
+#endif
+ if (0 == (p->opcode & 255)) {
+ p->MainClass = kIKindBsrW;
+ } else
+#if Use68020
+ if (255 == (p->opcode & 255)) {
+ p->MainClass = kIKindBsrL;
+ } else
+#endif
+ {
+ p->MainClass = kIKindBsrB;
+ p->DecOp.y.v[1].ArgDat = p->opcode & 255;
+ }
+ } else if (cond == 0) {
+ /* Bra 01100000nnnnnnnn */
+#if WantCycByPriOp
+ p->Cycles = (10 * kCycleScale + 2 * RdAvgXtraCyc);
+#endif
+ if (0 == (p->opcode & 255)) {
+ p->MainClass = kIKindBraW;
+ } else
+#if Use68020
+ if (255 == (p->opcode & 255)) {
+ p->MainClass = kIKindBraL;
+ } else
+#endif
+ {
+ p->MainClass = kIKindBraB;
+ p->DecOp.y.v[1].ArgDat = p->opcode & 255;
+ }
+ } else {
+ p->DecOp.y.v[0].ArgDat = cond;
+ /* Bcc 0110ccccnnnnnnnn */
+ if (0 == (p->opcode & 255)) {
+#if WantCycByPriOp
+#if WantCloserCyc
+ p->Cycles = 0;
+#else
+ p->Cycles = (11 * kCycleScale + 2 * RdAvgXtraCyc);
+ /* average of branch taken 10(2/0) and not 12(2/0) */
+#endif
+#endif
+ p->MainClass = kIKindBccW;
+ } else
+#if Use68020
+ if (255 == (p->opcode & 255)) {
+ p->MainClass = kIKindBccL;
+ } else
+#endif
+ {
+#if WantCycByPriOp
+#if WantCloserCyc
+ p->Cycles = 0;
+#else
+ p->Cycles = (9 * kCycleScale
+ + RdAvgXtraCyc + (RdAvgXtraCyc / 2));
+ /* average of branch taken 10(2/0) and not 8(1/0) */
+#endif
+#endif
+ p->MainClass = kIKindBccB;
+ p->DecOp.y.v[1].ArgDat = p->opcode & 255;
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DeCode7(WorkR *p)
+{
+ if (b8(p) == 0) {
+ p->opsize = 4;
+#if WantCycByPriOp
+ p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
+#endif
+ p->MainClass = kIKindMoveQ;
+ p->DecOp.y.v[0].ArgDat = p->opcode & 255;
+ p->DecOp.y.v[1].ArgDat = rg9(p);
+ } else {
+ p->MainClass = kIKindIllegal;
+ }
+}
+
+LOCALPROCUSEDONCE DeCode8(WorkR *p)
+{
+ if (b76(p) == 3) {
+ p->opsize = 2;
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidData, trueblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+ if (b8(p) == 0) {
+ /* DivU 1000ddd011mmmrrr */
+#if WantCycByPriOp
+ p->Cycles = RdAvgXtraCyc;
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#if ! WantCloserCyc
+ p->Cycles += 133 * kCycleScale;
+ /*
+ worse case 140, less than ten percent
+ different from best case
+ */
+#endif
+#endif
+ p->MainClass = kIKindDivU;
+ } else {
+ /* DivS 1000ddd111mmmrrr */
+#if WantCycByPriOp
+ p->Cycles = RdAvgXtraCyc;
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#if ! WantCloserCyc
+ p->Cycles += 150 * kCycleScale;
+ /*
+ worse case 158, less than ten percent different
+ from best case
+ */
+#endif
+#endif
+ p->MainClass = kIKindDivS;
+ }
+ }
+ } else {
+ if (b8(p) == 0) {
+ /* OR 1000ddd0ssmmmrrr */
+#if 0
+ if (CheckDataAddrMode(p)) {
+ p->MainClass = kIKindOrEaD;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidData, trueblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+ if (4 == p->opsize) {
+ if ((mode(p) < 2)
+ || ((7 == mode(p)) && (reg(p) == 4)))
+ {
+ p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
+ } else {
+ p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
+ }
+ } else {
+ p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindOrEaD;
+ }
+ } else {
+ if (mode(p) < 2) {
+ switch (b76(p)) {
+ case 0:
+ /* SBCD 1000xxx10000mxxx */
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (18 * kCycleScale
+ + 3 * RdAvgXtraCyc + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (6 * kCycleScale
+ + RdAvgXtraCyc);
+ }
+#endif
+ p->opsize = 1;
+ if (mode(p) == 0) {
+ if (CheckValidAddrMode(p, 0, reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+ p->MainClass = kIKindSbcd;
+ }
+ } else {
+ if (CheckValidAddrMode(p, 4, reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 4, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+ p->MainClass = kIKindSbcd;
+ }
+ }
+ break;
+#if Use68020
+ case 1:
+ /* PACK 1000rrr10100mrrr */
+ if (mode(p) == 0) {
+ p->opsize = 2;
+ if (CheckValidAddrMode(p, 0, reg(p),
+ kAddrValidAny, trueblnr))
+ {
+ p->opsize = 1;
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+ p->MainClass = kIKindPack;
+ }
+ }
+ } else {
+ p->opsize = 2;
+ if (CheckValidAddrMode(p, 4, reg(p),
+ kAddrValidAny, trueblnr))
+ {
+ p->opsize = 1;
+ if (CheckValidAddrMode(p, 4, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+ p->MainClass = kIKindPack;
+ }
+ }
+ }
+ break;
+ case 2:
+ /* UNPK 1000rrr11000mrrr */
+ if (mode(p) == 0) {
+ p->opsize = 1;
+ if (CheckValidAddrMode(p, 0, reg(p),
+ kAddrValidAny, trueblnr))
+ {
+ p->opsize = 2;
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+ p->MainClass = kIKindUnpk;
+ }
+ }
+ } else {
+ p->opsize = 1;
+ if (CheckValidAddrMode(p, 4, reg(p),
+ kAddrValidAny, trueblnr))
+ {
+ p->opsize = 2;
+ if (CheckValidAddrMode(p, 4, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+ p->MainClass = kIKindUnpk;
+ }
+ }
+ }
+ break;
+#endif
+ default:
+ p->MainClass = kIKindIllegal;
+ break;
+ }
+ } else {
+ /* OR 1000ddd1ssmmmrrr */
+#if 0
+ if (CheckDataAltAddrMode(p)) {
+ p->MainClass = kIKindOrDEa;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAltMem, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 == p->opsize)
+ ? (12 * kCycleScale
+ + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindOrDEa;
+ }
+ }
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DeCode9(WorkR *p)
+{
+ if (b76(p) == 3) {
+ /* SUBA 1001dddm11mmmrrr */
+#if 0
+ if (IsValidAddrMode(p)) {
+ p->MainClass = kIKindSubA;
+ }
+#endif
+ p->opsize = b8(p) * 2 + 2;
+ SetDcoArgFields(p, falseblnr, kAMdRegL, rg9(p) + 8);
+ /* always long, regardless of opsize */
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAny, trueblnr))
+ {
+#if WantCycByPriOp
+ if (4 == p->opsize) {
+ if ((mode(p) < 2) || ((7 == mode(p)) && (reg(p) == 4)))
+ {
+ p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
+ } else {
+ p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
+ }
+ } else {
+ p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindSubA;
+ }
+ } else {
+ if (b8(p) == 0) {
+ /* SUB 1001ddd0ssmmmrrr */
+#if 0
+ if (IsValidAddrMode(p)) {
+ p->MainClass = kIKindSubEaR;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+ if (4 == p->opsize) {
+ if ((mode(p) < 2)
+ || ((7 == mode(p)) && (reg(p) == 4)))
+ {
+ p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
+ } else {
+ p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
+ }
+ } else {
+ p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindSubB + OpSizeOffset(p);
+ }
+ } else {
+ if (mode(p) == 0) {
+ /* SUBX 1001ddd1ss000rrr */
+ /* p->MainClass = kIKindSubXd; */
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 0, reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 == p->opsize)
+ ? (8 * kCycleScale + RdAvgXtraCyc)
+ : (4 * kCycleScale + RdAvgXtraCyc);
+#endif
+ p->MainClass = kIKindSubXB + OpSizeOffset(p);
+ }
+ } else if (mode(p) == 1) {
+ /* SUBX 1001ddd1ss001rrr */
+ /* p->MainClass = kIKindSubXm; */
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 4, reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 4, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 == p->opsize)
+ ? (30 * kCycleScale
+ + 5 * RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (18 * kCycleScale
+ + 3 * RdAvgXtraCyc + 1 * WrAvgXtraCyc);
+#endif
+ p->MainClass = kIKindSubXB + OpSizeOffset(p);
+ }
+ } else {
+ /* SUB 1001ddd1ssmmmrrr */
+#if 0
+ if (CheckAltMemAddrMode(p)) {
+ p->MainClass = kIKindSubREa;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, mode(p),
+ reg(p), kAddrValidAltMem, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 == p->opsize)
+ ? (12 * kCycleScale
+ + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindSubB + OpSizeOffset(p);
+ }
+ }
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DeCodeA(WorkR *p)
+{
+#if WantCycByPriOp
+ p->Cycles = (34 * kCycleScale
+ + 4 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
+#endif
+ p->MainClass = kIKindA;
+}
+
+LOCALPROCUSEDONCE DeCodeB(WorkR *p)
+{
+ if (b76(p) == 3) {
+ /* CMPA 1011ddds11mmmrrr */
+#if 0
+ if (IsValidAddrMode(p)) {
+ p->MainClass = kIKindCmpA;
+ }
+#endif
+ p->opsize = b8(p) * 2 + 2;
+ SetDcoArgFields(p, falseblnr, kAMdRegL, rg9(p) + 8);
+ /* always long, regardless of opsize */
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAny, trueblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindCmpA;
+ }
+ } else if (b8(p) == 1) {
+ if (mode(p) == 1) {
+ /* CmpM 1011ddd1ss001rrr */
+#if 0
+ p->MainClass = kIKindCmpM;
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 3, reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 3, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 == p->opsize)
+ ? (20 * kCycleScale + 5 * RdAvgXtraCyc)
+ : (12 * kCycleScale + 3 * RdAvgXtraCyc);
+#endif
+ p->MainClass = kIKindCmpB + OpSizeOffset(p);
+ }
+ } else {
+#if 0
+ /* Eor 1011ddd1ssmmmrrr */
+ if (CheckDataAltAddrMode(p)) {
+ p->MainClass = kIKindEor;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidDataAlt, falseblnr))
+ {
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (4 == p->opsize)
+ ? (12 * kCycleScale
+ + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (4 == p->opsize)
+ ? (8 * kCycleScale + RdAvgXtraCyc)
+ : (4 * kCycleScale + RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindEor;
+ }
+ }
+ } else {
+ /* Cmp 1011ddd0ssmmmrrr */
+#if 0
+ if (IsValidAddrMode(p)) {
+ p->MainClass = kIKindCmp;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 == p->opsize)
+ ? (6 * kCycleScale + RdAvgXtraCyc)
+ : (4 * kCycleScale + RdAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindCmpB + OpSizeOffset(p);
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DeCodeC(WorkR *p)
+{
+ if (b76(p) == 3) {
+ p->opsize = 2;
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidData, trueblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+#if WantCloserCyc
+ p->Cycles = (38 * kCycleScale + RdAvgXtraCyc);
+#else
+ p->Cycles = (54 * kCycleScale + RdAvgXtraCyc);
+ /* worst case 70, best case 38 */
+#endif
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ if (b8(p) == 0) {
+ /* MulU 1100ddd011mmmrrr */
+ p->MainClass = kIKindMulU;
+ } else {
+ /* MulS 1100ddd111mmmrrr */
+ p->MainClass = kIKindMulS;
+ }
+ }
+ } else {
+ if (b8(p) == 0) {
+ /* And 1100ddd0ssmmmrrr */
+#if 0
+ if (CheckDataAddrMode(p)) {
+ p->MainClass = kIKindAndEaD;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidData, trueblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+ if (4 == p->opsize) {
+ if ((mode(p) < 2)
+ || ((7 == mode(p)) && (reg(p) == 4)))
+ {
+ p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
+ } else {
+ p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
+ }
+ } else {
+ p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindAndEaD;
+ }
+ } else {
+ if (mode(p) < 2) {
+ switch (b76(p)) {
+ case 0:
+ /* ABCD 1100ddd10000mrrr */
+#if WantCycByPriOp
+ if (0 != mode(p)) {
+ p->Cycles = (18 * kCycleScale
+ + 3 * RdAvgXtraCyc + WrAvgXtraCyc);
+ } else {
+ p->Cycles = (6 * kCycleScale
+ + RdAvgXtraCyc);
+ }
+#endif
+ p->opsize = 1;
+ if (mode(p) == 0) {
+ if (CheckValidAddrMode(p, 0, reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+ p->MainClass = kIKindAbcd;
+ }
+ } else {
+ if (CheckValidAddrMode(p, 4, reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 4, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+ p->MainClass = kIKindAbcd;
+ }
+ }
+ break;
+ case 1:
+ /* Exg 1100ddd10100trrr */
+#if WantCycByPriOp
+ p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
+#endif
+ p->opsize = 4;
+ if (mode(p) == 0) {
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 0, reg(p),
+ kAddrValidAny, falseblnr))
+ {
+ p->MainClass = kIKindExg;
+ }
+ } else {
+ if (CheckValidAddrMode(p, 1, rg9(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 1, reg(p),
+ kAddrValidAny, falseblnr))
+ {
+ p->MainClass = kIKindExg;
+ }
+ }
+ break;
+ case 2:
+ default: /* keep compiler happy */
+ if (mode(p) == 0) {
+ p->MainClass = kIKindIllegal;
+ } else {
+ /* Exg 1100ddd110001rrr */
+#if WantCycByPriOp
+ p->Cycles = (6 * kCycleScale
+ + RdAvgXtraCyc);
+#endif
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 1, reg(p),
+ kAddrValidAny, falseblnr))
+ {
+ p->MainClass = kIKindExg;
+ }
+ }
+ break;
+ }
+ } else {
+ /* And 1100ddd1ssmmmrrr */
+#if 0
+ if (CheckAltMemAddrMode(p)) {
+ p->MainClass = kIKindAndDEa;
+ }
+#endif
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAltMem, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 == p->opsize)
+ ? (12 * kCycleScale
+ + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindAndDEa;
+ }
+ }
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DeCodeD(WorkR *p)
+{
+ if (b76(p) == 3) {
+ /* ADDA 1101dddm11mmmrrr */
+ p->opsize = b8(p) * 2 + 2;
+ SetDcoArgFields(p, falseblnr, kAMdRegL, rg9(p) + 8);
+ /* always long, regardless of opsize */
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAny, trueblnr))
+ {
+#if WantCycByPriOp
+ if (4 == p->opsize) {
+ if ((mode(p) < 2) || ((7 == mode(p)) && (reg(p) == 4)))
+ {
+ p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
+ } else {
+ p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
+ }
+ } else {
+ p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindAddA;
+ }
+ } else {
+ if (b8(p) == 0) {
+ /* ADD 1101ddd0ssmmmrrr */
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+ if (4 == p->opsize) {
+ if ((mode(p) < 2)
+ || ((7 == mode(p)) && (reg(p) == 4)))
+ {
+ p->Cycles = (8 * kCycleScale + RdAvgXtraCyc);
+ } else {
+ p->Cycles = (6 * kCycleScale + RdAvgXtraCyc);
+ }
+ } else {
+ p->Cycles = (4 * kCycleScale + RdAvgXtraCyc);
+ }
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindAddB + OpSizeOffset(p);
+ }
+ } else {
+ if (mode(p) == 0) {
+ /* ADDX 1101ddd1ss000rrr */
+ /* p->MainClass = kIKindAddXd; */
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 0, reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 == p->opsize)
+ ? (8 * kCycleScale + RdAvgXtraCyc)
+ : (4 * kCycleScale + RdAvgXtraCyc);
+#endif
+ p->MainClass = kIKindAddXB + OpSizeOffset(p);
+ }
+ } else if (mode(p) == 1) {
+ /* p->MainClass = kIKindAddXm; */
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 4, reg(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 4, rg9(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 == p->opsize)
+ ? (30 * kCycleScale
+ + 5 * RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (18 * kCycleScale
+ + 3 * RdAvgXtraCyc + 1 * WrAvgXtraCyc);
+#endif
+ p->MainClass = kIKindAddXB + OpSizeOffset(p);
+ }
+ } else {
+ /* ADD 1101ddd1ssmmmrrr */
+ FindOpSizeFromb76(p);
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, mode(p), reg(p),
+ kAddrValidAltMem, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = (4 == p->opsize)
+ ? (12 * kCycleScale
+ + RdAvgXtraCyc + 2 * WrAvgXtraCyc)
+ : (8 * kCycleScale
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = kIKindAddB + OpSizeOffset(p);
+ }
+ }
+ }
+ }
+}
+
+LOCALFUNC ui5r rolops(WorkR *p, ui5r x)
+{
+ ui5r binop;
+
+ binop = (x << 1);
+ if (! b8(p)) {
+ binop++; /* 'R' */
+ } /* else 'L' */
+
+ return kIKindAslB + 3 * binop + OpSizeOffset(p);
+}
+
+LOCALPROCUSEDONCE DeCodeE(WorkR *p)
+{
+ if (b76(p) == 3) {
+ if ((p->opcode & 0x0800) != 0) {
+#if Use68020
+ /* 11101???11mmmrrr */
+ p->DecOp.y.v[0].AMd = mode(p);
+ p->DecOp.y.v[0].ArgDat = (p->opcode >> 8) & 7;
+ if (0 == mode(p)) {
+ SetDcoArgFields(p, falseblnr, kAMdRegL, reg(p));
+ p->MainClass = kIKindBitField;
+ } else {
+ switch ((p->opcode >> 8) & 7) {
+ case 0: /* BFTST */
+ case 1: /* BFEXTU */
+ case 3: /* BFEXTS */
+ case 5: /* BFFFO */
+ if (CheckControlAddrMode(p)) {
+ p->MainClass = kIKindBitField;
+ }
+ break;
+ default: /* BFCHG, BFCLR, BFSET, BFINS */
+ if (CheckControlAltAddrMode(p)) {
+ p->MainClass = kIKindBitField;
+ }
+ break;
+ }
+ }
+#else
+ p->MainClass = kIKindIllegal;
+#endif
+ } else {
+ p->opsize = 2;
+ /* 11100ttd11mmmddd */
+ if (CheckAltMemAddrMode(p)) {
+#if WantCycByPriOp
+ p->Cycles = (6 * kCycleScale
+#if ! WantCloserCyc
+ + 2 * kCycleScale
+#endif
+ + RdAvgXtraCyc + WrAvgXtraCyc);
+ p->Cycles += OpEACalcCyc(p, mode(p), reg(p));
+#endif
+ p->MainClass = rolops(p, rg9(p));
+ SetDcoArgFields(p, trueblnr, kAMdDat4, 1);
+ }
+ }
+ } else {
+ FindOpSizeFromb76(p);
+ if (mode(p) < 4) {
+ /* 1110cccdss0ttddd */
+ if (CheckValidAddrMode(p, 0, reg(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+ p->Cycles = ((4 == p->opsize)
+ ? (8 * kCycleScale + RdAvgXtraCyc)
+ : (6 * kCycleScale + RdAvgXtraCyc))
+#if ! WantCloserCyc
+ + (octdat(rg9(p)) * (2 * kCycleScale))
+#endif
+ ;
+#endif
+ p->MainClass = rolops(p, mode(p) & 3);
+ SetDcoArgFields(p, trueblnr, kAMdDat4, octdat(rg9(p)));
+ }
+ } else {
+ /* 1110rrrdss1ttddd */
+ if (CheckValidAddrMode(p, 0, rg9(p),
+ kAddrValidAny, trueblnr))
+ if (CheckValidAddrMode(p, 0, reg(p),
+ kAddrValidAny, falseblnr))
+ {
+#if WantCycByPriOp
+#if WantCloserCyc
+ p->Cycles = ((4 == p->opsize)
+ ? (8 * kCycleScale + RdAvgXtraCyc)
+ : (6 * kCycleScale + RdAvgXtraCyc));
+#else
+ p->Cycles = (4 == p->opsize)
+ ? ((8 * kCycleScale)
+ + RdAvgXtraCyc + (8 * (2 * kCycleScale)))
+ /* say average shift count of 8 */
+ : ((6 * kCycleScale)
+ + RdAvgXtraCyc + (4 * (2 * kCycleScale)));
+ /* say average shift count of 4 */
+#endif
+#endif
+ p->MainClass = rolops(p, mode(p) & 3);
+ }
+ }
+ }
+}
+
+LOCALPROCUSEDONCE DeCodeF(WorkR *p)
+{
+#if WantCycByPriOp
+ p->Cycles =
+ (34 * kCycleScale + 4 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
+#endif
+ p->DecOp.y.v[0].AMd = (p->opcode >> 8) & 0xFF;
+ p->DecOp.y.v[0].ArgDat = (p->opcode ) & 0xFF;
+#if EmMMU || EmFPU
+ switch (rg9(p)) {
+#if EmMMU
+ case 0:
+ p->MainClass = kIKindMMU;
+ break;
+#endif
+#if EmFPU
+ case 1:
+ switch (md6(p)) {
+ case 0:
+ p->MainClass = kIKindFPUmd60;
+ break;
+ case 1:
+ if (mode(p) == 1) {
+ p->MainClass = kIKindFPUDBcc;
+ } else if (mode(p) == 7) {
+ p->MainClass = kIKindFPUTrapcc;
+ } else {
+ p->MainClass = kIKindFPUScc;
+ }
+ break;
+ case 2:
+ p->MainClass = kIKindFPUFBccW;
+ break;
+ case 3:
+ p->MainClass = kIKindFPUFBccL;
+ break;
+ case 4:
+ p->MainClass = kIKindFPUSave;
+ break;
+ case 5:
+ p->MainClass = kIKindFPURestore;
+ break;
+ default:
+ p->MainClass = kIKindFPUdflt;
+ break;
+ }
+ break;
+#endif
+ default:
+ p->MainClass = kIKindFdflt;
+ break;
+ }
+#else
+ p->MainClass = kIKindFdflt;
+#endif
+}
+
+LOCALPROC DeCodeOneOp(WorkR *p)
+{
+ switch (p->opcode >> 12) {
+ case 0x0:
+ DeCode0(p);
+ break;
+ case 0x1:
+ DeCode1(p);
+ break;
+ case 0x2:
+ DeCode2(p);
+ break;
+ case 0x3:
+ DeCode3(p);
+ break;
+ case 0x4:
+ DeCode4(p);
+ break;
+ case 0x5:
+ DeCode5(p);
+ break;
+ case 0x6:
+ DeCode6(p);
+ break;
+ case 0x7:
+ DeCode7(p);
+ break;
+ case 0x8:
+ DeCode8(p);
+ break;
+ case 0x9:
+ DeCode9(p);
+ break;
+ case 0xA:
+ DeCodeA(p);
+ break;
+ case 0xB:
+ DeCodeB(p);
+ break;
+ case 0xC:
+ DeCodeC(p);
+ break;
+ case 0xD:
+ DeCodeD(p);
+ break;
+ case 0xE:
+ DeCodeE(p);
+ break;
+ case 0xF:
+ default: /* keep compiler happy */
+ DeCodeF(p);
+ break;
+ }
+
+ if (kIKindIllegal == p->MainClass) {
+#if WantCycByPriOp
+ p->Cycles = (34 * kCycleScale
+ + 4 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
+#endif
+ p->DecOp.y.v[0].AMd = 0;
+ p->DecOp.y.v[0].ArgDat = 0;
+ p->DecOp.y.v[1].AMd = 0;
+ p->DecOp.y.v[1].ArgDat = 0;
+ }
+
+ SetDcoMainClas(&(p->DecOp), p->MainClass);
+#if WantCycByPriOp
+ SetDcoCycles(&(p->DecOp), p->Cycles);
+#else
+ SetDcoCycles(&(p->DecOp), kMyAvgCycPerInstr);
+#endif
+}
+
+GLOBALPROC M68KITAB_setup(DecOpR *p)
+{
+ ui5b i;
+ WorkR r;
+
+ for (i = 0; i < (ui5b)256 * 256; ++i) {
+ r.opcode = i;
+ r.MainClass = kIKindIllegal;
+
+ r.DecOp.y.v[0].AMd = 0;
+ r.DecOp.y.v[0].ArgDat = 0;
+ r.DecOp.y.v[1].AMd = 0;
+ r.DecOp.y.v[1].ArgDat = 0;
+#if WantCycByPriOp
+ r.Cycles = kMyAvgCycPerInstr;
+#endif
+
+ DeCodeOneOp(&r);
+
+ p[i] = r.DecOp;
+ }
+}
--- /dev/null
+++ b/src/M68KITAB.h
@@ -1,0 +1,279 @@
+/*
+ M68KITAB.h
+
+ Copyright (C) 2007, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef M68KITAB_H
+#error "header already included"
+#else
+#define M68KITAB_H
+#endif
+
+enum {
+ kIKindTst,
+ kIKindCmpB,
+ kIKindCmpW,
+ kIKindCmpL,
+ kIKindBccB,
+ kIKindBccW,
+ kIKindBraB,
+ kIKindBraW,
+ kIKindDBcc,
+ kIKindDBF,
+ kIKindSwap,
+ kIKindMoveL,
+ kIKindMoveW,
+ kIKindMoveB,
+ kIKindMoveAL,
+ kIKindMoveAW,
+ kIKindMoveQ,
+ kIKindAddB,
+ kIKindAddW,
+ kIKindAddL,
+ kIKindSubB,
+ kIKindSubW,
+ kIKindSubL,
+ kIKindLea,
+ kIKindPEA,
+ kIKindA,
+ kIKindBsrB,
+ kIKindBsrW,
+ kIKindJsr,
+ kIKindLinkA6,
+ kIKindMOVEMRmML,
+ kIKindMOVEMApRL,
+ kIKindUnlkA6,
+ kIKindRts,
+ kIKindJmp,
+ kIKindClr,
+ kIKindAddA,
+ kIKindAddQA,
+ kIKindSubA,
+ kIKindSubQA,
+ kIKindCmpA,
+ kIKindAddXB,
+ kIKindAddXW,
+ kIKindAddXL,
+ kIKindSubXB,
+ kIKindSubXW,
+ kIKindSubXL,
+ kIKindAslB,
+ kIKindAslW,
+ kIKindAslL,
+ kIKindAsrB,
+ kIKindAsrW,
+ kIKindAsrL,
+ kIKindLslB,
+ kIKindLslW,
+ kIKindLslL,
+ kIKindLsrB,
+ kIKindLsrW,
+ kIKindLsrL,
+ kIKindRxlB,
+ kIKindRxlW,
+ kIKindRxlL,
+ kIKindRxrB,
+ kIKindRxrW,
+ kIKindRxrL,
+ kIKindRolB,
+ kIKindRolW,
+ kIKindRolL,
+ kIKindRorB,
+ kIKindRorW,
+ kIKindRorL,
+ kIKindBTstB,
+ kIKindBChgB,
+ kIKindBClrB,
+ kIKindBSetB,
+ kIKindBTstL,
+ kIKindBChgL,
+ kIKindBClrL,
+ kIKindBSetL,
+ kIKindAndI,
+ kIKindAndEaD,
+ kIKindAndDEa,
+ kIKindOrI,
+ kIKindOrDEa,
+ kIKindOrEaD,
+ kIKindEor,
+ kIKindEorI,
+ kIKindNot,
+ kIKindScc,
+ kIKindNegXB,
+ kIKindNegXW,
+ kIKindNegXL,
+ kIKindNegB,
+ kIKindNegW,
+ kIKindNegL,
+ kIKindEXTW,
+ kIKindEXTL,
+ kIKindMulU,
+ kIKindMulS,
+ kIKindDivU,
+ kIKindDivS,
+ kIKindExg,
+ kIKindMoveEaCCR,
+ kIKindMoveSREa,
+ kIKindMoveEaSR,
+ kIKindOrISR,
+ kIKindAndISR,
+ kIKindEorISR,
+ kIKindOrICCR,
+ kIKindAndICCR,
+ kIKindEorICCR,
+ kIKindMOVEMApRW,
+ kIKindMOVEMRmMW,
+ kIKindMOVEMrmW,
+ kIKindMOVEMrmL,
+ kIKindMOVEMmrW,
+ kIKindMOVEMmrL,
+ kIKindAbcd,
+ kIKindSbcd,
+ kIKindNbcd,
+ kIKindRte,
+ kIKindNop,
+ kIKindMoveP0,
+ kIKindMoveP1,
+ kIKindMoveP2,
+ kIKindMoveP3,
+ kIKindIllegal,
+ kIKindChkW,
+ kIKindTrap,
+ kIKindTrapV,
+ kIKindRtr,
+ kIKindLink,
+ kIKindUnlk,
+ kIKindMoveRUSP,
+ kIKindMoveUSPR,
+ kIKindTas,
+ kIKindFdflt,
+ kIKindStop,
+ kIKindReset,
+
+#if Use68020
+ kIKindCallMorRtm,
+ kIKindBraL,
+ kIKindBccL,
+ kIKindBsrL,
+ kIKindEXTBL,
+ kIKindTRAPcc,
+ kIKindChkL,
+ kIKindBkpt,
+ kIKindDivL,
+ kIKindMulL,
+ kIKindRtd,
+ kIKindMoveCCREa,
+ kIKindMoveCEa,
+ kIKindMoveEaC,
+ kIKindLinkL,
+ kIKindPack,
+ kIKindUnpk,
+ kIKindCHK2orCMP2,
+ kIKindCAS2,
+ kIKindCAS,
+ kIKindMoveS,
+ kIKindBitField,
+#endif
+#if EmMMU
+ kIKindMMU,
+#endif
+#if EmFPU
+ kIKindFPUmd60,
+ kIKindFPUDBcc,
+ kIKindFPUTrapcc,
+ kIKindFPUScc,
+ kIKindFPUFBccW,
+ kIKindFPUFBccL,
+ kIKindFPUSave,
+ kIKindFPURestore,
+ kIKindFPUdflt,
+#endif
+
+ kNumIKinds
+};
+
+enum {
+ kAMdRegB,
+ kAMdRegW,
+ kAMdRegL,
+ kAMdIndirectB,
+ kAMdIndirectW,
+ kAMdIndirectL,
+ kAMdAPosIncB,
+ kAMdAPosIncW,
+ kAMdAPosIncL,
+ kAMdAPosInc7B,
+ kAMdAPreDecB,
+ kAMdAPreDecW,
+ kAMdAPreDecL,
+ kAMdAPreDec7B,
+ kAMdADispB,
+ kAMdADispW,
+ kAMdADispL,
+ kAMdAIndexB,
+ kAMdAIndexW,
+ kAMdAIndexL,
+ kAMdAbsWB,
+ kAMdAbsWW,
+ kAMdAbsWL,
+ kAMdAbsLB,
+ kAMdAbsLW,
+ kAMdAbsLL,
+ kAMdPCDispB,
+ kAMdPCDispW,
+ kAMdPCDispL,
+ kAMdPCIndexB,
+ kAMdPCIndexW,
+ kAMdPCIndexL,
+ kAMdImmedB,
+ kAMdImmedW,
+ kAMdImmedL,
+ kAMdDat4,
+
+ kNumAMds
+};
+
+struct DecOpXR {
+ /* expected size : 4 bytes */
+ ui4b MainClas;
+ ui4b Cycles;
+};
+typedef struct DecOpXR DecOpXR;
+
+struct DecArgR {
+ /* expected size : 2 bytes */
+ ui3b AMd;
+ ui3b ArgDat;
+};
+typedef struct DecArgR DecArgR;
+
+struct DecOpYR {
+ /* expected size : 4 bytes */
+ DecArgR v[2];
+};
+typedef struct DecOpYR DecOpYR;
+
+struct DecOpR {
+ /* expected size : 8 bytes */
+ DecOpXR x;
+ DecOpYR y;
+} my_align_8;
+typedef struct DecOpR DecOpR;
+
+#define GetDcoCycles(p) ((p)->x.Cycles)
+
+#define SetDcoMainClas(p, xx) ((p)->x.MainClas = (xx))
+#define SetDcoCycles(p, xx) ((p)->x.Cycles = (xx))
+
+EXPORTPROC M68KITAB_setup(DecOpR *p);
--- /dev/null
+++ b/src/MINEM68K.c
@@ -1,0 +1,8924 @@
+/*
+ MINEM68K.c
+
+ Copyright (C) 2009 Bernd Schmidt, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ EMulator of 68K cpu with GENeric c code (not assembly)
+
+ This code descends from a simple 68000 emulator that I
+ (Paul C. Pratt) wrote long ago. That emulator ran on a 680x0,
+ and used the cpu it ran on to do some of the work. This
+ descendent fills in those holes with code from the
+ Un*x Amiga Emulator by Bernd Schmidt, as found being used in vMac.
+
+ This emulator is about 10 times smaller than the UAE,
+ at the cost of being 2 to 3 times slower.
+
+ FPU Emulation added 9/12/2009 by Ross Martin
+ (this code now located in "FPCPEMDV.h")
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+
+#include "MYOSGLUE.h"
+#include "ENDIANAC.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+
+#include "M68KITAB.h"
+
+#if WantDisasm
+#include "DISAM68K.h"
+#endif
+#endif
+
+#include "MINEM68K.h"
+
+/*
+ ReportAbnormalID unused 0x0123 - 0x01FF
+*/
+
+#ifndef DisableLazyFlagAll
+#define DisableLazyFlagAll 0
+#endif
+ /*
+ useful for debugging, to tell if an observed bug is
+ being cause by lazy flag evaluation stuff.
+ Can also disable parts of it individually:
+ */
+
+#ifndef ForceFlagsEval
+#if DisableLazyFlagAll
+#define ForceFlagsEval 1
+#else
+#define ForceFlagsEval 0
+#endif
+#endif
+
+#ifndef UseLazyZ
+#if DisableLazyFlagAll || ForceFlagsEval
+#define UseLazyZ 0
+#else
+#define UseLazyZ 1
+#endif
+#endif
+
+#ifndef UseLazyCC
+#if DisableLazyFlagAll
+#define UseLazyCC 0
+#else
+#define UseLazyCC 1
+#endif
+#endif
+
+
+typedef unsigned char flagtype; /* must be 0 or 1, not boolean */
+
+
+/* Memory Address Translation Cache record */
+
+struct MATCr {
+ ui5r cmpmask;
+ ui5r cmpvalu;
+ ui5r usemask;
+ ui3p usebase;
+};
+typedef struct MATCr MATCr;
+typedef MATCr *MATCp;
+
+#ifndef USE_PCLIMIT
+#define USE_PCLIMIT 1
+#endif
+
+#define AKMemory 0
+#define AKRegister 1
+
+union ArgAddrT {
+ ui5r mem;
+ ui5r *rga;
+};
+typedef union ArgAddrT ArgAddrT;
+
+enum {
+ kLazyFlagsDefault,
+ kLazyFlagsTstB,
+ kLazyFlagsTstW,
+ kLazyFlagsTstL,
+ kLazyFlagsCmpB,
+ kLazyFlagsCmpW,
+ kLazyFlagsCmpL,
+ kLazyFlagsSubB,
+ kLazyFlagsSubW,
+ kLazyFlagsSubL,
+ kLazyFlagsAddB,
+ kLazyFlagsAddW,
+ kLazyFlagsAddL,
+ kLazyFlagsNegB,
+ kLazyFlagsNegW,
+ kLazyFlagsNegL,
+ kLazyFlagsAsrB,
+ kLazyFlagsAsrW,
+ kLazyFlagsAsrL,
+ kLazyFlagsAslB,
+ kLazyFlagsAslW,
+ kLazyFlagsAslL,
+#if UseLazyZ
+ kLazyFlagsZSet,
+#endif
+
+ kNumLazyFlagsKinds
+};
+
+typedef void (my_reg_call *ArgSetDstP)(ui5r f);
+
+#define FasterAlignedL 0
+ /*
+ If most long memory access is long aligned,
+ this should be faster. But on the Mac, this
+ doesn't seem to be the case, so an
+ unpredictable branch slows it down.
+ */
+
+#ifndef HaveGlbReg
+#define HaveGlbReg 0
+#endif
+
+LOCALVAR struct regstruct
+{
+ ui5r regs[16]; /* Data and Address registers */
+
+ ui3p pc_p;
+ ui3p pc_pHi;
+ si5rr MaxCyclesToGo;
+
+#if WantCloserCyc
+ DecOpR *CurDecOp;
+#endif
+ DecOpYR CurDecOpY;
+
+ ui3r LazyFlagKind;
+ ui3r LazyXFlagKind;
+#if UseLazyZ
+ ui3r LazyFlagZSavedKind;
+#endif
+ ui5r LazyFlagArgSrc;
+ ui5r LazyFlagArgDst;
+ ui5r LazyXFlagArgSrc;
+ ui5r LazyXFlagArgDst;
+
+ ArgAddrT ArgAddr;
+ ArgSetDstP ArgSetDst;
+ ui5b SrcVal;
+
+ ui3p pc_pLo;
+ ui5r pc; /* Program Counter */
+
+ MATCr MATCrdB;
+ MATCr MATCwrB;
+ MATCr MATCrdW;
+ MATCr MATCwrW;
+#if FasterAlignedL
+ MATCr MATCrdL;
+ MATCr MATCwrL;
+#endif
+ ATTep HeadATTel;
+
+ si5r MoreCyclesToGo;
+ si5r ResidualCycles;
+ ui3b fakeword[2];
+
+ /* Status Register */
+ ui5r intmask; /* bits 10-8 : interrupt priority mask */
+ flagtype t1; /* bit 15: Trace mode 1 */
+#if Use68020
+ flagtype t0; /* bit 14: Trace mode 0 */
+#endif
+ flagtype s; /* bit 13: Supervisor or user privilege level */
+#if Use68020
+ flagtype m; /* bit 12: Master or interrupt mode */
+#endif
+
+ flagtype x; /* bit 4: eXtend */
+ flagtype n; /* bit 3: Negative */
+ flagtype z; /* bit 2: Zero */
+ flagtype v; /* bit 1: oVerflow */
+ flagtype c; /* bit 0: Carry */
+
+#if EmMMU | EmFPU
+ ui5b ArgKind;
+#endif
+
+ blnr TracePending;
+ blnr ExternalInterruptPending;
+#if 0
+ blnr ResetPending;
+#endif
+ ui3b *fIPL;
+#ifdef r_regs
+ struct regstruct *save_regs;
+#endif
+
+ CPTR usp; /* User Stack Pointer */
+ CPTR isp; /* Interrupt Stack Pointer */
+#if Use68020
+ CPTR msp; /* Master Stack Pointer */
+ ui5b sfc; /* Source Function Code register */
+ ui5b dfc; /* Destination Function Code register */
+ ui5b vbr; /* Vector Base Register */
+ ui5b cacr; /* Cache Control Register */
+ /*
+ bit 0 : Enable Cache
+ bit 1 : Freeze Cache
+ bit 2 : Clear Entry In Cache (write only)
+ bit 3 : Clear Cache (write only)
+ */
+ ui5b caar; /* Cache Address Register */
+#endif
+
+#define disp_table_sz (256 * 256)
+#if SmallGlobals
+ DecOpR *disp_table;
+#else
+ DecOpR disp_table[disp_table_sz];
+#endif
+} regs;
+
+#define ui5r_MSBisSet(x) (((si5r)(x)) < 0)
+
+#define Bool2Bit(x) ((x) ? 1 : 0)
+
+
+#ifdef r_regs
+register struct regstruct *g_regs asm (r_regs);
+#define V_regs (*g_regs)
+#else
+#define V_regs regs
+#endif
+
+#ifdef r_pc_p
+register ui3p g_pc_p asm (r_pc_p);
+#define V_pc_p g_pc_p
+#else
+#define V_pc_p V_regs.pc_p
+#endif
+
+#ifdef r_MaxCyclesToGo
+register si5rr g_MaxCyclesToGo asm (r_MaxCyclesToGo);
+#define V_MaxCyclesToGo g_MaxCyclesToGo
+#else
+#define V_MaxCyclesToGo V_regs.MaxCyclesToGo
+#endif
+
+#ifdef r_pc_pHi
+register ui3p g_pc_pHi asm (r_pc_pHi);
+#define V_pc_pHi g_pc_pHi
+#else
+#define V_pc_pHi V_regs.pc_pHi
+#endif
+
+#define ZFLG V_regs.z
+#define NFLG V_regs.n
+#define CFLG V_regs.c
+#define VFLG V_regs.v
+#define XFLG V_regs.x
+
+#define m68k_dreg(num) (V_regs.regs[(num)])
+#define m68k_areg(num) (V_regs.regs[(num) + 8])
+
+
+#ifndef WantDumpTable
+#define WantDumpTable 0
+#endif
+
+#if WantDumpTable
+LOCALVAR ui5b DumpTable[kNumIKinds];
+#endif
+
+#if USE_PCLIMIT
+FORWARDPROC Recalc_PC_Block(void);
+FORWARDFUNC ui5r my_reg_call Recalc_PC_BlockReturnUi5r(ui5r v);
+#endif
+
+LOCALINLINEFUNC ui4r nextiword(void)
+/* NOT sign extended */
+{
+ ui4r r = do_get_mem_word(V_pc_p);
+ V_pc_p += 2;
+
+#if USE_PCLIMIT
+ if (my_cond_rare(V_pc_p >= V_pc_pHi)) {
+ Recalc_PC_Block();
+ }
+#endif
+
+ return r;
+}
+
+LOCALINLINEFUNC ui5r nextiSByte(void)
+{
+ ui5r r = ui5r_FromSByte(do_get_mem_byte(V_pc_p + 1));
+ V_pc_p += 2;
+
+#if USE_PCLIMIT
+ if (my_cond_rare(V_pc_p >= V_pc_pHi)) {
+ return Recalc_PC_BlockReturnUi5r(r);
+ }
+#endif
+
+ return r;
+}
+
+LOCALINLINEFUNC ui5r nextiSWord(void)
+/* NOT sign extended */
+{
+ ui5r r = ui5r_FromSWord(do_get_mem_word(V_pc_p));
+ V_pc_p += 2;
+
+#if USE_PCLIMIT
+ if (my_cond_rare(V_pc_p >= V_pc_pHi)) {
+ return Recalc_PC_BlockReturnUi5r(r);
+ }
+#endif
+
+ return r;
+}
+
+FORWARDFUNC ui5r nextilong_ext(void);
+
+LOCALINLINEFUNC ui5r nextilong(void)
+{
+ ui5r r = do_get_mem_long(V_pc_p);
+ V_pc_p += 4;
+
+#if USE_PCLIMIT
+ /* could be two words in different blocks */
+ if (my_cond_rare(V_pc_p >= V_pc_pHi)) {
+ r = nextilong_ext();
+ }
+#endif
+
+ return r;
+}
+
+LOCALINLINEPROC BackupPC(void)
+{
+ V_pc_p -= 2;
+
+#if USE_PCLIMIT
+ if (my_cond_rare(V_pc_p < V_regs.pc_pLo)) {
+ Recalc_PC_Block();
+ }
+#endif
+}
+
+LOCALINLINEFUNC CPTR m68k_getpc(void)
+{
+ return V_regs.pc + (V_pc_p - V_regs.pc_pLo);
+}
+
+
+FORWARDPROC DoCodeTst(void);
+FORWARDPROC DoCodeCmpB(void);
+FORWARDPROC DoCodeCmpW(void);
+FORWARDPROC DoCodeCmpL(void);
+FORWARDPROC DoCodeBccB(void);
+FORWARDPROC DoCodeBccW(void);
+FORWARDPROC DoCodeBraB(void);
+FORWARDPROC DoCodeBraW(void);
+FORWARDPROC DoCodeDBcc(void);
+FORWARDPROC DoCodeDBF(void);
+FORWARDPROC DoCodeSwap(void);
+FORWARDPROC DoCodeMoveL(void);
+FORWARDPROC DoCodeMoveW(void);
+FORWARDPROC DoCodeMoveB(void);
+FORWARDPROC DoCodeMoveA(void);
+FORWARDPROC DoCodeMoveQ(void);
+FORWARDPROC DoCodeAddB(void);
+FORWARDPROC DoCodeAddW(void);
+FORWARDPROC DoCodeAddL(void);
+FORWARDPROC DoCodeSubB(void);
+FORWARDPROC DoCodeSubW(void);
+FORWARDPROC DoCodeSubL(void);
+FORWARDPROC DoCodeLea(void);
+FORWARDPROC DoCodePEA(void);
+FORWARDPROC DoCodeA(void);
+FORWARDPROC DoCodeBsrB(void);
+FORWARDPROC DoCodeBsrW(void);
+FORWARDPROC DoCodeJsr(void);
+FORWARDPROC DoCodeLinkA6(void);
+FORWARDPROC DoCodeMOVEMRmML(void);
+FORWARDPROC DoCodeMOVEMApRL(void);
+FORWARDPROC DoCodeUnlkA6(void);
+FORWARDPROC DoCodeRts(void);
+FORWARDPROC DoCodeJmp(void);
+FORWARDPROC DoCodeClr(void);
+FORWARDPROC DoCodeAddA(void);
+FORWARDPROC DoCodeSubA(void);
+FORWARDPROC DoCodeCmpA(void);
+FORWARDPROC DoCodeAddXB(void);
+FORWARDPROC DoCodeAddXW(void);
+FORWARDPROC DoCodeAddXL(void);
+FORWARDPROC DoCodeSubXB(void);
+FORWARDPROC DoCodeSubXW(void);
+FORWARDPROC DoCodeSubXL(void);
+FORWARDPROC DoCodeAslB(void);
+FORWARDPROC DoCodeAslW(void);
+FORWARDPROC DoCodeAslL(void);
+FORWARDPROC DoCodeAsrB(void);
+FORWARDPROC DoCodeAsrW(void);
+FORWARDPROC DoCodeAsrL(void);
+FORWARDPROC DoCodeLslB(void);
+FORWARDPROC DoCodeLslW(void);
+FORWARDPROC DoCodeLslL(void);
+FORWARDPROC DoCodeLsrB(void);
+FORWARDPROC DoCodeLsrW(void);
+FORWARDPROC DoCodeLsrL(void);
+FORWARDPROC DoCodeRxlB(void);
+FORWARDPROC DoCodeRxlW(void);
+FORWARDPROC DoCodeRxlL(void);
+FORWARDPROC DoCodeRxrB(void);
+FORWARDPROC DoCodeRxrW(void);
+FORWARDPROC DoCodeRxrL(void);
+FORWARDPROC DoCodeRolB(void);
+FORWARDPROC DoCodeRolW(void);
+FORWARDPROC DoCodeRolL(void);
+FORWARDPROC DoCodeRorB(void);
+FORWARDPROC DoCodeRorW(void);
+FORWARDPROC DoCodeRorL(void);
+FORWARDPROC DoCodeBTstB(void);
+FORWARDPROC DoCodeBChgB(void);
+FORWARDPROC DoCodeBClrB(void);
+FORWARDPROC DoCodeBSetB(void);
+FORWARDPROC DoCodeBTstL(void);
+FORWARDPROC DoCodeBChgL(void);
+FORWARDPROC DoCodeBClrL(void);
+FORWARDPROC DoCodeBSetL(void);
+FORWARDPROC DoCodeAnd(void);
+FORWARDPROC DoCodeOr(void);
+FORWARDPROC DoCodeEor(void);
+FORWARDPROC DoCodeNot(void);
+FORWARDPROC DoCodeScc(void);
+FORWARDPROC DoCodeNegXB(void);
+FORWARDPROC DoCodeNegXW(void);
+FORWARDPROC DoCodeNegXL(void);
+FORWARDPROC DoCodeNegB(void);
+FORWARDPROC DoCodeNegW(void);
+FORWARDPROC DoCodeNegL(void);
+FORWARDPROC DoCodeEXTW(void);
+FORWARDPROC DoCodeEXTL(void);
+FORWARDPROC DoCodeMulU(void);
+FORWARDPROC DoCodeMulS(void);
+FORWARDPROC DoCodeDivU(void);
+FORWARDPROC DoCodeDivS(void);
+FORWARDPROC DoCodeExg(void);
+FORWARDPROC DoCodeMoveEaCR(void);
+FORWARDPROC DoCodeMoveSREa(void);
+FORWARDPROC DoCodeMoveEaSR(void);
+FORWARDPROC DoCodeOrISR(void);
+FORWARDPROC DoCodeAndISR(void);
+FORWARDPROC DoCodeEorISR(void);
+FORWARDPROC DoCodeOrICCR(void);
+FORWARDPROC DoCodeAndICCR(void);
+FORWARDPROC DoCodeEorICCR(void);
+FORWARDPROC DoCodeMOVEMApRW(void);
+FORWARDPROC DoCodeMOVEMRmMW(void);
+FORWARDPROC DoCodeMOVEMrmW(void);
+FORWARDPROC DoCodeMOVEMrmL(void);
+FORWARDPROC DoCodeMOVEMmrW(void);
+FORWARDPROC DoCodeMOVEMmrL(void);
+FORWARDPROC DoCodeAbcd(void);
+FORWARDPROC DoCodeSbcd(void);
+FORWARDPROC DoCodeNbcd(void);
+FORWARDPROC DoCodeRte(void);
+FORWARDPROC DoCodeNop(void);
+FORWARDPROC DoCodeMoveP0(void);
+FORWARDPROC DoCodeMoveP1(void);
+FORWARDPROC DoCodeMoveP2(void);
+FORWARDPROC DoCodeMoveP3(void);
+FORWARDPROC op_illg(void);
+FORWARDPROC DoCodeChk(void);
+FORWARDPROC DoCodeTrap(void);
+FORWARDPROC DoCodeTrapV(void);
+FORWARDPROC DoCodeRtr(void);
+FORWARDPROC DoCodeLink(void);
+FORWARDPROC DoCodeUnlk(void);
+FORWARDPROC DoCodeMoveRUSP(void);
+FORWARDPROC DoCodeMoveUSPR(void);
+FORWARDPROC DoCodeTas(void);
+FORWARDPROC DoCodeFdefault(void);
+FORWARDPROC DoCodeStop(void);
+FORWARDPROC DoCodeReset(void);
+
+#if Use68020
+FORWARDPROC DoCodeCallMorRtm(void);
+FORWARDPROC DoCodeBraL(void);
+FORWARDPROC DoCodeBccL(void);
+FORWARDPROC DoCodeBsrL(void);
+FORWARDPROC DoCodeEXTBL(void);
+FORWARDPROC DoCodeTRAPcc(void);
+FORWARDPROC DoCodeBkpt(void);
+FORWARDPROC DoCodeDivL(void);
+FORWARDPROC DoCodeMulL(void);
+FORWARDPROC DoCodeRtd(void);
+FORWARDPROC DoCodeMoveCCREa(void);
+FORWARDPROC DoMoveFromControl(void);
+FORWARDPROC DoMoveToControl(void);
+FORWARDPROC DoCodeLinkL(void);
+FORWARDPROC DoCodePack(void);
+FORWARDPROC DoCodeUnpk(void);
+FORWARDPROC DoCHK2orCMP2(void);
+FORWARDPROC DoCAS2(void);
+FORWARDPROC DoCAS(void);
+FORWARDPROC DoMOVES(void);
+FORWARDPROC DoBitField(void);
+#endif
+
+#if EmMMU
+FORWARDPROC DoCodeMMU(void);
+#endif
+
+#if EmFPU
+FORWARDPROC DoCodeFPU_md60(void);
+FORWARDPROC DoCodeFPU_DBcc(void);
+FORWARDPROC DoCodeFPU_Trapcc(void);
+FORWARDPROC DoCodeFPU_Scc(void);
+FORWARDPROC DoCodeFPU_FBccW(void);
+FORWARDPROC DoCodeFPU_FBccL(void);
+FORWARDPROC DoCodeFPU_Save(void);
+FORWARDPROC DoCodeFPU_Restore(void);
+FORWARDPROC DoCodeFPU_dflt(void);
+#endif
+
+typedef void (*func_pointer_t)(void);
+
+LOCALVAR const func_pointer_t OpDispatch[kNumIKinds + 1] = {
+ DoCodeTst /* kIKindTst */,
+ DoCodeCmpB /* kIKindCmpB */,
+ DoCodeCmpW /* kIKindCmpW */,
+ DoCodeCmpL /* kIKindCmpL */,
+ DoCodeBccB /* kIKindBccB */,
+ DoCodeBccW /* kIKindBccW */,
+ DoCodeBraB /* kIKindBraB */,
+ DoCodeBraW /* kIKindBraW */,
+ DoCodeDBcc /* kIKindDBcc */,
+ DoCodeDBF /* kIKindDBF */,
+ DoCodeSwap /* kIKindSwap */,
+ DoCodeMoveL /* kIKindMoveL */,
+ DoCodeMoveW /* kIKindMoveW */,
+ DoCodeMoveB /* kIKindMoveB */,
+ DoCodeMoveA /* kIKindMoveAL */,
+ DoCodeMoveA /* kIKindMoveAW */,
+ DoCodeMoveQ /* kIKindMoveQ */,
+ DoCodeAddB /* kIKindAddB */,
+ DoCodeAddW /* kIKindAddW */,
+ DoCodeAddL /* kIKindAddL */,
+ DoCodeSubB /* kIKindSubB */,
+ DoCodeSubW /* kIKindSubW */,
+ DoCodeSubL /* kIKindSubL */,
+ DoCodeLea /* kIKindLea */,
+ DoCodePEA /* kIKindPEA */,
+ DoCodeA /* kIKindA */,
+ DoCodeBsrB /* kIKindBsrB */,
+ DoCodeBsrW /* kIKindBsrW */,
+ DoCodeJsr /* kIKindJsr */,
+ DoCodeLinkA6 /* kIKindLinkA6 */,
+ DoCodeMOVEMRmML /* kIKindMOVEMRmML */,
+ DoCodeMOVEMApRL /* kIKindMOVEMApRL */,
+ DoCodeUnlkA6 /* kIKindUnlkA6 */,
+ DoCodeRts /* kIKindRts */,
+ DoCodeJmp /* kIKindJmp */,
+ DoCodeClr /* kIKindClr */,
+ DoCodeAddA /* kIKindAddA */,
+ DoCodeAddA /* kIKindAddQA */,
+ DoCodeSubA /* kIKindSubA */,
+ DoCodeSubA /* kIKindSubQA */,
+ DoCodeCmpA /* kIKindCmpA */,
+ DoCodeAddXB /* kIKindAddXB */,
+ DoCodeAddXW /* kIKindAddXW */,
+ DoCodeAddXL /* kIKindAddXL */,
+ DoCodeSubXB /* kIKindSubXB */,
+ DoCodeSubXW /* kIKindSubXW */,
+ DoCodeSubXL /* kIKindSubXL */,
+ DoCodeAslB /* kIKindAslB */,
+ DoCodeAslW /* kIKindAslW */,
+ DoCodeAslL /* kIKindAslL */,
+ DoCodeAsrB /* kIKindAsrB */,
+ DoCodeAsrW /* kIKindAsrW */,
+ DoCodeAsrL /* kIKindAsrL */,
+ DoCodeLslB /* kIKindLslB */,
+ DoCodeLslW /* kIKindLslW */,
+ DoCodeLslL /* kIKindLslL */,
+ DoCodeLsrB /* kIKindLsrB */,
+ DoCodeLsrW /* kIKindLsrW */,
+ DoCodeLsrL /* kIKindLsrL */,
+ DoCodeRxlB /* kIKindRxlB */,
+ DoCodeRxlW /* kIKindRxlW */,
+ DoCodeRxlL /* kIKindRxlL */,
+ DoCodeRxrB /* kIKindRxrB */,
+ DoCodeRxrW /* kIKindRxrW */,
+ DoCodeRxrL /* kIKindRxrL */,
+ DoCodeRolB /* kIKindRolB */,
+ DoCodeRolW /* kIKindRolW */,
+ DoCodeRolL /* kIKindRolL */,
+ DoCodeRorB /* kIKindRorB */,
+ DoCodeRorW /* kIKindRorW */,
+ DoCodeRorL /* kIKindRorL */,
+ DoCodeBTstB /* kIKindBTstB */,
+ DoCodeBChgB /* kIKindBChgB */,
+ DoCodeBClrB /* kIKindBClrB */,
+ DoCodeBSetB /* kIKindBSetB */,
+ DoCodeBTstL /* kIKindBTstL */,
+ DoCodeBChgL /* kIKindBChgL */,
+ DoCodeBClrL /* kIKindBClrL */,
+ DoCodeBSetL /* kIKindBSetL */,
+ DoCodeAnd /* kIKindAndI */,
+ DoCodeAnd /* kIKindAndEaD */,
+ DoCodeAnd /* kIKindAndDEa */,
+ DoCodeOr /* kIKindOrI */,
+ DoCodeOr /* kIKindOrDEa */,
+ DoCodeOr /* kIKindOrEaD */,
+ DoCodeEor /* kIKindEor */,
+ DoCodeEor /* kIKindEorI */,
+ DoCodeNot /* kIKindNot */,
+ DoCodeScc /* kIKindScc */,
+ DoCodeNegXB /* kIKindNegXB */,
+ DoCodeNegXW /* kIKindNegXW */,
+ DoCodeNegXL /* kIKindNegXL */,
+ DoCodeNegB /* kIKindNegB */,
+ DoCodeNegW /* kIKindNegW */,
+ DoCodeNegL /* kIKindNegL */,
+ DoCodeEXTW /* kIKindEXTW */,
+ DoCodeEXTL /* kIKindEXTL */,
+ DoCodeMulU /* kIKindMulU */,
+ DoCodeMulS /* kIKindMulS */,
+ DoCodeDivU /* kIKindDivU */,
+ DoCodeDivS /* kIKindDivS */,
+ DoCodeExg /* kIKindExg */,
+ DoCodeMoveEaCR /* kIKindMoveEaCCR */,
+ DoCodeMoveSREa /* kIKindMoveSREa */,
+ DoCodeMoveEaSR /* kIKindMoveEaSR */,
+ DoCodeOrISR /* kIKindOrISR */,
+ DoCodeAndISR /* kIKindAndISR */,
+ DoCodeEorISR /* kIKindEorISR */,
+ DoCodeOrICCR /* kIKindOrICCR */,
+ DoCodeAndICCR /* kIKindAndICCR */,
+ DoCodeEorICCR /* kIKindEorICCR */,
+ DoCodeMOVEMApRW /* kIKindMOVEMApRW */,
+ DoCodeMOVEMRmMW /* kIKindMOVEMRmMW */,
+ DoCodeMOVEMrmW /* kIKindMOVEMrmW */,
+ DoCodeMOVEMrmL /* kIKindMOVEMrmL */,
+ DoCodeMOVEMmrW /* kIKindMOVEMmrW */,
+ DoCodeMOVEMmrL /* kIKindMOVEMmrL */,
+ DoCodeAbcd /* kIKindAbcd */,
+ DoCodeSbcd /* kIKindSbcd */,
+ DoCodeNbcd /* kIKindNbcd */,
+ DoCodeRte /* kIKindRte */,
+ DoCodeNop /* kIKindNop */,
+ DoCodeMoveP0 /* kIKindMoveP0 */,
+ DoCodeMoveP1 /* kIKindMoveP1 */,
+ DoCodeMoveP2 /* kIKindMoveP2 */,
+ DoCodeMoveP3 /* kIKindMoveP3 */,
+ op_illg /* kIKindIllegal */,
+ DoCodeChk /* kIKindChkW */,
+ DoCodeTrap /* kIKindTrap */,
+ DoCodeTrapV /* kIKindTrapV */,
+ DoCodeRtr /* kIKindRtr */,
+ DoCodeLink /* kIKindLink */,
+ DoCodeUnlk /* kIKindUnlk */,
+ DoCodeMoveRUSP /* kIKindMoveRUSP */,
+ DoCodeMoveUSPR /* kIKindMoveUSPR */,
+ DoCodeTas /* kIKindTas */,
+ DoCodeFdefault /* kIKindFdflt */,
+ DoCodeStop /* kIKindStop */,
+ DoCodeReset /* kIKindReset */,
+
+#if Use68020
+ DoCodeCallMorRtm /* kIKindCallMorRtm */,
+ DoCodeBraL /* kIKindBraL */,
+ DoCodeBccL /* kIKindBccL */,
+ DoCodeBsrL /* kIKindBsrL */,
+ DoCodeEXTBL /* kIKindEXTBL */,
+ DoCodeTRAPcc /* kIKindTRAPcc */,
+ DoCodeChk /* kIKindChkL */,
+ DoCodeBkpt /* kIKindBkpt */,
+ DoCodeDivL /* kIKindDivL */,
+ DoCodeMulL /* kIKindMulL */,
+ DoCodeRtd /* kIKindRtd */,
+ DoCodeMoveCCREa /* kIKindMoveCCREa */,
+ DoMoveFromControl /* kIKindMoveCEa */,
+ DoMoveToControl /* kIKindMoveEaC */,
+ DoCodeLinkL /* kIKindLinkL */,
+ DoCodePack /* kIKindPack */,
+ DoCodeUnpk /* kIKindUnpk */,
+ DoCHK2orCMP2 /* kIKindCHK2orCMP2 */,
+ DoCAS2 /* kIKindCAS2 */,
+ DoCAS /* kIKindCAS */,
+ DoMOVES /* kIKindMoveS */,
+ DoBitField /* kIKindBitField */,
+#endif
+#if EmMMU
+ DoCodeMMU /* kIKindMMU */,
+#endif
+#if EmFPU
+ DoCodeFPU_md60 /* kIKindFPUmd60 */,
+ DoCodeFPU_DBcc /* kIKindFPUDBcc */,
+ DoCodeFPU_Trapcc /* kIKindFPUTrapcc */,
+ DoCodeFPU_Scc /* kIKindFPUScc */,
+ DoCodeFPU_FBccW /* kIKindFPUFBccW */,
+ DoCodeFPU_FBccL /* kIKindFPUFBccL */,
+ DoCodeFPU_Save /* kIKindFPUSave */,
+ DoCodeFPU_Restore /* kIKindFPURestore */,
+ DoCodeFPU_dflt /* kIKindFPUdflt */,
+#endif
+
+ 0
+};
+
+#ifndef WantBreakPoint
+#define WantBreakPoint 0
+#endif
+
+#if WantBreakPoint
+
+#define BreakPointAddress 0xD198
+
+LOCALPROC BreakPointAction(void)
+{
+ dbglog_StartLine();
+ dbglog_writeCStr("breakpoint A0=");
+ dbglog_writeHex(m68k_areg(0));
+ dbglog_writeCStr(" A1=");
+ dbglog_writeHex(m68k_areg(1));
+ dbglog_writeReturn();
+}
+
+#endif
+
+LOCALINLINEPROC DecodeNextInstruction(func_pointer_t *d, ui4rr *Cycles,
+ DecOpYR *y)
+{
+ ui5r opcode;
+ DecOpR *p;
+ ui4rr MainClas;
+
+ opcode = nextiword();
+
+ p = &V_regs.disp_table[opcode];
+
+#if WantCloserCyc
+ V_regs.CurDecOp = p;
+#endif
+ MainClas = p->x.MainClas;
+ *Cycles = p->x.Cycles;
+ *y = p->y;
+#if WantDumpTable
+ DumpTable[MainClas] ++;
+#endif
+ *d = OpDispatch[MainClas];
+}
+
+LOCALINLINEPROC UnDecodeNextInstruction(ui4rr Cycles)
+{
+ V_MaxCyclesToGo += Cycles;
+
+ BackupPC();
+
+#if WantDumpTable
+ {
+ ui5r opcode = do_get_mem_word(V_pc_p);
+ DecOpR *p = &V_regs.disp_table[opcode];
+ ui4rr MainClas = p->x.MainClas;
+
+ DumpTable[MainClas] --;
+ }
+#endif
+}
+
+LOCALPROC m68k_go_MaxCycles(void)
+{
+ ui4rr Cycles;
+ DecOpYR y;
+ func_pointer_t d;
+
+ /*
+ Main loop of emulator.
+
+ Always execute at least one instruction,
+ even if V_regs.MaxInstructionsToGo == 0.
+ Needed for trace flag to work.
+ */
+
+ DecodeNextInstruction(&d, &Cycles, &y);
+
+ V_MaxCyclesToGo -= Cycles;
+
+ do {
+ V_regs.CurDecOpY = y;
+
+#if WantDisasm || WantBreakPoint
+ {
+ CPTR pc = m68k_getpc() - 2;
+#if WantDisasm
+ DisasmOneOrSave(pc);
+#endif
+#if WantBreakPoint
+ if (BreakPointAddress == pc) {
+ BreakPointAction();
+ }
+#endif
+ }
+#endif
+
+ d();
+
+ DecodeNextInstruction(&d, &Cycles, &y);
+
+ } while (((si5rr)(V_MaxCyclesToGo -= Cycles)) > 0);
+
+ /* abort instruction that have started to decode */
+
+ UnDecodeNextInstruction(Cycles);
+}
+
+FORWARDFUNC ui5r my_reg_call get_byte_ext(CPTR addr);
+
+LOCALFUNC ui5r my_reg_call get_byte(CPTR addr)
+{
+ ui3p m = (addr & V_regs.MATCrdB.usemask) + V_regs.MATCrdB.usebase;
+
+ if ((addr & V_regs.MATCrdB.cmpmask) == V_regs.MATCrdB.cmpvalu) {
+ return ui5r_FromSByte(*m);
+ } else {
+ return get_byte_ext(addr);
+ }
+}
+
+FORWARDPROC my_reg_call put_byte_ext(CPTR addr, ui5r b);
+
+LOCALPROC my_reg_call put_byte(CPTR addr, ui5r b)
+{
+ ui3p m = (addr & V_regs.MATCwrB.usemask) + V_regs.MATCwrB.usebase;
+ if ((addr & V_regs.MATCwrB.cmpmask) == V_regs.MATCwrB.cmpvalu) {
+ *m = b;
+ } else {
+ put_byte_ext(addr, b);
+ }
+}
+
+FORWARDFUNC ui5r my_reg_call get_word_ext(CPTR addr);
+
+LOCALFUNC ui5r my_reg_call get_word(CPTR addr)
+{
+ ui3p m = (addr & V_regs.MATCrdW.usemask) + V_regs.MATCrdW.usebase;
+ if ((addr & V_regs.MATCrdW.cmpmask) == V_regs.MATCrdW.cmpvalu) {
+ return ui5r_FromSWord(do_get_mem_word(m));
+ } else {
+ return get_word_ext(addr);
+ }
+}
+
+FORWARDPROC my_reg_call put_word_ext(CPTR addr, ui5r w);
+
+LOCALPROC my_reg_call put_word(CPTR addr, ui5r w)
+{
+ ui3p m = (addr & V_regs.MATCwrW.usemask) + V_regs.MATCwrW.usebase;
+ if ((addr & V_regs.MATCwrW.cmpmask) == V_regs.MATCwrW.cmpvalu) {
+ do_put_mem_word(m, w);
+ } else {
+ put_word_ext(addr, w);
+ }
+}
+
+FORWARDFUNC ui5r my_reg_call get_long_misaligned_ext(CPTR addr);
+
+LOCALFUNC ui5r my_reg_call get_long_misaligned(CPTR addr)
+{
+ CPTR addr2 = addr + 2;
+ ui3p m = (addr & V_regs.MATCrdW.usemask) + V_regs.MATCrdW.usebase;
+ ui3p m2 = (addr2 & V_regs.MATCrdW.usemask) + V_regs.MATCrdW.usebase;
+ if (((addr & V_regs.MATCrdW.cmpmask) == V_regs.MATCrdW.cmpvalu)
+ && ((addr2 & V_regs.MATCrdW.cmpmask) == V_regs.MATCrdW.cmpvalu))
+ {
+ ui5r hi = do_get_mem_word(m);
+ ui5r lo = do_get_mem_word(m2);
+ ui5r Data = ((hi << 16) & 0xFFFF0000)
+ | (lo & 0x0000FFFF);
+
+ return ui5r_FromSLong(Data);
+ } else {
+ return get_long_misaligned_ext(addr);
+ }
+}
+
+#if FasterAlignedL
+FORWARDFUNC ui5r my_reg_call get_long_ext(CPTR addr);
+#endif
+
+#if FasterAlignedL
+LOCALFUNC ui5r my_reg_call get_long(CPTR addr)
+{
+ if (0 == (addr & 0x03)) {
+ ui3p m = (addr & V_regs.MATCrdL.usemask)
+ + V_regs.MATCrdL.usebase;
+ if ((addr & V_regs.MATCrdL.cmpmask) == V_regs.MATCrdL.cmpvalu) {
+ return ui5r_FromSLong(do_get_mem_long(m));
+ } else {
+ return get_long_ext(addr);
+ }
+ } else {
+ return get_long_misaligned(addr);
+ }
+}
+#else
+#define get_long get_long_misaligned
+#endif
+
+FORWARDPROC my_reg_call put_long_misaligned_ext(CPTR addr, ui5r l);
+
+LOCALPROC my_reg_call put_long_misaligned(CPTR addr, ui5r l)
+{
+ CPTR addr2 = addr + 2;
+ ui3p m = (addr & V_regs.MATCwrW.usemask) + V_regs.MATCwrW.usebase;
+ ui3p m2 = (addr2 & V_regs.MATCwrW.usemask) + V_regs.MATCwrW.usebase;
+ if (((addr & V_regs.MATCwrW.cmpmask) == V_regs.MATCwrW.cmpvalu)
+ && ((addr2 & V_regs.MATCwrW.cmpmask) == V_regs.MATCwrW.cmpvalu))
+ {
+ do_put_mem_word(m, l >> 16);
+ do_put_mem_word(m2, l);
+ } else {
+ put_long_misaligned_ext(addr, l);
+ }
+}
+
+#if FasterAlignedL
+FORWARDPROC my_reg_call put_long_ext(CPTR addr, ui5r l);
+#endif
+
+#if FasterAlignedL
+LOCALPROC my_reg_call put_long(CPTR addr, ui5r l)
+{
+ if (0 == (addr & 0x03)) {
+ ui3p m = (addr & V_regs.MATCwrL.usemask)
+ + V_regs.MATCwrL.usebase;
+ if ((addr & V_regs.MATCwrL.cmpmask) == V_regs.MATCwrL.cmpvalu) {
+ do_put_mem_long(m, l);
+ } else {
+ put_long_ext(addr, l);
+ }
+ } else {
+ put_long_misaligned(addr, l);
+ }
+}
+#else
+#define put_long put_long_misaligned
+#endif
+
+LOCALFUNC ui5b my_reg_call get_disp_ea(ui5b base)
+{
+ ui4b dp = nextiword();
+ int regno = (dp >> 12) & 0x0F;
+ si5b regd = V_regs.regs[regno];
+ if ((dp & 0x0800) == 0) {
+ regd = (si5b)(si4b)regd;
+ }
+#if Use68020
+ regd <<= (dp >> 9) & 3;
+#if ExtraAbnormalReports
+ if (((dp >> 9) & 3) != 0) {
+ /* ReportAbnormal("Have scale in Extension Word"); */
+ /* apparently can happen in Sys 7.5.5 boot on 68000 */
+ }
+#endif
+ if (dp & 0x0100) {
+ if ((dp & 0x80) != 0) {
+ base = 0;
+ /* ReportAbnormal("Extension Word: suppress base"); */
+ /* used by Sys 7.5.5 boot */
+ }
+ if ((dp & 0x40) != 0) {
+ regd = 0;
+ /* ReportAbnormal("Extension Word: suppress regd"); */
+ /* used by Mac II boot */
+ }
+
+ switch ((dp >> 4) & 0x03) {
+ case 0:
+ /* reserved */
+ ReportAbnormalID(0x0101, "Extension Word: dp reserved");
+ break;
+ case 1:
+ /* no displacement */
+ /* ReportAbnormal("Extension Word: no displacement"); */
+ /* used by Sys 7.5.5 boot */
+ break;
+ case 2:
+ base += nextiSWord();
+ /*
+ ReportAbnormal("Extension Word: word displacement");
+ */
+ /* used by Sys 7.5.5 boot */
+ break;
+ case 3:
+ base += nextilong();
+ /*
+ ReportAbnormal("Extension Word: long displacement");
+ */
+ /* used by Mac II boot from system 6.0.8? */
+ break;
+ }
+
+ if ((dp & 0x03) == 0) {
+ base += regd;
+ if ((dp & 0x04) != 0) {
+ ReportAbnormalID(0x0102,
+ "Extension Word: reserved dp form");
+ }
+ /* ReportAbnormal("Extension Word: noindex"); */
+ /* used by Sys 7.5.5 boot */
+ } else {
+ if ((dp & 0x04) != 0) {
+ base = get_long(base);
+ base += regd;
+ /* ReportAbnormal("Extension Word: postindex"); */
+ /* used by Sys 7.5.5 boot */
+ } else {
+ base += regd;
+ base = get_long(base);
+ /* ReportAbnormal("Extension Word: preindex"); */
+ /* used by Sys 7.5.5 boot */
+ }
+ switch (dp & 0x03) {
+ case 1:
+ /* null outer displacement */
+ /*
+ ReportAbnormal(
+ "Extension Word: null outer displacement");
+ */
+ /* used by Sys 7.5.5 boot */
+ break;
+ case 2:
+ base += nextiSWord();
+ /*
+ ReportAbnormal(
+ "Extension Word: word outer displacement");
+ */
+ /* used by Mac II boot from system 6.0.8? */
+ break;
+ case 3:
+ base += nextilong();
+ /*
+ ReportAbnormal(
+ "Extension Word: long outer displacement");
+ */
+ /* used by Mac II boot from system 6.0.8? */
+ break;
+ }
+ }
+
+ return base;
+ } else
+#endif
+ {
+ return base + (si3b)(dp) + regd;
+ }
+}
+
+LOCALFUNC ui5r my_reg_call DecodeAddr_Indirect(ui3rr ArgDat)
+{
+ return V_regs.regs[ArgDat];
+}
+
+LOCALFUNC ui5r my_reg_call DecodeAddr_APosIncB(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 1;
+
+ return a;
+}
+
+LOCALFUNC ui5r my_reg_call DecodeAddr_APosIncW(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 2;
+
+ return a;
+}
+
+LOCALFUNC ui5r my_reg_call DecodeAddr_APosIncL(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 4;
+
+ return a;
+}
+
+LOCALFUNC ui5r my_reg_call DecodeAddr_APreDecB(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 1;
+
+ *p = a;
+
+ return a;
+}
+
+LOCALFUNC ui5r my_reg_call DecodeAddr_APreDecW(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 2;
+
+ *p = a;
+
+ return a;
+}
+
+LOCALFUNC ui5r my_reg_call DecodeAddr_APreDecL(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 4;
+
+ *p = a;
+
+ return a;
+}
+
+LOCALFUNC ui5r my_reg_call DecodeAddr_ADisp(ui3rr ArgDat)
+{
+ return V_regs.regs[ArgDat] + nextiSWord();
+}
+
+LOCALFUNC ui5r my_reg_call DecodeAddr_AIndex(ui3rr ArgDat)
+{
+ return get_disp_ea(V_regs.regs[ArgDat]);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeAddr_AbsW(ui3rr ArgDat)
+{
+ UnusedParam(ArgDat);
+ return nextiSWord();
+}
+
+LOCALFUNC ui5r my_reg_call DecodeAddr_AbsL(ui3rr ArgDat)
+{
+ UnusedParam(ArgDat);
+ return nextilong();
+}
+
+LOCALFUNC ui5r my_reg_call DecodeAddr_PCDisp(ui3rr ArgDat)
+{
+ CPTR pc = m68k_getpc();
+
+ UnusedParam(ArgDat);
+ return pc + nextiSWord();
+}
+
+LOCALFUNC ui5r my_reg_call DecodeAddr_PCIndex(ui3rr ArgDat)
+{
+ UnusedParam(ArgDat);
+ return get_disp_ea(m68k_getpc());
+}
+
+typedef ui5r (my_reg_call *DecodeAddrP)(ui3rr ArgDat);
+
+LOCALVAR const DecodeAddrP DecodeAddrDispatch[kNumAMds] = {
+ (DecodeAddrP)nullpr /* kAMdRegB */,
+ (DecodeAddrP)nullpr /* kAMdRegW */,
+ (DecodeAddrP)nullpr /* kAMdRegL */,
+ DecodeAddr_Indirect /* kAMdIndirectB */,
+ DecodeAddr_Indirect /* kAMdIndirectW */,
+ DecodeAddr_Indirect /* kAMdIndirectL */,
+ DecodeAddr_APosIncB /* kAMdAPosIncB */,
+ DecodeAddr_APosIncW /* kAMdAPosIncW */,
+ DecodeAddr_APosIncL /* kAMdAPosIncL */,
+ DecodeAddr_APosIncW /* kAMdAPosInc7B */,
+ DecodeAddr_APreDecB /* kAMdAPreDecB */,
+ DecodeAddr_APreDecW /* kAMdAPreDecW */,
+ DecodeAddr_APreDecL /* kAMdAPreDecL */,
+ DecodeAddr_APreDecW /* kAMdAPreDec7B */,
+ DecodeAddr_ADisp /* kAMdADispB */,
+ DecodeAddr_ADisp /* kAMdADispW */,
+ DecodeAddr_ADisp /* kAMdADispL */,
+ DecodeAddr_AIndex /* kAMdAIndexB */,
+ DecodeAddr_AIndex /* kAMdAIndexW */,
+ DecodeAddr_AIndex /* kAMdAIndexL */,
+ DecodeAddr_AbsW /* kAMdAbsWB */,
+ DecodeAddr_AbsW /* kAMdAbsWW */,
+ DecodeAddr_AbsW /* kAMdAbsWL */,
+ DecodeAddr_AbsL /* kAMdAbsLB */,
+ DecodeAddr_AbsL /* kAMdAbsLW */,
+ DecodeAddr_AbsL /* kAMdAbsLL */,
+ DecodeAddr_PCDisp /* kAMdPCDispB */,
+ DecodeAddr_PCDisp /* kAMdPCDispW */,
+ DecodeAddr_PCDisp /* kAMdPCDispL */,
+ DecodeAddr_PCIndex /* kAMdPCIndexB */,
+ DecodeAddr_PCIndex /* kAMdPCIndexW */,
+ DecodeAddr_PCIndex /* kAMdPCIndexL */,
+ (DecodeAddrP)nullpr /* kAMdImmedB */,
+ (DecodeAddrP)nullpr /* kAMdImmedW */,
+ (DecodeAddrP)nullpr /* kAMdImmedL */,
+ (DecodeAddrP)nullpr /* kAMdDat4 */
+};
+
+LOCALINLINEFUNC ui5r DecodeAddrSrcDst(DecArgR *f)
+{
+ return (DecodeAddrDispatch[f->AMd])(f->ArgDat);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_RegB(ui3rr ArgDat)
+{
+ return ui5r_FromSByte(V_regs.regs[ArgDat]);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_RegW(ui3rr ArgDat)
+{
+ return ui5r_FromSWord(V_regs.regs[ArgDat]);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_RegL(ui3rr ArgDat)
+{
+ return ui5r_FromSLong(V_regs.regs[ArgDat]);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_IndirectB(ui3rr ArgDat)
+{
+ return get_byte(V_regs.regs[ArgDat]);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_IndirectW(ui3rr ArgDat)
+{
+ return get_word(V_regs.regs[ArgDat]);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_IndirectL(ui3rr ArgDat)
+{
+ return get_long(V_regs.regs[ArgDat]);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APosIncB(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 1;
+
+ return get_byte(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APosIncW(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 2;
+
+ return get_word(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APosIncL(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 4;
+
+ return get_long(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APosInc7B(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 2;
+
+ return get_byte(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APreDecB(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 1;
+
+ *p = a;
+
+ return get_byte(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APreDecW(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 2;
+
+ *p = a;
+
+ return get_word(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APreDecL(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 4;
+
+ *p = a;
+
+ return get_long(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_APreDec7B(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 2;
+
+ *p = a;
+
+ return get_byte(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_ADispB(ui3rr ArgDat)
+{
+ return get_byte(DecodeAddr_ADisp(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_ADispW(ui3rr ArgDat)
+{
+ return get_word(DecodeAddr_ADisp(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_ADispL(ui3rr ArgDat)
+{
+ return get_long(DecodeAddr_ADisp(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AIndexB(ui3rr ArgDat)
+{
+ return get_byte(get_disp_ea(V_regs.regs[ArgDat]));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AIndexW(ui3rr ArgDat)
+{
+ return get_word(get_disp_ea(V_regs.regs[ArgDat]));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AIndexL(ui3rr ArgDat)
+{
+ return get_long(get_disp_ea(V_regs.regs[ArgDat]));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AbsWB(ui3rr ArgDat)
+{
+ return get_byte(DecodeAddr_AbsW(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AbsWW(ui3rr ArgDat)
+{
+ return get_word(DecodeAddr_AbsW(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AbsWL(ui3rr ArgDat)
+{
+ return get_long(DecodeAddr_AbsW(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AbsLB(ui3rr ArgDat)
+{
+ return get_byte(DecodeAddr_AbsL(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AbsLW(ui3rr ArgDat)
+{
+ return get_word(DecodeAddr_AbsL(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_AbsLL(ui3rr ArgDat)
+{
+ return get_long(DecodeAddr_AbsL(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_PCDispB(ui3rr ArgDat)
+{
+ return get_byte(DecodeAddr_PCDisp(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_PCDispW(ui3rr ArgDat)
+{
+ return get_word(DecodeAddr_PCDisp(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_PCDispL(ui3rr ArgDat)
+{
+ return get_long(DecodeAddr_PCDisp(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_PCIndexB(ui3rr ArgDat)
+{
+ return get_byte(DecodeAddr_PCIndex(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_PCIndexW(ui3rr ArgDat)
+{
+ return get_word(DecodeAddr_PCIndex(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_PCIndexL(ui3rr ArgDat)
+{
+ return get_long(DecodeAddr_PCIndex(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_ImmedB(ui3rr ArgDat)
+{
+ UnusedParam(ArgDat);
+ return nextiSByte();
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_ImmedW(ui3rr ArgDat)
+{
+ UnusedParam(ArgDat);
+ return nextiSWord();
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_ImmedL(ui3rr ArgDat)
+{
+ UnusedParam(ArgDat);
+ return ui5r_FromSLong(nextilong());
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSrcDst_Dat4(ui3rr ArgDat)
+{
+ return ArgDat;
+}
+
+typedef ui5r (my_reg_call *DecodeGetSrcDstP)(ui3rr ArgDat);
+
+LOCALVAR const DecodeGetSrcDstP DecodeGetSrcDstDispatch[kNumAMds] = {
+ DecodeGetSrcDst_RegB /* kAMdRegB */,
+ DecodeGetSrcDst_RegW /* kAMdRegW */,
+ DecodeGetSrcDst_RegL /* kAMdRegL */,
+ DecodeGetSrcDst_IndirectB /* kAMdIndirectB */,
+ DecodeGetSrcDst_IndirectW /* kAMdIndirectW */,
+ DecodeGetSrcDst_IndirectL /* kAMdIndirectL */,
+ DecodeGetSrcDst_APosIncB /* kAMdAPosIncB */,
+ DecodeGetSrcDst_APosIncW /* kAMdAPosIncW */,
+ DecodeGetSrcDst_APosIncL /* kAMdAPosIncL */,
+ DecodeGetSrcDst_APosInc7B /* kAMdAPosInc7B */,
+ DecodeGetSrcDst_APreDecB /* kAMdAPreDecB */,
+ DecodeGetSrcDst_APreDecW /* kAMdAPreDecW */,
+ DecodeGetSrcDst_APreDecL /* kAMdAPreDecL */,
+ DecodeGetSrcDst_APreDec7B /* kAMdAPreDec7B */,
+ DecodeGetSrcDst_ADispB /* kAMdADispB */,
+ DecodeGetSrcDst_ADispW /* kAMdADispW */,
+ DecodeGetSrcDst_ADispL /* kAMdADispL */,
+ DecodeGetSrcDst_AIndexB /* kAMdAIndexB */,
+ DecodeGetSrcDst_AIndexW /* kAMdAIndexW */,
+ DecodeGetSrcDst_AIndexL /* kAMdAIndexL */,
+ DecodeGetSrcDst_AbsWB /* kAMdAbsWB */,
+ DecodeGetSrcDst_AbsWW /* kAMdAbsWW */,
+ DecodeGetSrcDst_AbsWL /* kAMdAbsWL */,
+ DecodeGetSrcDst_AbsLB /* kAMdAbsLB */,
+ DecodeGetSrcDst_AbsLW /* kAMdAbsLW */,
+ DecodeGetSrcDst_AbsLL /* kAMdAbsLL */,
+ DecodeGetSrcDst_PCDispB /* kAMdPCDispB */,
+ DecodeGetSrcDst_PCDispW /* kAMdPCDispW */,
+ DecodeGetSrcDst_PCDispL /* kAMdPCDispL */,
+ DecodeGetSrcDst_PCIndexB /* kAMdPCIndexB */,
+ DecodeGetSrcDst_PCIndexW /* kAMdPCIndexW */,
+ DecodeGetSrcDst_PCIndexL /* kAMdPCIndexL */,
+ DecodeGetSrcDst_ImmedB /* kAMdImmedB */,
+ DecodeGetSrcDst_ImmedW /* kAMdImmedW */,
+ DecodeGetSrcDst_ImmedL /* kAMdImmedL */,
+ DecodeGetSrcDst_Dat4 /* kAMdDat4 */
+};
+
+LOCALINLINEFUNC ui5r DecodeGetSrcDst(DecArgR *f)
+{
+ return (DecodeGetSrcDstDispatch[f->AMd])(f->ArgDat);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_RegB(ui5r v, ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+
+#if LittleEndianUnaligned
+ *(ui3b *)p = v;
+#else
+ *p = (*p & ~ 0xff) | ((v) & 0xff);
+#endif
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_RegW(ui5r v, ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+
+#if LittleEndianUnaligned
+ *(ui4b *)p = v;
+#else
+ *p = (*p & ~ 0xffff) | ((v) & 0xffff);
+#endif
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_RegL(ui5r v, ui3rr ArgDat)
+{
+ V_regs.regs[ArgDat] = v;
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_IndirectB(ui5r v, ui3rr ArgDat)
+{
+ put_byte(V_regs.regs[ArgDat], v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_IndirectW(ui5r v, ui3rr ArgDat)
+{
+ put_word(V_regs.regs[ArgDat], v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_IndirectL(ui5r v, ui3rr ArgDat)
+{
+ put_long(V_regs.regs[ArgDat], v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_APosIncB(ui5r v, ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 1;
+
+ put_byte(a, v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_APosIncW(ui5r v, ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 2;
+
+ put_word(a, v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_APosIncL(ui5r v, ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 4;
+
+ put_long(a, v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_APosInc7B(ui5r v, ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 2;
+
+ put_byte(a, v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_APreDecB(ui5r v, ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 1;
+
+ *p = a;
+
+ put_byte(a, v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_APreDecW(ui5r v, ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 2;
+
+ *p = a;
+
+ put_word(a, v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_APreDecL(ui5r v, ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 4;
+
+ *p = a;
+
+ put_long(a, v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_APreDec7B(ui5r v, ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 2;
+
+ *p = a;
+
+ put_byte(a, v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_ADispB(ui5r v, ui3rr ArgDat)
+{
+ put_byte(V_regs.regs[ArgDat]
+ + nextiSWord(), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_ADispW(ui5r v, ui3rr ArgDat)
+{
+ put_word(V_regs.regs[ArgDat]
+ + nextiSWord(), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_ADispL(ui5r v, ui3rr ArgDat)
+{
+ put_long(V_regs.regs[ArgDat]
+ + nextiSWord(), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_AIndexB(ui5r v, ui3rr ArgDat)
+{
+ put_byte(get_disp_ea(V_regs.regs[ArgDat]), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_AIndexW(ui5r v, ui3rr ArgDat)
+{
+ put_word(get_disp_ea(V_regs.regs[ArgDat]), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_AIndexL(ui5r v, ui3rr ArgDat)
+{
+ put_long(get_disp_ea(V_regs.regs[ArgDat]), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_AbsWB(ui5r v, ui3rr ArgDat)
+{
+ put_byte(DecodeAddr_AbsW(ArgDat), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_AbsWW(ui5r v, ui3rr ArgDat)
+{
+ put_word(DecodeAddr_AbsW(ArgDat), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_AbsWL(ui5r v, ui3rr ArgDat)
+{
+ put_long(DecodeAddr_AbsW(ArgDat), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_AbsLB(ui5r v, ui3rr ArgDat)
+{
+ put_byte(DecodeAddr_AbsL(ArgDat), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_AbsLW(ui5r v, ui3rr ArgDat)
+{
+ put_word(DecodeAddr_AbsL(ArgDat), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_AbsLL(ui5r v, ui3rr ArgDat)
+{
+ put_long(DecodeAddr_AbsL(ArgDat), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_PCDispB(ui5r v, ui3rr ArgDat)
+{
+ put_byte(DecodeAddr_PCDisp(ArgDat), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_PCDispW(ui5r v, ui3rr ArgDat)
+{
+ put_word(DecodeAddr_PCDisp(ArgDat), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_PCDispL(ui5r v, ui3rr ArgDat)
+{
+ put_long(DecodeAddr_PCDisp(ArgDat), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_PCIndexB(ui5r v, ui3rr ArgDat)
+{
+ put_byte(DecodeAddr_PCIndex(ArgDat), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_PCIndexW(ui5r v, ui3rr ArgDat)
+{
+ put_word(DecodeAddr_PCIndex(ArgDat), v);
+}
+
+LOCALPROC my_reg_call DecodeSetSrcDst_PCIndexL(ui5r v, ui3rr ArgDat)
+{
+ put_long(DecodeAddr_PCIndex(ArgDat), v);
+}
+
+typedef void (my_reg_call *DecodeSetSrcDstP)(ui5r v, ui3rr ArgDat);
+
+LOCALVAR const DecodeSetSrcDstP DecodeSetSrcDstDispatch[kNumAMds] = {
+ DecodeSetSrcDst_RegB /* kAMdRegB */,
+ DecodeSetSrcDst_RegW /* kAMdRegW */,
+ DecodeSetSrcDst_RegL /* kAMdRegL */,
+ DecodeSetSrcDst_IndirectB /* kAMdIndirectB */,
+ DecodeSetSrcDst_IndirectW /* kAMdIndirectW */,
+ DecodeSetSrcDst_IndirectL /* kAMdIndirectL*/,
+ DecodeSetSrcDst_APosIncB /* kAMdAPosIncB */,
+ DecodeSetSrcDst_APosIncW /* kAMdAPosIncW */,
+ DecodeSetSrcDst_APosIncL /* kAMdAPosIncL */,
+ DecodeSetSrcDst_APosInc7B /* kAMdAPosInc7B */,
+ DecodeSetSrcDst_APreDecB /* kAMdAPreDecB */,
+ DecodeSetSrcDst_APreDecW /* kAMdAPreDecW */,
+ DecodeSetSrcDst_APreDecL /* kAMdAPreDecL */,
+ DecodeSetSrcDst_APreDec7B /* kAMdAPreDec7B */,
+ DecodeSetSrcDst_ADispB /* kAMdADispB */,
+ DecodeSetSrcDst_ADispW /* kAMdADispW */,
+ DecodeSetSrcDst_ADispL /* kAMdADispL */,
+ DecodeSetSrcDst_AIndexB /* kAMdAIndexB */,
+ DecodeSetSrcDst_AIndexW /* kAMdAIndexW */,
+ DecodeSetSrcDst_AIndexL /* kAMdAIndexL */,
+ DecodeSetSrcDst_AbsWB /* kAMdAbsWB */,
+ DecodeSetSrcDst_AbsWW /* kAMdAbsWW */,
+ DecodeSetSrcDst_AbsWL /* kAMdAbsWL */,
+ DecodeSetSrcDst_AbsLB /* kAMdAbsLB */,
+ DecodeSetSrcDst_AbsLW /* kAMdAbsLW */,
+ DecodeSetSrcDst_AbsLL /* kAMdAbsLL */,
+ DecodeSetSrcDst_PCDispB /* kAMdPCDispB */,
+ DecodeSetSrcDst_PCDispW /* kAMdPCDispW */,
+ DecodeSetSrcDst_PCDispL /* kAMdPCDispL */,
+ DecodeSetSrcDst_PCIndexB /* kAMdPCIndexB */,
+ DecodeSetSrcDst_PCIndexW /* kAMdPCIndexW */,
+ DecodeSetSrcDst_PCIndexL /* kAMdPCIndexL */,
+ (DecodeSetSrcDstP)nullpr /* kAMdImmedB */,
+ (DecodeSetSrcDstP)nullpr /* kAMdImmedW */,
+ (DecodeSetSrcDstP)nullpr /* kAMdImmedL */,
+ (DecodeSetSrcDstP)nullpr /* kAMdDat4 */
+};
+
+LOCALINLINEPROC DecodeSetSrcDst(ui5r v, DecArgR *f)
+{
+ (DecodeSetSrcDstDispatch[f->AMd])(v, f->ArgDat);
+}
+
+LOCALPROC my_reg_call ArgSetDstRegBValue(ui5r v)
+{
+ ui5r *p = V_regs.ArgAddr.rga;
+
+#if LittleEndianUnaligned
+ *(ui3b *)p = v;
+#else
+ *p = (*p & ~ 0xff) | ((v) & 0xff);
+#endif
+}
+
+LOCALPROC my_reg_call ArgSetDstRegWValue(ui5r v)
+{
+ ui5r *p = V_regs.ArgAddr.rga;
+
+#if LittleEndianUnaligned
+ *(ui4b *)p = v;
+#else
+ *p = (*p & ~ 0xffff) | ((v) & 0xffff);
+#endif
+}
+
+LOCALPROC my_reg_call ArgSetDstRegLValue(ui5r v)
+{
+ ui5r *p = V_regs.ArgAddr.rga;
+
+ *p = v;
+}
+
+LOCALPROC my_reg_call ArgSetDstMemBValue(ui5r v)
+{
+ put_byte(V_regs.ArgAddr.mem, v);
+}
+
+LOCALPROC my_reg_call ArgSetDstMemWValue(ui5r v)
+{
+ put_word(V_regs.ArgAddr.mem, v);
+}
+
+LOCALPROC my_reg_call ArgSetDstMemLValue(ui5r v)
+{
+ put_long(V_regs.ArgAddr.mem, v);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_RegB(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+
+ V_regs.ArgAddr.rga = p;
+ V_regs.ArgSetDst = ArgSetDstRegBValue;
+
+ return ui5r_FromSByte(*p);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_RegW(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+
+ V_regs.ArgAddr.rga = p;
+ V_regs.ArgSetDst = ArgSetDstRegWValue;
+
+ return ui5r_FromSWord(*p);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_RegL(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+
+ V_regs.ArgAddr.rga = p;
+ V_regs.ArgSetDst = ArgSetDstRegLValue;
+
+ return ui5r_FromSLong(*p);
+}
+
+LOCALFUNC ui5r my_reg_call getarg_byte(ui5r a)
+{
+ V_regs.ArgAddr.mem = a;
+ V_regs.ArgSetDst = ArgSetDstMemBValue;
+
+ return get_byte(a);
+}
+
+LOCALFUNC ui5r my_reg_call getarg_word(ui5r a)
+{
+ V_regs.ArgAddr.mem = a;
+ V_regs.ArgSetDst = ArgSetDstMemWValue;
+
+ return get_word(a);
+}
+
+LOCALFUNC ui5r my_reg_call getarg_long(ui5r a)
+{
+ V_regs.ArgAddr.mem = a;
+ V_regs.ArgSetDst = ArgSetDstMemLValue;
+
+ return get_long(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_IndirectB(ui3rr ArgDat)
+{
+ return getarg_byte(V_regs.regs[ArgDat]);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_IndirectW(ui3rr ArgDat)
+{
+ return getarg_word(V_regs.regs[ArgDat]);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_IndirectL(ui3rr ArgDat)
+{
+ return getarg_long(V_regs.regs[ArgDat]);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APosIncB(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 1;
+
+ return getarg_byte(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APosIncW(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 2;
+
+ return getarg_word(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APosIncL(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 4;
+
+ return getarg_long(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APosInc7B(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p;
+
+ *p = a + 2;
+
+ return getarg_byte(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APreDecB(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 1;
+
+ *p = a;
+
+ return getarg_byte(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APreDecW(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 2;
+
+ *p = a;
+
+ return getarg_word(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APreDecL(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 4;
+
+ *p = a;
+
+ return getarg_long(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_APreDec7B(ui3rr ArgDat)
+{
+ ui5r *p = &V_regs.regs[ArgDat];
+ ui5r a = *p - 2;
+
+ *p = a;
+
+ return getarg_byte(a);
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_ADispB(ui3rr ArgDat)
+{
+ return getarg_byte(V_regs.regs[ArgDat]
+ + nextiSWord());
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_ADispW(ui3rr ArgDat)
+{
+ return getarg_word(V_regs.regs[ArgDat]
+ + nextiSWord());
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_ADispL(ui3rr ArgDat)
+{
+ return getarg_long(V_regs.regs[ArgDat]
+ + nextiSWord());
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AIndexB(ui3rr ArgDat)
+{
+ return getarg_byte(get_disp_ea(V_regs.regs[ArgDat]));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AIndexW(ui3rr ArgDat)
+{
+ return getarg_word(get_disp_ea(V_regs.regs[ArgDat]));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AIndexL(ui3rr ArgDat)
+{
+ return getarg_long(get_disp_ea(V_regs.regs[ArgDat]));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AbsWB(ui3rr ArgDat)
+{
+ return getarg_byte(DecodeAddr_AbsW(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AbsWW(ui3rr ArgDat)
+{
+ return getarg_word(DecodeAddr_AbsW(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AbsWL(ui3rr ArgDat)
+{
+ return getarg_long(DecodeAddr_AbsW(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AbsLB(ui3rr ArgDat)
+{
+ return getarg_byte(DecodeAddr_AbsL(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AbsLW(ui3rr ArgDat)
+{
+ return getarg_word(DecodeAddr_AbsL(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_AbsLL(ui3rr ArgDat)
+{
+ return getarg_long(DecodeAddr_AbsL(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_PCDispB(ui3rr ArgDat)
+{
+ return getarg_byte(DecodeAddr_PCDisp(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_PCDispW(ui3rr ArgDat)
+{
+ return getarg_word(DecodeAddr_PCDisp(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_PCDispL(ui3rr ArgDat)
+{
+ return getarg_long(DecodeAddr_PCDisp(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_PCIndexB(ui3rr ArgDat)
+{
+ return getarg_byte(DecodeAddr_PCIndex(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_PCIndexW(ui3rr ArgDat)
+{
+ return getarg_word(DecodeAddr_PCIndex(ArgDat));
+}
+
+LOCALFUNC ui5r my_reg_call DecodeGetSetSrcDst_PCIndexL(ui3rr ArgDat)
+{
+ return getarg_long(DecodeAddr_PCIndex(ArgDat));
+}
+
+typedef ui5r (my_reg_call *DecodeGetSetSrcDstP)(ui3rr ArgDat);
+
+LOCALVAR const DecodeGetSetSrcDstP
+ DecodeGetSetSrcDstDispatch[kNumAMds] =
+{
+ DecodeGetSetSrcDst_RegB /* kAMdRegB */,
+ DecodeGetSetSrcDst_RegW /* kAMdRegW */,
+ DecodeGetSetSrcDst_RegL /* kAMdRegL */,
+ DecodeGetSetSrcDst_IndirectB /* kAMdIndirectB */,
+ DecodeGetSetSrcDst_IndirectW /* kAMdIndirectW */,
+ DecodeGetSetSrcDst_IndirectL /* kAMdIndirectL*/,
+ DecodeGetSetSrcDst_APosIncB /* kAMdAPosIncB */,
+ DecodeGetSetSrcDst_APosIncW /* kAMdAPosIncW */,
+ DecodeGetSetSrcDst_APosIncL /* kAMdAPosIncL */,
+ DecodeGetSetSrcDst_APosInc7B /* kAMdAPosInc7B */,
+ DecodeGetSetSrcDst_APreDecB /* kAMdAPreDecB */,
+ DecodeGetSetSrcDst_APreDecW /* kAMdAPreDecW */,
+ DecodeGetSetSrcDst_APreDecL /* kAMdAPreDecL */,
+ DecodeGetSetSrcDst_APreDec7B /* kAMdAPreDec7B */,
+ DecodeGetSetSrcDst_ADispB /* kAMdADispB */,
+ DecodeGetSetSrcDst_ADispW /* kAMdADispW */,
+ DecodeGetSetSrcDst_ADispL /* kAMdADispL */,
+ DecodeGetSetSrcDst_AIndexB /* kAMdAIndexB */,
+ DecodeGetSetSrcDst_AIndexW /* kAMdAIndexW */,
+ DecodeGetSetSrcDst_AIndexL /* kAMdAIndexL */,
+ DecodeGetSetSrcDst_AbsWB /* kAMdAbsWB */,
+ DecodeGetSetSrcDst_AbsWW /* kAMdAbsWW */,
+ DecodeGetSetSrcDst_AbsWL /* kAMdAbsWL */,
+ DecodeGetSetSrcDst_AbsLB /* kAMdAbsLB */,
+ DecodeGetSetSrcDst_AbsLW /* kAMdAbsLW */,
+ DecodeGetSetSrcDst_AbsLL /* kAMdAbsLL */,
+ DecodeGetSetSrcDst_PCDispB /* kAMdPCDispB */,
+ DecodeGetSetSrcDst_PCDispW /* kAMdPCDispW */,
+ DecodeGetSetSrcDst_PCDispL /* kAMdPCDispL */,
+ DecodeGetSetSrcDst_PCIndexB /* kAMdPCIndexB */,
+ DecodeGetSetSrcDst_PCIndexW /* kAMdPCIndexW */,
+ DecodeGetSetSrcDst_PCIndexL /* kAMdPCIndexL */,
+ (DecodeGetSetSrcDstP)nullpr /* kAMdImmedB */,
+ (DecodeGetSetSrcDstP)nullpr /* kAMdImmedW */,
+ (DecodeGetSetSrcDstP)nullpr /* kAMdImmedL */,
+ (DecodeGetSetSrcDstP)nullpr /* kAMdDat4 */
+};
+
+LOCALINLINEFUNC ui5r DecodeGetSetSrcDst(DecArgR *f)
+{
+ return (DecodeGetSetSrcDstDispatch[f->AMd])(f->ArgDat);
+}
+
+
+LOCALINLINEFUNC ui5r DecodeDst(void)
+{
+ return DecodeAddrSrcDst(&V_regs.CurDecOpY.v[1]);
+}
+
+LOCALINLINEFUNC ui5r DecodeGetSetDstValue(void)
+{
+ return DecodeGetSetSrcDst(&V_regs.CurDecOpY.v[1]);
+}
+
+LOCALINLINEPROC ArgSetDstValue(ui5r v)
+{
+ V_regs.ArgSetDst(v);
+}
+
+LOCALINLINEPROC DecodeSetDstValue(ui5r v)
+{
+ DecodeSetSrcDst(v, &V_regs.CurDecOpY.v[1]);
+}
+
+LOCALINLINEFUNC ui5r DecodeGetSrcValue(void)
+{
+ return DecodeGetSrcDst(&V_regs.CurDecOpY.v[0]);
+}
+
+LOCALINLINEFUNC ui5r DecodeGetDstValue(void)
+{
+ return DecodeGetSrcDst(&V_regs.CurDecOpY.v[1]);
+}
+
+LOCALINLINEFUNC ui5r DecodeGetSrcSetDstValue(void)
+{
+ V_regs.SrcVal = DecodeGetSrcValue();
+
+ return DecodeGetSetDstValue();
+}
+
+LOCALINLINEFUNC ui5r DecodeGetSrcGetDstValue(void)
+{
+ V_regs.SrcVal = DecodeGetSrcValue();
+
+ return DecodeGetDstValue();
+}
+
+
+typedef void (*cond_actP)(void);
+
+LOCALPROC my_reg_call cctrue_T(cond_actP t_act, cond_actP f_act)
+{
+ UnusedParam(f_act);
+ t_act();
+}
+
+LOCALPROC my_reg_call cctrue_F(cond_actP t_act, cond_actP f_act)
+{
+ UnusedParam(t_act);
+ f_act();
+}
+
+LOCALPROC my_reg_call cctrue_HI(cond_actP t_act, cond_actP f_act)
+{
+ if (0 == (CFLG | ZFLG)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_LS(cond_actP t_act, cond_actP f_act)
+{
+ if (0 != (CFLG | ZFLG)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CC(cond_actP t_act, cond_actP f_act)
+{
+ if (0 == (CFLG)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CS(cond_actP t_act, cond_actP f_act)
+{
+ if (0 != (CFLG)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_NE(cond_actP t_act, cond_actP f_act)
+{
+ if (0 == (ZFLG)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_EQ(cond_actP t_act, cond_actP f_act)
+{
+ if (0 != (ZFLG)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_VC(cond_actP t_act, cond_actP f_act)
+{
+ if (0 == (VFLG)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_VS(cond_actP t_act, cond_actP f_act)
+{
+ if (0 != (VFLG)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_PL(cond_actP t_act, cond_actP f_act)
+{
+ if (0 == (NFLG)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_MI(cond_actP t_act, cond_actP f_act)
+{
+ if (0 != (NFLG)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_GE(cond_actP t_act, cond_actP f_act)
+{
+ if (0 == (NFLG ^ VFLG)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_LT(cond_actP t_act, cond_actP f_act)
+{
+ if (0 != (NFLG ^ VFLG)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_GT(cond_actP t_act, cond_actP f_act)
+{
+ if (0 == (ZFLG | (NFLG ^ VFLG))) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_LE(cond_actP t_act, cond_actP f_act)
+{
+ if (0 != (ZFLG | (NFLG ^ VFLG))) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+#if Have_ASR
+#define Ui5rASR(x, s) ((ui5r)(((si5r)(x)) >> (s)))
+#else
+LOCALFUNC ui5r Ui5rASR(ui5r x, ui5r s)
+{
+ ui5r v;
+
+ if (ui5r_MSBisSet(x)) {
+ v = ~ ((~ x) >> s);
+ } else {
+ v = x >> s;
+ }
+
+ return v;
+}
+#endif
+
+#if UseLazyCC
+
+LOCALPROC my_reg_call cctrue_TstL_HI(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui5b)V_regs.LazyFlagArgDst) > ((ui5b)0)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_TstL_LS(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui5b)V_regs.LazyFlagArgDst) <= ((ui5b)0)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+#if 0 /* always true */
+LOCALPROC my_reg_call cctrue_TstL_CC(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui5b)V_regs.LazyFlagArgDst) >= ((ui5b)0)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+#endif
+
+#if 0 /* always false */
+LOCALPROC my_reg_call cctrue_TstL_CS(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui5b)V_regs.LazyFlagArgDst) < ((ui5b)0)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+#endif
+
+LOCALPROC my_reg_call cctrue_TstL_NE(cond_actP t_act, cond_actP f_act)
+{
+ if (V_regs.LazyFlagArgDst != 0) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_TstL_EQ(cond_actP t_act, cond_actP f_act)
+{
+ if (V_regs.LazyFlagArgDst == 0) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_TstL_PL(cond_actP t_act, cond_actP f_act)
+{
+ if (((si5b)(V_regs.LazyFlagArgDst)) >= 0) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_TstL_MI(cond_actP t_act, cond_actP f_act)
+{
+ if (((si5b)(V_regs.LazyFlagArgDst)) < 0) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_TstL_GE(cond_actP t_act, cond_actP f_act)
+{
+ if (((si5b)V_regs.LazyFlagArgDst) >= ((si5b)0)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_TstL_LT(cond_actP t_act, cond_actP f_act)
+{
+ if (((si5b)V_regs.LazyFlagArgDst) < ((si5b)0)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_TstL_GT(cond_actP t_act, cond_actP f_act)
+{
+ if (((si5b)V_regs.LazyFlagArgDst) > ((si5b)0)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_TstL_LE(cond_actP t_act, cond_actP f_act)
+{
+ if (((si5b)V_regs.LazyFlagArgDst) <= ((si5b)0)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpB_HI(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui3b)V_regs.LazyFlagArgDst) > ((ui3b)V_regs.LazyFlagArgSrc)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpB_LS(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui3b)V_regs.LazyFlagArgDst) <= ((ui3b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpB_CC(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui3b)V_regs.LazyFlagArgDst) >= ((ui3b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpB_CS(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui3b)V_regs.LazyFlagArgDst) < ((ui3b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpB_NE(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui3b)V_regs.LazyFlagArgDst) != ((ui3b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpB_EQ(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui3b)V_regs.LazyFlagArgDst) == ((ui3b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpB_PL(cond_actP t_act, cond_actP f_act)
+{
+ if (((si3b)(V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc)) >= 0) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpB_MI(cond_actP t_act, cond_actP f_act)
+{
+ if (((si3b)(V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc)) < 0) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpB_GE(cond_actP t_act, cond_actP f_act)
+{
+ if (((si3b)V_regs.LazyFlagArgDst) >= ((si3b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpB_LT(cond_actP t_act, cond_actP f_act)
+{
+ if (((si3b)V_regs.LazyFlagArgDst) < ((si3b)V_regs.LazyFlagArgSrc)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpB_GT(cond_actP t_act, cond_actP f_act)
+{
+ if (((si3b)V_regs.LazyFlagArgDst) > ((si3b)V_regs.LazyFlagArgSrc)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpB_LE(cond_actP t_act, cond_actP f_act)
+{
+ if (((si3b)V_regs.LazyFlagArgDst) <= ((si3b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpW_HI(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui4b)V_regs.LazyFlagArgDst) > ((ui4b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpW_LS(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui4b)V_regs.LazyFlagArgDst) <= ((ui4b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpW_CC(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui4b)V_regs.LazyFlagArgDst) >= ((ui4b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpW_CS(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui4b)V_regs.LazyFlagArgDst) < ((ui4b)V_regs.LazyFlagArgSrc)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpW_NE(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui4b)V_regs.LazyFlagArgDst) != ((ui4b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpW_EQ(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui4b)V_regs.LazyFlagArgDst) == ((ui4b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpW_PL(cond_actP t_act, cond_actP f_act)
+{
+ if (((si4b)(V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc)) >= 0) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpW_MI(cond_actP t_act, cond_actP f_act)
+{
+ if (((si4b)(V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc)) < 0) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpW_GE(cond_actP t_act, cond_actP f_act)
+{
+ if (((si4b)V_regs.LazyFlagArgDst) >= ((si4b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpW_LT(cond_actP t_act, cond_actP f_act)
+{
+ if (((si4b)V_regs.LazyFlagArgDst) < ((si4b)V_regs.LazyFlagArgSrc)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpW_GT(cond_actP t_act, cond_actP f_act)
+{
+ if (((si4b)V_regs.LazyFlagArgDst) > ((si4b)V_regs.LazyFlagArgSrc)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpW_LE(cond_actP t_act, cond_actP f_act)
+{
+ if (((si4b)V_regs.LazyFlagArgDst) <= ((si4b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpL_HI(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui5b)V_regs.LazyFlagArgDst) > ((ui5b)V_regs.LazyFlagArgSrc)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpL_LS(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui5b)V_regs.LazyFlagArgDst) <= ((ui5b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpL_CC(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui5b)V_regs.LazyFlagArgDst) >= ((ui5b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpL_CS(cond_actP t_act, cond_actP f_act)
+{
+ if (((ui5b)V_regs.LazyFlagArgDst) < ((ui5b)V_regs.LazyFlagArgSrc)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpL_NE(cond_actP t_act, cond_actP f_act)
+{
+ if (V_regs.LazyFlagArgDst != V_regs.LazyFlagArgSrc) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpL_EQ(cond_actP t_act, cond_actP f_act)
+{
+ if (V_regs.LazyFlagArgDst == V_regs.LazyFlagArgSrc) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpL_PL(cond_actP t_act, cond_actP f_act)
+{
+ if ((((si5b)(V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc)) >= 0))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpL_MI(cond_actP t_act, cond_actP f_act)
+{
+ if ((((si5b)(V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc)) < 0)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpL_GE(cond_actP t_act, cond_actP f_act)
+{
+ if (((si5b)V_regs.LazyFlagArgDst) >= ((si5b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpL_LT(cond_actP t_act, cond_actP f_act)
+{
+ if (((si5b)V_regs.LazyFlagArgDst) < ((si5b)V_regs.LazyFlagArgSrc)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpL_GT(cond_actP t_act, cond_actP f_act)
+{
+ if (((si5b)V_regs.LazyFlagArgDst) > ((si5b)V_regs.LazyFlagArgSrc)) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_CmpL_LE(cond_actP t_act, cond_actP f_act)
+{
+ if (((si5b)V_regs.LazyFlagArgDst) <= ((si5b)V_regs.LazyFlagArgSrc))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_Asr_CC(cond_actP t_act, cond_actP f_act)
+{
+ if (0 ==
+ ((V_regs.LazyFlagArgDst >> (V_regs.LazyFlagArgSrc - 1)) & 1))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_Asr_CS(cond_actP t_act, cond_actP f_act)
+{
+ if (0 !=
+ ((V_regs.LazyFlagArgDst >> (V_regs.LazyFlagArgSrc - 1)) & 1))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_AslB_CC(cond_actP t_act, cond_actP f_act)
+{
+ if (0 ==
+ ((V_regs.LazyFlagArgDst >> (8 - V_regs.LazyFlagArgSrc)) & 1))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_AslB_CS(cond_actP t_act, cond_actP f_act)
+{
+ if (0 !=
+ ((V_regs.LazyFlagArgDst >> (8 - V_regs.LazyFlagArgSrc)) & 1))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_AslB_VC(cond_actP t_act, cond_actP f_act)
+{
+ ui5r cnt = V_regs.LazyFlagArgSrc;
+ ui5r dst = ui5r_FromSByte(V_regs.LazyFlagArgDst << cnt);
+
+ if (Ui5rASR(dst, cnt) == V_regs.LazyFlagArgDst) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_AslB_VS(cond_actP t_act, cond_actP f_act)
+{
+ ui5r cnt = V_regs.LazyFlagArgSrc;
+ ui5r dst = ui5r_FromSByte(V_regs.LazyFlagArgDst << cnt);
+
+ if (Ui5rASR(dst, cnt) != V_regs.LazyFlagArgDst) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_AslW_CC(cond_actP t_act, cond_actP f_act)
+{
+ if (0 ==
+ ((V_regs.LazyFlagArgDst >> (16 - V_regs.LazyFlagArgSrc)) & 1))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_AslW_CS(cond_actP t_act, cond_actP f_act)
+{
+ if (0 !=
+ ((V_regs.LazyFlagArgDst >> (16 - V_regs.LazyFlagArgSrc)) & 1))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_AslW_VC(cond_actP t_act, cond_actP f_act)
+{
+ ui5r cnt = V_regs.LazyFlagArgSrc;
+ ui5r dst = ui5r_FromSWord(V_regs.LazyFlagArgDst << cnt);
+
+ if (Ui5rASR(dst, cnt) == V_regs.LazyFlagArgDst) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_AslW_VS(cond_actP t_act, cond_actP f_act)
+{
+ ui5r cnt = V_regs.LazyFlagArgSrc;
+ ui5r dst = ui5r_FromSWord(V_regs.LazyFlagArgDst << cnt);
+
+ if (Ui5rASR(dst, cnt) != V_regs.LazyFlagArgDst) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_AslL_CC(cond_actP t_act, cond_actP f_act)
+{
+ if (0 ==
+ ((V_regs.LazyFlagArgDst >> (32 - V_regs.LazyFlagArgSrc)) & 1))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_AslL_CS(cond_actP t_act, cond_actP f_act)
+{
+ if (0 !=
+ ((V_regs.LazyFlagArgDst >> (32 - V_regs.LazyFlagArgSrc)) & 1))
+ {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_AslL_VC(cond_actP t_act, cond_actP f_act)
+{
+ ui5r cnt = V_regs.LazyFlagArgSrc;
+ ui5r dst = ui5r_FromSLong(V_regs.LazyFlagArgDst << cnt);
+
+ if (Ui5rASR(dst, cnt) == V_regs.LazyFlagArgDst) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+LOCALPROC my_reg_call cctrue_AslL_VS(cond_actP t_act, cond_actP f_act)
+{
+ ui5r cnt = V_regs.LazyFlagArgSrc;
+ ui5r dst = ui5r_FromSLong(V_regs.LazyFlagArgDst << cnt);
+
+ if (Ui5rASR(dst, cnt) != V_regs.LazyFlagArgDst) {
+ t_act();
+ } else {
+ f_act();
+ }
+}
+
+FORWARDPROC my_reg_call cctrue_Dflt(cond_actP t_act, cond_actP f_act);
+
+#endif /* UseLazyCC */
+
+#if UseLazyCC
+#define CCdispSz (16 * kNumLazyFlagsKinds)
+#else
+#define CCdispSz kNumLazyFlagsKinds
+#endif
+
+typedef void (my_reg_call *cctrueP)(cond_actP t_act, cond_actP f_act);
+
+LOCALVAR const cctrueP cctrueDispatch[CCdispSz + 1] = {
+ cctrue_T /* kLazyFlagsDefault T */,
+ cctrue_F /* kLazyFlagsDefault F */,
+ cctrue_HI /* kLazyFlagsDefault HI */,
+ cctrue_LS /* kLazyFlagsDefault LS */,
+ cctrue_CC /* kLazyFlagsDefault CC */,
+ cctrue_CS /* kLazyFlagsDefault CS */,
+ cctrue_NE /* kLazyFlagsDefault NE */,
+ cctrue_EQ /* kLazyFlagsDefault EQ */,
+ cctrue_VC /* kLazyFlagsDefault VC */,
+ cctrue_VS /* kLazyFlagsDefault VS */,
+ cctrue_PL /* kLazyFlagsDefault PL */,
+ cctrue_MI /* kLazyFlagsDefault MI */,
+ cctrue_GE /* kLazyFlagsDefault GE */,
+ cctrue_LT /* kLazyFlagsDefault LT */,
+ cctrue_GT /* kLazyFlagsDefault GT */,
+ cctrue_LE /* kLazyFlagsDefault LE */,
+
+#if UseLazyCC
+ cctrue_T /* kLazyFlagsTstB T */,
+ cctrue_F /* kLazyFlagsTstB F */,
+ cctrue_Dflt /* kLazyFlagsTstB HI */,
+ cctrue_Dflt /* kLazyFlagsTstB LS */,
+ cctrue_Dflt /* kLazyFlagsTstB CC */,
+ cctrue_Dflt /* kLazyFlagsTstB CS */,
+ cctrue_Dflt /* kLazyFlagsTstB NE */,
+ cctrue_Dflt /* kLazyFlagsTstB EQ */,
+ cctrue_Dflt /* kLazyFlagsTstB VC */,
+ cctrue_Dflt /* kLazyFlagsTstB VS */,
+ cctrue_Dflt /* kLazyFlagsTstB PL */,
+ cctrue_Dflt /* kLazyFlagsTstB MI */,
+ cctrue_Dflt /* kLazyFlagsTstB GE */,
+ cctrue_Dflt /* kLazyFlagsTstB LT */,
+ cctrue_Dflt /* kLazyFlagsTstB GT */,
+ cctrue_Dflt /* kLazyFlagsTstB LE */,
+
+ cctrue_T /* kLazyFlagsTstW T */,
+ cctrue_F /* kLazyFlagsTstW F */,
+ cctrue_Dflt /* kLazyFlagsTstW HI */,
+ cctrue_Dflt /* kLazyFlagsTstW LS */,
+ cctrue_Dflt /* kLazyFlagsTstW CC */,
+ cctrue_Dflt /* kLazyFlagsTstW CS */,
+ cctrue_Dflt /* kLazyFlagsTstW NE */,
+ cctrue_Dflt /* kLazyFlagsTstW EQ */,
+ cctrue_Dflt /* kLazyFlagsTstW VC */,
+ cctrue_Dflt /* kLazyFlagsTstW VS */,
+ cctrue_Dflt /* kLazyFlagsTstW PL */,
+ cctrue_Dflt /* kLazyFlagsTstW MI */,
+ cctrue_Dflt /* kLazyFlagsTstW GE */,
+ cctrue_Dflt /* kLazyFlagsTstW LT */,
+ cctrue_Dflt /* kLazyFlagsTstW GT */,
+ cctrue_Dflt /* kLazyFlagsTstW LE */,
+
+ cctrue_T /* kLazyFlagsTstL T */,
+ cctrue_F /* kLazyFlagsTstL F */,
+ cctrue_TstL_HI /* kLazyFlagsTstL HI */,
+ cctrue_TstL_LS /* kLazyFlagsTstL LS */,
+ cctrue_T /* cctrue_TstL_CC */ /* kLazyFlagsTstL CC */,
+ cctrue_F /* cctrue_TstL_CS */ /* kLazyFlagsTstL CS */,
+ cctrue_TstL_NE /* kLazyFlagsTstL NE */,
+ cctrue_TstL_EQ /* kLazyFlagsTstL EQ */,
+ cctrue_T /* cctrue_Dflt */ /* kLazyFlagsTstL VC */,
+ cctrue_F /* cctrue_Dflt */ /* kLazyFlagsTstL VS */,
+ cctrue_TstL_PL /* kLazyFlagsTstL PL */,
+ cctrue_TstL_MI /* kLazyFlagsTstL MI */,
+ cctrue_TstL_GE /* kLazyFlagsTstL GE */,
+ cctrue_TstL_LT /* kLazyFlagsTstL LT */,
+ cctrue_TstL_GT /* kLazyFlagsTstL GT */,
+ cctrue_TstL_LE /* kLazyFlagsTstL LE */,
+
+ cctrue_T /* kLazyFlagsCmpB T */,
+ cctrue_F /* kLazyFlagsCmpB F */,
+ cctrue_CmpB_HI /* kLazyFlagsCmpB HI */,
+ cctrue_CmpB_LS /* kLazyFlagsCmpB LS */,
+ cctrue_CmpB_CC /* kLazyFlagsCmpB CC */,
+ cctrue_CmpB_CS /* kLazyFlagsCmpB CS */,
+ cctrue_CmpB_NE /* kLazyFlagsCmpB NE */,
+ cctrue_CmpB_EQ /* kLazyFlagsCmpB EQ */,
+ cctrue_Dflt /* kLazyFlagsCmpB VC */,
+ cctrue_Dflt /* kLazyFlagsCmpB VS */,
+ cctrue_CmpB_PL /* kLazyFlagsCmpB PL */,
+ cctrue_CmpB_MI /* kLazyFlagsCmpB MI */,
+ cctrue_CmpB_GE /* kLazyFlagsCmpB GE */,
+ cctrue_CmpB_LT /* kLazyFlagsCmpB LT */,
+ cctrue_CmpB_GT /* kLazyFlagsCmpB GT */,
+ cctrue_CmpB_LE /* kLazyFlagsCmpB LE */,
+
+ cctrue_T /* kLazyFlagsCmpW T */,
+ cctrue_F /* kLazyFlagsCmpW F */,
+ cctrue_CmpW_HI /* kLazyFlagsCmpW HI */,
+ cctrue_CmpW_LS /* kLazyFlagsCmpW LS */,
+ cctrue_CmpW_CC /* kLazyFlagsCmpW CC */,
+ cctrue_CmpW_CS /* kLazyFlagsCmpW CS */,
+ cctrue_CmpW_NE /* kLazyFlagsCmpW NE */,
+ cctrue_CmpW_EQ /* kLazyFlagsCmpW EQ */,
+ cctrue_Dflt /* kLazyFlagsCmpW VC */,
+ cctrue_Dflt /* kLazyFlagsCmpW VS */,
+ cctrue_CmpW_PL /* kLazyFlagsCmpW PL */,
+ cctrue_CmpW_MI /* kLazyFlagsCmpW MI */,
+ cctrue_CmpW_GE /* kLazyFlagsCmpW GE */,
+ cctrue_CmpW_LT /* kLazyFlagsCmpW LT */,
+ cctrue_CmpW_GT /* kLazyFlagsCmpW GT */,
+ cctrue_CmpW_LE /* kLazyFlagsCmpW LE */,
+
+ cctrue_T /* kLazyFlagsCmpL T */,
+ cctrue_F /* kLazyFlagsCmpL F */,
+ cctrue_CmpL_HI /* kLazyFlagsCmpL HI */,
+ cctrue_CmpL_LS /* kLazyFlagsCmpL LS */,
+ cctrue_CmpL_CC /* kLazyFlagsCmpL CC */,
+ cctrue_CmpL_CS /* kLazyFlagsCmpL CS */,
+ cctrue_CmpL_NE /* kLazyFlagsCmpL NE */,
+ cctrue_CmpL_EQ /* kLazyFlagsCmpL EQ */,
+ cctrue_Dflt /* kLazyFlagsCmpL VC */,
+ cctrue_Dflt /* kLazyFlagsCmpL VS */,
+ cctrue_CmpL_PL /* kLazyFlagsCmpL PL */,
+ cctrue_CmpL_MI /* kLazyFlagsCmpL MI */,
+ cctrue_CmpL_GE /* kLazyFlagsCmpL GE */,
+ cctrue_CmpL_LT /* kLazyFlagsCmpL LT */,
+ cctrue_CmpL_GT /* kLazyFlagsCmpL GT */,
+ cctrue_CmpL_LE /* kLazyFlagsCmpL LE */,
+
+ cctrue_T /* kLazyFlagsSubB T */,
+ cctrue_F /* kLazyFlagsSubB F */,
+ cctrue_CmpB_HI /* kLazyFlagsSubB HI */,
+ cctrue_CmpB_LS /* kLazyFlagsSubB LS */,
+ cctrue_CmpB_CC /* kLazyFlagsSubB CC */,
+ cctrue_CmpB_CS /* kLazyFlagsSubB CS */,
+ cctrue_CmpB_NE /* kLazyFlagsSubB NE */,
+ cctrue_CmpB_EQ /* kLazyFlagsSubB EQ */,
+ cctrue_Dflt /* kLazyFlagsSubB VC */,
+ cctrue_Dflt /* kLazyFlagsSubB VS */,
+ cctrue_CmpB_PL /* kLazyFlagsSubB PL */,
+ cctrue_CmpB_MI /* kLazyFlagsSubB MI */,
+ cctrue_CmpB_GE /* kLazyFlagsSubB GE */,
+ cctrue_CmpB_LT /* kLazyFlagsSubB LT */,
+ cctrue_CmpB_GT /* kLazyFlagsSubB GT */,
+ cctrue_CmpB_LE /* kLazyFlagsSubB LE */,
+
+ cctrue_T /* kLazyFlagsSubW T */,
+ cctrue_F /* kLazyFlagsSubW F */,
+ cctrue_CmpW_HI /* kLazyFlagsSubW HI */,
+ cctrue_CmpW_LS /* kLazyFlagsSubW LS */,
+ cctrue_CmpW_CC /* kLazyFlagsSubW CC */,
+ cctrue_CmpW_CS /* kLazyFlagsSubW CS */,
+ cctrue_CmpW_NE /* kLazyFlagsSubW NE */,
+ cctrue_CmpW_EQ /* kLazyFlagsSubW EQ */,
+ cctrue_Dflt /* kLazyFlagsSubW VC */,
+ cctrue_Dflt /* kLazyFlagsSubW VS */,
+ cctrue_CmpW_PL /* kLazyFlagsSubW PL */,
+ cctrue_CmpW_MI /* kLazyFlagsSubW MI */,
+ cctrue_CmpW_GE /* kLazyFlagsSubW GE */,
+ cctrue_CmpW_LT /* kLazyFlagsSubW LT */,
+ cctrue_CmpW_GT /* kLazyFlagsSubW GT */,
+ cctrue_CmpW_LE /* kLazyFlagsSubW LE */,
+
+ cctrue_T /* kLazyFlagsSubL T */,
+ cctrue_F /* kLazyFlagsSubL F */,
+ cctrue_CmpL_HI /* kLazyFlagsSubL HI */,
+ cctrue_CmpL_LS /* kLazyFlagsSubL LS */,
+ cctrue_CmpL_CC /* kLazyFlagsSubL CC */,
+ cctrue_CmpL_CS /* kLazyFlagsSubL CS */,
+ cctrue_CmpL_NE /* kLazyFlagsSubL NE */,
+ cctrue_CmpL_EQ /* kLazyFlagsSubL EQ */,
+ cctrue_Dflt /* kLazyFlagsSubL VC */,
+ cctrue_Dflt /* kLazyFlagsSubL VS */,
+ cctrue_CmpL_PL /* kLazyFlagsSubL PL */,
+ cctrue_CmpL_MI /* kLazyFlagsSubL MI */,
+ cctrue_CmpL_GE /* kLazyFlagsSubL GE */,
+ cctrue_CmpL_LT /* kLazyFlagsSubL LT */,
+ cctrue_CmpL_GT /* kLazyFlagsSubL GT */,
+ cctrue_CmpL_LE /* kLazyFlagsSubL LE */,
+
+ cctrue_T /* kLazyFlagsAddB T */,
+ cctrue_F /* kLazyFlagsAddB F */,
+ cctrue_Dflt /* kLazyFlagsAddB HI */,
+ cctrue_Dflt /* kLazyFlagsAddB LS */,
+ cctrue_Dflt /* kLazyFlagsAddB CC */,
+ cctrue_Dflt /* kLazyFlagsAddB CS */,
+ cctrue_Dflt /* kLazyFlagsAddB NE */,
+ cctrue_Dflt /* kLazyFlagsAddB EQ */,
+ cctrue_Dflt /* kLazyFlagsAddB VC */,
+ cctrue_Dflt /* kLazyFlagsAddB VS */,
+ cctrue_Dflt /* kLazyFlagsAddB PL */,
+ cctrue_Dflt /* kLazyFlagsAddB MI */,
+ cctrue_Dflt /* kLazyFlagsAddB GE */,
+ cctrue_Dflt /* kLazyFlagsAddB LT */,
+ cctrue_Dflt /* kLazyFlagsAddB GT */,
+ cctrue_Dflt /* kLazyFlagsAddB LE */,
+
+ cctrue_T /* kLazyFlagsAddW T */,
+ cctrue_F /* kLazyFlagsAddW F */,
+ cctrue_Dflt /* kLazyFlagsAddW HI */,
+ cctrue_Dflt /* kLazyFlagsAddW LS */,
+ cctrue_Dflt /* kLazyFlagsAddW CC */,
+ cctrue_Dflt /* kLazyFlagsAddW CS */,
+ cctrue_Dflt /* kLazyFlagsAddW NE */,
+ cctrue_Dflt /* kLazyFlagsAddW EQ */,
+ cctrue_Dflt /* kLazyFlagsAddW VC */,
+ cctrue_Dflt /* kLazyFlagsAddW VS */,
+ cctrue_Dflt /* kLazyFlagsAddW PL */,
+ cctrue_Dflt /* kLazyFlagsAddW MI */,
+ cctrue_Dflt /* kLazyFlagsAddW GE */,
+ cctrue_Dflt /* kLazyFlagsAddW LT */,
+ cctrue_Dflt /* kLazyFlagsAddW GT */,
+ cctrue_Dflt /* kLazyFlagsAddW LE */,
+
+ cctrue_T /* kLazyFlagsAddL T */,
+ cctrue_F /* kLazyFlagsAddL F */,
+ cctrue_Dflt /* kLazyFlagsAddL HI */,
+ cctrue_Dflt /* kLazyFlagsAddL LS */,
+ cctrue_Dflt /* kLazyFlagsAddL CC */,
+ cctrue_Dflt /* kLazyFlagsAddL CS */,
+ cctrue_Dflt /* kLazyFlagsAddL NE */,
+ cctrue_Dflt /* kLazyFlagsAddL EQ */,
+ cctrue_Dflt /* kLazyFlagsAddL VC */,
+ cctrue_Dflt /* kLazyFlagsAddL VS */,
+ cctrue_Dflt /* kLazyFlagsAddL PL */,
+ cctrue_Dflt /* kLazyFlagsAddL MI */,
+ cctrue_Dflt /* kLazyFlagsAddL GE */,
+ cctrue_Dflt /* kLazyFlagsAddL LT */,
+ cctrue_Dflt /* kLazyFlagsAddL GT */,
+ cctrue_Dflt /* kLazyFlagsAddL LE */,
+
+ cctrue_T /* kLazyFlagsNegB T */,
+ cctrue_F /* kLazyFlagsNegB F */,
+ cctrue_Dflt /* kLazyFlagsNegB HI */,
+ cctrue_Dflt /* kLazyFlagsNegB LS */,
+ cctrue_Dflt /* kLazyFlagsNegB CC */,
+ cctrue_Dflt /* kLazyFlagsNegB CS */,
+ cctrue_Dflt /* kLazyFlagsNegB NE */,
+ cctrue_Dflt /* kLazyFlagsNegB EQ */,
+ cctrue_Dflt /* kLazyFlagsNegB VC */,
+ cctrue_Dflt /* kLazyFlagsNegB VS */,
+ cctrue_Dflt /* kLazyFlagsNegB PL */,
+ cctrue_Dflt /* kLazyFlagsNegB MI */,
+ cctrue_Dflt /* kLazyFlagsNegB GE */,
+ cctrue_Dflt /* kLazyFlagsNegB LT */,
+ cctrue_Dflt /* kLazyFlagsNegB GT */,
+ cctrue_Dflt /* kLazyFlagsNegB LE */,
+
+ cctrue_T /* kLazyFlagsNegW T */,
+ cctrue_F /* kLazyFlagsNegW F */,
+ cctrue_Dflt /* kLazyFlagsNegW HI */,
+ cctrue_Dflt /* kLazyFlagsNegW LS */,
+ cctrue_Dflt /* kLazyFlagsNegW CC */,
+ cctrue_Dflt /* kLazyFlagsNegW CS */,
+ cctrue_Dflt /* kLazyFlagsNegW NE */,
+ cctrue_Dflt /* kLazyFlagsNegW EQ */,
+ cctrue_Dflt /* kLazyFlagsNegW VC */,
+ cctrue_Dflt /* kLazyFlagsNegW VS */,
+ cctrue_Dflt /* kLazyFlagsNegW PL */,
+ cctrue_Dflt /* kLazyFlagsNegW MI */,
+ cctrue_Dflt /* kLazyFlagsNegW GE */,
+ cctrue_Dflt /* kLazyFlagsNegW LT */,
+ cctrue_Dflt /* kLazyFlagsNegW GT */,
+ cctrue_Dflt /* kLazyFlagsNegW LE */,
+
+ cctrue_T /* kLazyFlagsNegL T */,
+ cctrue_F /* kLazyFlagsNegL F */,
+ cctrue_Dflt /* kLazyFlagsNegL HI */,
+ cctrue_Dflt /* kLazyFlagsNegL LS */,
+ cctrue_Dflt /* kLazyFlagsNegL CC */,
+ cctrue_Dflt /* kLazyFlagsNegL CS */,
+ cctrue_Dflt /* kLazyFlagsNegL NE */,
+ cctrue_Dflt /* kLazyFlagsNegL EQ */,
+ cctrue_Dflt /* kLazyFlagsNegL VC */,
+ cctrue_Dflt /* kLazyFlagsNegL VS */,
+ cctrue_Dflt /* kLazyFlagsNegL PL */,
+ cctrue_Dflt /* kLazyFlagsNegL MI */,
+ cctrue_Dflt /* kLazyFlagsNegL GE */,
+ cctrue_Dflt /* kLazyFlagsNegL LT */,
+ cctrue_Dflt /* kLazyFlagsNegL GT */,
+ cctrue_Dflt /* kLazyFlagsNegL LE */,
+
+ cctrue_T /* kLazyFlagsAsrB T */,
+ cctrue_F /* kLazyFlagsAsrB F */,
+ cctrue_Dflt /* kLazyFlagsAsrB HI */,
+ cctrue_Dflt /* kLazyFlagsAsrB LS */,
+ cctrue_Asr_CC /* kLazyFlagsAsrB CC */,
+ cctrue_Asr_CS /* kLazyFlagsAsrB CS */,
+ cctrue_Dflt /* kLazyFlagsAsrB NE */,
+ cctrue_Dflt /* kLazyFlagsAsrB EQ */,
+ cctrue_Dflt /* kLazyFlagsAsrB VC */,
+ cctrue_Dflt /* kLazyFlagsAsrB VS */,
+ cctrue_Dflt /* kLazyFlagsAsrB PL */,
+ cctrue_Dflt /* kLazyFlagsAsrB MI */,
+ cctrue_Dflt /* kLazyFlagsAsrB GE */,
+ cctrue_Dflt /* kLazyFlagsAsrB LT */,
+ cctrue_Dflt /* kLazyFlagsAsrB GT */,
+ cctrue_Dflt /* kLazyFlagsAsrB LE */,
+
+ cctrue_T /* kLazyFlagsAsrW T */,
+ cctrue_F /* kLazyFlagsAsrW F */,
+ cctrue_Dflt /* kLazyFlagsAsrW HI */,
+ cctrue_Dflt /* kLazyFlagsAsrW LS */,
+ cctrue_Asr_CC /* kLazyFlagsAsrW CC */,
+ cctrue_Asr_CS /* kLazyFlagsAsrW CS */,
+ cctrue_Dflt /* kLazyFlagsAsrW NE */,
+ cctrue_Dflt /* kLazyFlagsAsrW EQ */,
+ cctrue_Dflt /* kLazyFlagsAsrW VC */,
+ cctrue_Dflt /* kLazyFlagsAsrW VS */,
+ cctrue_Dflt /* kLazyFlagsAsrW PL */,
+ cctrue_Dflt /* kLazyFlagsAsrW MI */,
+ cctrue_Dflt /* kLazyFlagsAsrW GE */,
+ cctrue_Dflt /* kLazyFlagsAsrW LT */,
+ cctrue_Dflt /* kLazyFlagsAsrW GT */,
+ cctrue_Dflt /* kLazyFlagsAsrW LE */,
+
+ cctrue_T /* kLazyFlagsAsrL T */,
+ cctrue_F /* kLazyFlagsAsrL F */,
+ cctrue_Dflt /* kLazyFlagsAsrL HI */,
+ cctrue_Dflt /* kLazyFlagsAsrL LS */,
+ cctrue_Asr_CC /* kLazyFlagsAsrL CC */,
+ cctrue_Asr_CS /* kLazyFlagsAsrL CS */,
+ cctrue_Dflt /* kLazyFlagsAsrL NE */,
+ cctrue_Dflt /* kLazyFlagsAsrL EQ */,
+ cctrue_Dflt /* kLazyFlagsAsrL VC */,
+ cctrue_Dflt /* kLazyFlagsAsrL VS */,
+ cctrue_Dflt /* kLazyFlagsAsrL PL */,
+ cctrue_Dflt /* kLazyFlagsAsrL MI */,
+ cctrue_Dflt /* kLazyFlagsAsrL GE */,
+ cctrue_Dflt /* kLazyFlagsAsrL LT */,
+ cctrue_Dflt /* kLazyFlagsAsrL GT */,
+ cctrue_Dflt /* kLazyFlagsAsrL LE */,
+
+ cctrue_T /* kLazyFlagsAslB T */,
+ cctrue_F /* kLazyFlagsAslB F */,
+ cctrue_Dflt /* kLazyFlagsAslB HI */,
+ cctrue_Dflt /* kLazyFlagsAslB LS */,
+ cctrue_AslB_CC /* kLazyFlagsAslB CC */,
+ cctrue_AslB_CS /* kLazyFlagsAslB CS */,
+ cctrue_Dflt /* kLazyFlagsAslB NE */,
+ cctrue_Dflt /* kLazyFlagsAslB EQ */,
+ cctrue_AslB_VC /* kLazyFlagsAslB VC */,
+ cctrue_AslB_VS /* kLazyFlagsAslB VS */,
+ cctrue_Dflt /* kLazyFlagsAslB PL */,
+ cctrue_Dflt /* kLazyFlagsAslB MI */,
+ cctrue_Dflt /* kLazyFlagsAslB GE */,
+ cctrue_Dflt /* kLazyFlagsAslB LT */,
+ cctrue_Dflt /* kLazyFlagsAslB GT */,
+ cctrue_Dflt /* kLazyFlagsAslB LE */,
+
+ cctrue_T /* kLazyFlagsAslW T */,
+ cctrue_F /* kLazyFlagsAslW F */,
+ cctrue_Dflt /* kLazyFlagsAslW HI */,
+ cctrue_Dflt /* kLazyFlagsAslW LS */,
+ cctrue_AslW_CC /* kLazyFlagsAslW CC */,
+ cctrue_AslW_CS /* kLazyFlagsAslW CS */,
+ cctrue_Dflt /* kLazyFlagsAslW NE */,
+ cctrue_Dflt /* kLazyFlagsAslW EQ */,
+ cctrue_AslW_VC /* kLazyFlagsAslW VC */,
+ cctrue_AslW_VS /* kLazyFlagsAslW VS */,
+ cctrue_Dflt /* kLazyFlagsAslW PL */,
+ cctrue_Dflt /* kLazyFlagsAslW MI */,
+ cctrue_Dflt /* kLazyFlagsAslW GE */,
+ cctrue_Dflt /* kLazyFlagsAslW LT */,
+ cctrue_Dflt /* kLazyFlagsAslW GT */,
+ cctrue_Dflt /* kLazyFlagsAslW LE */,
+
+ cctrue_T /* kLazyFlagsAslL T */,
+ cctrue_F /* kLazyFlagsAslL F */,
+ cctrue_Dflt /* kLazyFlagsAslL HI */,
+ cctrue_Dflt /* kLazyFlagsAslL LS */,
+ cctrue_AslL_CC /* kLazyFlagsAslL CC */,
+ cctrue_AslL_CS /* kLazyFlagsAslL CS */,
+ cctrue_Dflt /* kLazyFlagsAslL NE */,
+ cctrue_Dflt /* kLazyFlagsAslL EQ */,
+ cctrue_AslL_VC /* kLazyFlagsAslL VC */,
+ cctrue_AslL_VS /* kLazyFlagsAslL VS */,
+ cctrue_Dflt /* kLazyFlagsAslL PL */,
+ cctrue_Dflt /* kLazyFlagsAslL MI */,
+ cctrue_Dflt /* kLazyFlagsAslL GE */,
+ cctrue_Dflt /* kLazyFlagsAslL LT */,
+ cctrue_Dflt /* kLazyFlagsAslL GT */,
+ cctrue_Dflt /* kLazyFlagsAslL LE */,
+
+#if UseLazyZ
+ cctrue_T /* kLazyFlagsZSet T */,
+ cctrue_F /* kLazyFlagsZSet F */,
+ cctrue_Dflt /* kLazyFlagsZSet HI */,
+ cctrue_Dflt /* kLazyFlagsZSet LS */,
+ cctrue_Dflt /* kLazyFlagsZSet CC */,
+ cctrue_Dflt /* kLazyFlagsZSet CS */,
+ cctrue_NE /* kLazyFlagsZSet NE */,
+ cctrue_EQ /* kLazyFlagsZSet EQ */,
+ cctrue_Dflt /* kLazyFlagsZSet VC */,
+ cctrue_Dflt /* kLazyFlagsZSet VS */,
+ cctrue_Dflt /* kLazyFlagsZSet PL */,
+ cctrue_Dflt /* kLazyFlagsZSet MI */,
+ cctrue_Dflt /* kLazyFlagsZSet GE */,
+ cctrue_Dflt /* kLazyFlagsZSet LT */,
+ cctrue_Dflt /* kLazyFlagsZSet GT */,
+ cctrue_Dflt /* kLazyFlagsZSet LE */,
+#endif
+#endif /* UseLazyCC */
+
+ 0
+};
+
+#if UseLazyCC
+LOCALINLINEPROC cctrue(cond_actP t_act, cond_actP f_act)
+{
+ (cctrueDispatch[V_regs.LazyFlagKind * 16
+ + V_regs.CurDecOpY.v[0].ArgDat])(t_act, f_act);
+}
+#endif
+
+
+LOCALPROC NeedDefaultLazyXFlagSubB(void)
+{
+ XFLG = Bool2Bit(((ui3b)V_regs.LazyXFlagArgDst)
+ < ((ui3b)V_regs.LazyXFlagArgSrc));
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyXFlagSubW(void)
+{
+ XFLG = Bool2Bit(((ui4b)V_regs.LazyXFlagArgDst)
+ < ((ui4b)V_regs.LazyXFlagArgSrc));
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyXFlagSubL(void)
+{
+ XFLG = Bool2Bit(((ui5b)V_regs.LazyXFlagArgDst)
+ < ((ui5b)V_regs.LazyXFlagArgSrc));
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyXFlagAddB(void)
+{
+ ui3b src = (ui3b)V_regs.LazyXFlagArgSrc;
+ ui3b dst = (ui3b)V_regs.LazyXFlagArgDst;
+ ui3b result = dst + src;
+
+ XFLG = Bool2Bit(result < src);
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyXFlagAddW(void)
+{
+ ui4b src = (ui4b)V_regs.LazyXFlagArgSrc;
+ ui4b dst = (ui4b)V_regs.LazyXFlagArgDst;
+ ui4b result = dst + src;
+
+ XFLG = Bool2Bit(result < src);
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyXFlagAddL(void)
+{
+ ui5b src = (ui5b)V_regs.LazyXFlagArgSrc;
+ ui5b dst = (ui5b)V_regs.LazyXFlagArgDst;
+ ui5b result = dst + src;
+
+ XFLG = Bool2Bit(result < src);
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyXFlagNegB(void)
+{
+ XFLG = Bool2Bit(((ui3b)0)
+ < ((ui3b)V_regs.LazyXFlagArgDst));
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyXFlagNegW(void)
+{
+ XFLG = Bool2Bit(((ui4b)0)
+ < ((ui4b)V_regs.LazyXFlagArgDst));
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyXFlagNegL(void)
+{
+ XFLG = Bool2Bit(((ui5b)0)
+ < ((ui5b)V_regs.LazyXFlagArgDst));
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyXFlagAsr(void)
+{
+ ui5r cnt = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+
+ XFLG = ((dst >> (cnt - 1)) & 1);
+
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyXFlagAslB(void)
+{
+ XFLG = (V_regs.LazyFlagArgDst >> (8 - V_regs.LazyFlagArgSrc)) & 1;
+
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyXFlagAslW(void)
+{
+ XFLG = (V_regs.LazyFlagArgDst >> (16 - V_regs.LazyFlagArgSrc)) & 1;
+
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyXFlagAslL(void)
+{
+ XFLG = (V_regs.LazyFlagArgDst >> (32 - V_regs.LazyFlagArgSrc)) & 1;
+
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyXFlagDefault(void)
+{
+}
+
+typedef void (*NeedLazyFlagP)(void);
+
+LOCALVAR const NeedLazyFlagP
+ NeedLazyXFlagDispatch[kNumLazyFlagsKinds + 1] =
+{
+ NeedDefaultLazyXFlagDefault /* kLazyFlagsDefault */,
+ 0 /* kLazyFlagsTstB */,
+ 0 /* kLazyFlagsTstW */,
+ 0 /* kLazyFlagsTstL */,
+ 0 /* kLazyFlagsCmpB */,
+ 0 /* kLazyFlagsCmpW */,
+ 0 /* kLazyFlagsCmpL */,
+ NeedDefaultLazyXFlagSubB /* kLazyFlagsSubB */,
+ NeedDefaultLazyXFlagSubW /* kLazyFlagsSubW */,
+ NeedDefaultLazyXFlagSubL /* kLazyFlagsSubL */,
+ NeedDefaultLazyXFlagAddB /* kLazyFlagsAddB */,
+ NeedDefaultLazyXFlagAddW /* kLazyFlagsAddW */,
+ NeedDefaultLazyXFlagAddL /* kLazyFlagsAddL */,
+ NeedDefaultLazyXFlagNegB /* kLazyFlagsNegB */,
+ NeedDefaultLazyXFlagNegW /* kLazyFlagsNegW */,
+ NeedDefaultLazyXFlagNegL /* kLazyFlagsNegL */,
+ NeedDefaultLazyXFlagAsr /* kLazyFlagsAsrB */,
+ NeedDefaultLazyXFlagAsr /* kLazyFlagsAsrW */,
+ NeedDefaultLazyXFlagAsr /* kLazyFlagsAsrL */,
+ NeedDefaultLazyXFlagAslB /* kLazyFlagsAslB */,
+ NeedDefaultLazyXFlagAslW /* kLazyFlagsAslW */,
+ NeedDefaultLazyXFlagAslL /* kLazyFlagsAslL */,
+#if UseLazyZ
+ 0 /* kLazyFlagsZSet */,
+#endif
+
+ 0
+};
+
+LOCALPROC NeedDefaultLazyXFlag(void)
+{
+#if ForceFlagsEval
+ if (kLazyFlagsDefault != V_regs.LazyXFlagKind) {
+ ReportAbnormalID(0x0103,
+ "not kLazyFlagsDefault in NeedDefaultLazyXFlag");
+ }
+#else
+ (NeedLazyXFlagDispatch[V_regs.LazyXFlagKind])();
+#endif
+}
+
+LOCALPROC NeedDefaultLazyFlagsTstL(void)
+{
+ ui5r dst = V_regs.LazyFlagArgDst;
+
+ VFLG = CFLG = 0;
+ ZFLG = Bool2Bit(dst == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dst));
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ NeedDefaultLazyXFlag();
+}
+
+LOCALPROC NeedDefaultLazyFlagsCmpB(void)
+{
+ ui5r src = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+ ui5r result0 = dst - src;
+ ui5r result1 = ui5r_FromUByte(dst)
+ - ui5r_FromUByte(src);
+ ui5r result = ui5r_FromSByte(result0);
+
+ ZFLG = Bool2Bit(result == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(result));
+ VFLG = (((result0 >> 1) ^ result0) >> 7) & 1;
+ CFLG = (result1 >> 8) & 1;
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ NeedDefaultLazyXFlag();
+}
+
+LOCALPROC NeedDefaultLazyFlagsCmpW(void)
+{
+ ui5r result0 = V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc;
+ ui5r result = ui5r_FromSWord(result0);
+
+ ZFLG = Bool2Bit(result == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(result));
+
+ VFLG = (((result0 >> 1) ^ result0) >> 15) & 1;
+ {
+ ui5r result1 = ui5r_FromUWord(V_regs.LazyFlagArgDst)
+ - ui5r_FromUWord(V_regs.LazyFlagArgSrc);
+
+ CFLG = (result1 >> 16) & 1;
+ }
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ NeedDefaultLazyXFlag();
+}
+
+LOCALPROC NeedDefaultLazyFlagsCmpL(void)
+{
+ ui5r src = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+ ui5r result = ui5r_FromSLong(dst - src);
+
+ ZFLG = Bool2Bit(result == 0);
+
+ {
+ flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
+ flagtype flgs = Bool2Bit(ui5r_MSBisSet(src));
+ flagtype flgo = Bool2Bit(ui5r_MSBisSet(dst)) ^ 1;
+ flagtype flgsando = flgs & flgo;
+ flagtype flgsoro = flgs | flgo;
+
+ NFLG = flgn;
+ VFLG = ((flgn | flgsoro) ^ 1) | (flgn & flgsando);
+ CFLG = flgsando | (flgn & flgsoro);
+ }
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ NeedDefaultLazyXFlag();
+}
+
+LOCALPROC NeedDefaultLazyFlagsSubB(void)
+{
+ ui5r src = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+ ui5r result0 = dst - src;
+ ui5r result1 = ui5r_FromUByte(dst)
+ - ui5r_FromUByte(src);
+ ui5r result = ui5r_FromSByte(result0);
+
+ ZFLG = Bool2Bit(result == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(result));
+ VFLG = (((result0 >> 1) ^ result0) >> 7) & 1;
+ CFLG = (result1 >> 8) & 1;
+
+ XFLG = CFLG;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyFlagsSubW(void)
+{
+ ui5r result0 = V_regs.LazyFlagArgDst - V_regs.LazyFlagArgSrc;
+ ui5r result = ui5r_FromSWord(result0);
+
+ ZFLG = Bool2Bit(result == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(result));
+
+ VFLG = (((result0 >> 1) ^ result0) >> 15) & 1;
+ {
+ ui5r result1 = ui5r_FromUWord(V_regs.LazyFlagArgDst)
+ - ui5r_FromUWord(V_regs.LazyFlagArgSrc);
+
+ CFLG = (result1 >> 16) & 1;
+ }
+
+ XFLG = CFLG;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyFlagsSubL(void)
+{
+ ui5r src = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+ ui5r result = ui5r_FromSLong(dst - src);
+
+ ZFLG = Bool2Bit(result == 0);
+
+ {
+ flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
+ flagtype flgs = Bool2Bit(ui5r_MSBisSet(src));
+ flagtype flgo = Bool2Bit(ui5r_MSBisSet(dst)) ^ 1;
+ flagtype flgsando = flgs & flgo;
+ flagtype flgsoro = flgs | flgo;
+
+ NFLG = flgn;
+ VFLG = ((flgn | flgsoro) ^ 1) | (flgn & flgsando);
+ CFLG = flgsando | (flgn & flgsoro);
+ }
+
+ XFLG = CFLG;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyFlagsAddB(void)
+{
+ ui5r src = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+ ui5r result0 = dst + src;
+ ui5r result1 = ui5r_FromUByte(dst)
+ + ui5r_FromUByte(src);
+ ui5r result = ui5r_FromSByte(result0);
+
+ ZFLG = Bool2Bit(result == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(result));
+ VFLG = (((result0 >> 1) ^ result0) >> 7) & 1;
+ CFLG = (result1 >> 8);
+
+ XFLG = CFLG;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyFlagsAddW(void)
+{
+ ui5r src = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+ ui5r result0 = dst + src;
+ ui5r result1 = ui5r_FromUWord(dst)
+ + ui5r_FromUWord(src);
+ ui5r result = ui5r_FromSWord(result0);
+
+ ZFLG = Bool2Bit(result == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(result));
+ VFLG = (((result0 >> 1) ^ result0) >> 15) & 1;
+ CFLG = (result1 >> 16);
+
+ XFLG = CFLG;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+#if 0
+LOCALPROC NeedDefaultLazyFlagsAddCommon(ui5r result)
+{
+ ZFLG = Bool2Bit(result == 0);
+ {
+ flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
+ flagtype flgs = Bool2Bit(ui5r_MSBisSet(V_regs.LazyFlagArgSrc));
+ flagtype flgo = Bool2Bit(ui5r_MSBisSet(V_regs.LazyFlagArgDst));
+ flagtype flgsando = flgs & flgo;
+ flagtype flgsoro = flgs | flgo;
+
+ NFLG = flgn;
+ flgn ^= 1;
+ VFLG = ((flgn | flgsoro) ^ 1) | (flgn & flgsando);
+ CFLG = flgsando | (flgn & flgsoro);
+ }
+
+ XFLG = CFLG;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+#endif
+
+LOCALPROC NeedDefaultLazyFlagsAddL(void)
+{
+#if 1
+ ui5r src = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+ ui5r result = ui5r_FromSLong(dst + src);
+
+ ZFLG = Bool2Bit(result == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(result));
+
+ {
+ ui5r result1;
+ ui5r result0;
+ ui5r MidCarry = (ui5r_FromUWord(dst)
+ + ui5r_FromUWord(src)) >> 16;
+
+ dst >>= 16;
+ src >>= 16;
+
+ result1 = ui5r_FromUWord(dst)
+ + ui5r_FromUWord(src)
+ + MidCarry;
+ CFLG = (result1 >> 16);
+ result0 = ui5r_FromSWord(dst)
+ + ui5r_FromSWord(src)
+ + MidCarry;
+ VFLG = (((result0 >> 1) ^ result0) >> 15) & 1;
+ }
+
+ XFLG = CFLG;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+#else
+ ui5r result = ui5r_FromSLong(V_regs.LazyFlagArgDst
+ + V_regs.LazyFlagArgSrc);
+
+ NeedDefaultLazyFlagsAddCommon(result);
+#endif
+}
+
+LOCALPROC NeedDefaultLazyFlagsNegCommon(ui5r dstvalue, ui5r result)
+{
+ flagtype flgs = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
+
+ ZFLG = Bool2Bit(result == 0);
+ NFLG = flgn;
+ VFLG = flgs & flgn;
+ CFLG = flgs | flgn;
+
+ XFLG = CFLG;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyFlagsNegB(void)
+{
+ ui5r dstvalue = V_regs.LazyFlagArgDst;
+ ui5r result = ui5r_FromSByte(0 - dstvalue);
+
+ NeedDefaultLazyFlagsNegCommon(dstvalue, result);
+}
+
+LOCALPROC NeedDefaultLazyFlagsNegW(void)
+{
+ ui5r dstvalue = V_regs.LazyFlagArgDst;
+ ui5r result = ui5r_FromSWord(0 - dstvalue);
+
+ NeedDefaultLazyFlagsNegCommon(dstvalue, result);
+}
+
+LOCALPROC NeedDefaultLazyFlagsNegL(void)
+{
+ ui5r dstvalue = V_regs.LazyFlagArgDst;
+ ui5r result = ui5r_FromSLong(0 - dstvalue);
+
+ NeedDefaultLazyFlagsNegCommon(dstvalue, result);
+}
+
+LOCALPROC NeedDefaultLazyFlagsAsr(void)
+{
+ ui5r cnt = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+
+ NFLG = Bool2Bit(ui5r_MSBisSet(dst));
+ VFLG = 0;
+
+ CFLG = ((dst >> (cnt - 1)) & 1);
+ dst = Ui5rASR(dst, cnt);
+ ZFLG = Bool2Bit(dst == 0);
+
+ XFLG = CFLG;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyFlagsAslB(void)
+{
+ ui5r cnt = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+ ui5r dstvalue0 = dst;
+ ui5r comparevalue;
+
+ dst = dst << (cnt - 1);
+ dst = ui5r_FromSByte(dst);
+ CFLG = Bool2Bit(ui5r_MSBisSet(dst));
+ dst = dst << 1;
+ dst = ui5r_FromSByte(dst);
+ comparevalue = Ui5rASR(dst, cnt);
+ VFLG = Bool2Bit(comparevalue != dstvalue0);
+ ZFLG = Bool2Bit(dst == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dst));
+
+ XFLG = CFLG;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyFlagsAslW(void)
+{
+ ui5r cnt = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+ ui5r dstvalue0 = dst;
+ ui5r comparevalue;
+
+ dst = dst << (cnt - 1);
+ dst = ui5r_FromSWord(dst);
+ CFLG = Bool2Bit(ui5r_MSBisSet(dst));
+ dst = dst << 1;
+ dst = ui5r_FromSWord(dst);
+ comparevalue = Ui5rASR(dst, cnt);
+ VFLG = Bool2Bit(comparevalue != dstvalue0);
+ ZFLG = Bool2Bit(dst == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dst));
+
+ XFLG = CFLG;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+LOCALPROC NeedDefaultLazyFlagsAslL(void)
+{
+ ui5r cnt = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+ ui5r dstvalue0 = dst;
+ ui5r comparevalue;
+
+ dst = dst << (cnt - 1);
+ dst = ui5r_FromSLong(dst);
+ CFLG = Bool2Bit(ui5r_MSBisSet(dst));
+ dst = dst << 1;
+ dst = ui5r_FromSLong(dst);
+ comparevalue = Ui5rASR(dst, cnt);
+ VFLG = Bool2Bit(comparevalue != dstvalue0);
+ ZFLG = Bool2Bit(dst == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dst));
+
+ XFLG = CFLG;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+#if UseLazyZ
+FORWARDPROC NeedDefaultLazyFlagsZSet(void);
+#endif
+
+LOCALVAR const NeedLazyFlagP
+ NeedLazyFlagDispatch[kNumLazyFlagsKinds + 1] =
+{
+ NeedDefaultLazyXFlag /* kLazyFlagsDefault */,
+ 0 /* kLazyFlagsTstB */,
+ 0 /* kLazyFlagsTstW */,
+ NeedDefaultLazyFlagsTstL /* kLazyFlagsTstL */,
+ NeedDefaultLazyFlagsCmpB /* kLazyFlagsCmpB */,
+ NeedDefaultLazyFlagsCmpW /* kLazyFlagsCmpW */,
+ NeedDefaultLazyFlagsCmpL /* kLazyFlagsCmpL */,
+ NeedDefaultLazyFlagsSubB /* kLazyFlagsSubB */,
+ NeedDefaultLazyFlagsSubW /* kLazyFlagsSubW */,
+ NeedDefaultLazyFlagsSubL /* kLazyFlagsSubL */,
+ NeedDefaultLazyFlagsAddB /* kLazyFlagsAddB */,
+ NeedDefaultLazyFlagsAddW /* kLazyFlagsAddW */,
+ NeedDefaultLazyFlagsAddL /* kLazyFlagsAddL */,
+ NeedDefaultLazyFlagsNegB /* kLazyFlagsNegB */,
+ NeedDefaultLazyFlagsNegW /* kLazyFlagsNegW */,
+ NeedDefaultLazyFlagsNegL /* kLazyFlagsNegL */,
+ NeedDefaultLazyFlagsAsr /* kLazyFlagsAsrB */,
+ NeedDefaultLazyFlagsAsr /* kLazyFlagsAsrW */,
+ NeedDefaultLazyFlagsAsr /* kLazyFlagsAsrL */,
+ NeedDefaultLazyFlagsAslB /* kLazyFlagsAslB */,
+ NeedDefaultLazyFlagsAslW /* kLazyFlagsAslW */,
+ NeedDefaultLazyFlagsAslL /* kLazyFlagsAslL */,
+#if UseLazyZ
+ NeedDefaultLazyFlagsZSet /* kLazyFlagsZSet */,
+#endif
+
+ 0
+};
+
+LOCALPROC NeedDefaultLazyAllFlags0(void)
+{
+ (NeedLazyFlagDispatch[V_regs.LazyFlagKind])();
+}
+
+#if ForceFlagsEval
+LOCALPROC NeedDefaultLazyAllFlags(void)
+{
+ if (kLazyFlagsDefault != V_regs.LazyFlagKind) {
+ ReportAbnormalID(0x0104,
+ "not kLazyFlagsDefault in NeedDefaultLazyAllFlags");
+#if dbglog_HAVE
+ dbglog_writelnNum("LazyFlagKind", V_regs.LazyFlagKind);
+#endif
+ }
+}
+#else
+#define NeedDefaultLazyAllFlags NeedDefaultLazyAllFlags0
+#endif
+
+#if ForceFlagsEval
+#define HaveSetUpFlags NeedDefaultLazyAllFlags0
+#else
+#define HaveSetUpFlags()
+#endif
+
+#if UseLazyZ
+LOCALPROC NeedDefaultLazyFlagsZSet(void)
+{
+ flagtype SaveZFLG = ZFLG;
+
+ V_regs.LazyFlagKind = V_regs.LazyFlagZSavedKind;
+ NeedDefaultLazyAllFlags();
+
+ ZFLG = SaveZFLG;
+}
+#endif
+
+#if UseLazyCC
+LOCALPROC my_reg_call cctrue_Dflt(cond_actP t_act, cond_actP f_act)
+{
+ NeedDefaultLazyAllFlags();
+ cctrue(t_act, f_act);
+}
+#endif
+
+#if ! UseLazyCC
+LOCALINLINEPROC cctrue(cond_actP t_act, cond_actP f_act)
+{
+ NeedDefaultLazyAllFlags();
+ (cctrueDispatch[V_regs.CurDecOpY.v[0].ArgDat])(t_act, f_act);
+}
+#endif
+
+
+#define LOCALIPROC LOCALPROC /* LOCALPROCUSEDONCE */
+
+LOCALIPROC DoCodeCmpB(void)
+{
+ ui5r dstvalue = DecodeGetSrcGetDstValue();
+
+ V_regs.LazyFlagKind = kLazyFlagsCmpB;
+ V_regs.LazyFlagArgSrc = V_regs.SrcVal;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+}
+
+LOCALIPROC DoCodeCmpW(void)
+{
+ ui5r dstvalue = DecodeGetSrcGetDstValue();
+
+ V_regs.LazyFlagKind = kLazyFlagsCmpW;
+ V_regs.LazyFlagArgSrc = V_regs.SrcVal;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+}
+
+LOCALIPROC DoCodeCmpL(void)
+{
+ ui5r dstvalue = DecodeGetSrcGetDstValue();
+
+ V_regs.LazyFlagKind = kLazyFlagsCmpL;
+ V_regs.LazyFlagArgSrc = V_regs.SrcVal;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+}
+
+LOCALIPROC DoCodeMoveL(void)
+{
+ ui5r src = DecodeGetSrcValue();
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = src;
+
+ HaveSetUpFlags();
+
+ DecodeSetDstValue(src);
+}
+
+LOCALIPROC DoCodeMoveW(void)
+{
+ ui5r src = DecodeGetSrcValue();
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = src;
+
+ HaveSetUpFlags();
+
+ DecodeSetDstValue(src);
+}
+
+LOCALIPROC DoCodeMoveB(void)
+{
+ ui5r src = DecodeGetSrcValue();
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = src;
+
+ HaveSetUpFlags();
+
+ DecodeSetDstValue(src);
+}
+
+LOCALIPROC DoCodeTst(void)
+{
+ /* Tst 01001010ssmmmrrr */
+
+ ui5r srcvalue = DecodeGetDstValue();
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = srcvalue;
+
+ HaveSetUpFlags();
+}
+
+LOCALIPROC DoCodeBraB(void)
+{
+ si5r offset = (si5r)(si3b)(ui3b)(V_regs.CurDecOpY.v[1].ArgDat);
+ ui3p s = V_pc_p + offset;
+
+ V_pc_p = s;
+
+#if USE_PCLIMIT
+ if (my_cond_rare(s >= V_pc_pHi)
+ || my_cond_rare(s < V_regs.pc_pLo))
+ {
+ Recalc_PC_Block();
+ }
+#endif
+}
+
+LOCALIPROC DoCodeBraW(void)
+{
+ si5r offset = (si5r)(si4b)(ui4b)do_get_mem_word(V_pc_p);
+ /* note that pc not incremented here */
+ ui3p s = V_pc_p + offset;
+
+ V_pc_p = s;
+
+#if USE_PCLIMIT
+ if (my_cond_rare(s >= V_pc_pHi)
+ || my_cond_rare(s < V_regs.pc_pLo))
+ {
+ Recalc_PC_Block();
+ }
+#endif
+}
+
+#if WantCloserCyc
+LOCALPROC DoCodeBccB_t(void)
+{
+ V_MaxCyclesToGo -= (10 * kCycleScale + 2 * RdAvgXtraCyc);
+ DoCodeBraB();
+}
+#else
+#define DoCodeBccB_t DoCodeBraB
+#endif
+
+LOCALPROC DoCodeBccB_f(void)
+{
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (8 * kCycleScale + RdAvgXtraCyc);
+#endif
+ /* do nothing */
+}
+
+LOCALIPROC DoCodeBccB(void)
+{
+ /* Bcc 0110ccccnnnnnnnn */
+ cctrue(DoCodeBccB_t, DoCodeBccB_f);
+}
+
+LOCALPROC SkipiWord(void)
+{
+ V_pc_p += 2;
+
+#if USE_PCLIMIT
+ if (my_cond_rare(V_pc_p >= V_pc_pHi)) {
+ Recalc_PC_Block();
+ }
+#endif
+}
+
+#if WantCloserCyc
+LOCALPROC DoCodeBccW_t(void)
+{
+ V_MaxCyclesToGo -= (10 * kCycleScale + 2 * RdAvgXtraCyc);
+ DoCodeBraW();
+}
+#else
+#define DoCodeBccW_t DoCodeBraW
+#endif
+
+#if WantCloserCyc
+LOCALPROC DoCodeBccW_f(void)
+{
+ V_MaxCyclesToGo -= (12 * kCycleScale + 2 * RdAvgXtraCyc);
+ SkipiWord();
+}
+#else
+#define DoCodeBccW_f SkipiWord
+#endif
+
+LOCALIPROC DoCodeBccW(void)
+{
+ /* Bcc 0110ccccnnnnnnnn */
+ cctrue(DoCodeBccW_t, DoCodeBccW_f);
+}
+
+
+LOCALIPROC DoCodeDBF(void)
+{
+ /* DBcc 0101cccc11001ddd */
+
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r dstvalue = ui5r_FromSWord(*dstp);
+
+ --dstvalue;
+#if LittleEndianUnaligned
+ *(ui4b *)dstp = dstvalue;
+#else
+ *dstp = (*dstp & ~ 0xffff) | ((dstvalue) & 0xffff);
+#endif
+
+ if ((si5b)dstvalue == -1) {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (14 * kCycleScale + 3 * RdAvgXtraCyc);
+#endif
+ SkipiWord();
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (10 * kCycleScale + 2 * RdAvgXtraCyc);
+#endif
+ DoCodeBraW();
+ }
+}
+
+#if WantCloserCyc
+LOCALPROC DoCodeDBcc_t(void)
+{
+ V_MaxCyclesToGo -= (12 * kCycleScale + 2 * RdAvgXtraCyc);
+ SkipiWord();
+}
+#else
+#define DoCodeDBcc_t SkipiWord
+#endif
+
+LOCALIPROC DoCodeDBcc(void)
+{
+ /* DBcc 0101cccc11001ddd */
+
+ cctrue(DoCodeDBcc_t, DoCodeDBF);
+}
+
+LOCALIPROC DoCodeSwap(void)
+{
+ /* Swap 0100100001000rrr */
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r src = *dstp;
+ ui5r dst = ui5r_FromSLong(((src >> 16) & 0xFFFF)
+ | ((src & 0xFFFF) << 16));
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = dst;
+
+ HaveSetUpFlags();
+
+ *dstp = dst;
+}
+
+LOCALIPROC DoCodeMoveA(void) /* MOVE */
+{
+ ui5r src = DecodeGetSrcValue();
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+
+ m68k_areg(dstreg) = src;
+}
+
+LOCALIPROC DoCodeMoveQ(void)
+{
+ /* MoveQ 0111ddd0nnnnnnnn */
+ ui5r src = ui5r_FromSByte(V_regs.CurDecOpY.v[0].ArgDat);
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = src;
+
+ HaveSetUpFlags();
+
+ m68k_dreg(dstreg) = src;
+}
+
+LOCALIPROC DoCodeAddB(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r srcvalue = V_regs.SrcVal;
+ ui5r result = ui5r_FromSByte(dstvalue + srcvalue);
+
+ V_regs.LazyFlagKind = kLazyFlagsAddB;
+ V_regs.LazyFlagArgSrc = srcvalue;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ V_regs.LazyXFlagKind = kLazyFlagsAddB;
+ V_regs.LazyXFlagArgSrc = srcvalue;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+}
+
+LOCALIPROC DoCodeAddW(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r srcvalue = V_regs.SrcVal;
+ ui5r result = ui5r_FromSWord(dstvalue + srcvalue);
+
+ V_regs.LazyFlagKind = kLazyFlagsAddW;
+ V_regs.LazyFlagArgSrc = srcvalue;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ V_regs.LazyXFlagKind = kLazyFlagsAddW;
+ V_regs.LazyXFlagArgSrc = srcvalue;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+}
+
+LOCALIPROC DoCodeAddL(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r srcvalue = V_regs.SrcVal;
+ ui5r result = ui5r_FromSLong(dstvalue + srcvalue);
+
+ V_regs.LazyFlagKind = kLazyFlagsAddL;
+ V_regs.LazyFlagArgSrc = srcvalue;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ V_regs.LazyXFlagKind = kLazyFlagsAddL;
+ V_regs.LazyXFlagArgSrc = srcvalue;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+}
+
+LOCALIPROC DoCodeSubB(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r srcvalue = V_regs.SrcVal;
+ ui5r result = ui5r_FromSByte(dstvalue - srcvalue);
+
+ V_regs.LazyFlagKind = kLazyFlagsSubB;
+ V_regs.LazyFlagArgSrc = srcvalue;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ V_regs.LazyXFlagKind = kLazyFlagsSubB;
+ V_regs.LazyXFlagArgSrc = srcvalue;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+}
+
+LOCALIPROC DoCodeSubW(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r srcvalue = V_regs.SrcVal;
+ ui5r result = ui5r_FromSWord(dstvalue - srcvalue);
+
+ V_regs.LazyFlagKind = kLazyFlagsSubW;
+ V_regs.LazyFlagArgSrc = srcvalue;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ V_regs.LazyXFlagKind = kLazyFlagsSubW;
+ V_regs.LazyXFlagArgSrc = srcvalue;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+}
+
+LOCALIPROC DoCodeSubL(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r srcvalue = V_regs.SrcVal;
+ ui5r result = ui5r_FromSLong(dstvalue - srcvalue);
+
+ V_regs.LazyFlagKind = kLazyFlagsSubL;
+ V_regs.LazyFlagArgSrc = srcvalue;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ V_regs.LazyXFlagKind = kLazyFlagsSubL;
+ V_regs.LazyXFlagArgSrc = srcvalue;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+}
+
+LOCALIPROC DoCodeLea(void)
+{
+ /* Lea 0100aaa111mmmrrr */
+ ui5r DstAddr = DecodeDst();
+ ui5r dstreg = V_regs.CurDecOpY.v[0].ArgDat;
+
+ m68k_areg(dstreg) = DstAddr;
+}
+
+LOCALIPROC DoCodePEA(void)
+{
+ /* PEA 0100100001mmmrrr */
+ ui5r DstAddr = DecodeDst();
+
+ m68k_areg(7) -= 4;
+ put_long(m68k_areg(7), DstAddr);
+}
+
+LOCALIPROC DoCodeBsrB(void)
+{
+ m68k_areg(7) -= 4;
+ put_long(m68k_areg(7), m68k_getpc());
+ DoCodeBraB();
+}
+
+LOCALIPROC DoCodeBsrW(void)
+{
+ m68k_areg(7) -= 4;
+ put_long(m68k_areg(7), m68k_getpc() + 2);
+ DoCodeBraW();
+}
+
+#define m68k_logExceptions (dbglog_HAVE && 0)
+
+
+#ifndef WantDumpAJump
+#define WantDumpAJump 0
+#endif
+
+#if WantDumpAJump
+LOCALPROCUSEDONCE DumpAJump(CPTR toaddr)
+{
+ CPTR fromaddr = m68k_getpc();
+ if ((toaddr > fromaddr) || (toaddr < V_regs.pc))
+ {
+ dbglog_writeHex(fromaddr);
+ dbglog_writeCStr(",");
+ dbglog_writeHex(toaddr);
+ dbglog_writeReturn();
+ }
+}
+#endif
+
+LOCALPROC my_reg_call m68k_setpc(CPTR newpc)
+{
+#if WantDumpAJump
+ DumpAJump(newpc);
+#endif
+
+#if 0
+ if (newpc == 0xBD50 /* 401AB4 */) {
+ /* Debugger(); */
+ /* Exception(5); */ /* try and get macsbug */
+ }
+#endif
+
+ V_pc_p = V_regs.pc_pLo + (newpc - V_regs.pc);
+ if (my_cond_rare(V_pc_p >= V_pc_pHi)
+ || my_cond_rare(V_pc_p < V_regs.pc_pLo))
+ {
+ Recalc_PC_Block();
+ }
+}
+
+LOCALIPROC DoCodeJsr(void)
+{
+ /* Jsr 0100111010mmmrrr */
+ ui5r DstAddr = DecodeDst();
+
+ m68k_areg(7) -= 4;
+ put_long(m68k_areg(7), m68k_getpc());
+ m68k_setpc(DstAddr);
+}
+
+LOCALIPROC DoCodeLinkA6(void)
+{
+ CPTR stackp = m68k_areg(7);
+ stackp -= 4;
+ put_long(stackp, m68k_areg(6));
+ m68k_areg(6) = stackp;
+ m68k_areg(7) = stackp + nextiSWord();
+}
+
+LOCALIPROC DoCodeUnlkA6(void)
+{
+ ui5r src = m68k_areg(6);
+ m68k_areg(6) = get_long(src);
+ m68k_areg(7) = src + 4;
+}
+
+LOCALIPROC DoCodeRts(void)
+{
+ /* Rts 0100111001110101 */
+ ui5r NewPC = get_long(m68k_areg(7));
+ m68k_areg(7) += 4;
+ m68k_setpc(NewPC);
+}
+
+LOCALIPROC DoCodeJmp(void)
+{
+ /* JMP 0100111011mmmrrr */
+ ui5r DstAddr = DecodeDst();
+
+ m68k_setpc(DstAddr);
+}
+
+LOCALIPROC DoCodeClr(void)
+{
+ /* Clr 01000010ssmmmrrr */
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = 0;
+
+ HaveSetUpFlags();
+
+ DecodeSetDstValue(0);
+}
+
+LOCALIPROC DoCodeAddA(void)
+{
+ /* ADDA 1101dddm11mmmrrr */
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+
+ ArgSetDstValue(dstvalue + V_regs.SrcVal);
+}
+
+LOCALIPROC DoCodeSubA(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+
+ ArgSetDstValue(dstvalue - V_regs.SrcVal);
+}
+
+LOCALIPROC DoCodeCmpA(void)
+{
+ ui5r dstvalue = DecodeGetSrcGetDstValue();
+
+ V_regs.LazyFlagKind = kLazyFlagsCmpL;
+ V_regs.LazyFlagArgSrc = V_regs.SrcVal;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+}
+
+LOCALFUNC ui4rr m68k_getCR(void)
+{
+ NeedDefaultLazyAllFlags();
+
+ return (XFLG << 4) | (NFLG << 3) | (ZFLG << 2)
+ | (VFLG << 1) | CFLG;
+}
+
+LOCALPROC my_reg_call m68k_setCR(ui4rr newcr)
+{
+ XFLG = (newcr >> 4) & 1;
+ NFLG = (newcr >> 3) & 1;
+ ZFLG = (newcr >> 2) & 1;
+ VFLG = (newcr >> 1) & 1;
+ CFLG = newcr & 1;
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+}
+
+
+LOCALFUNC ui4rr m68k_getSR(void)
+{
+ return m68k_getCR()
+ | (V_regs.t1 << 15)
+#if Use68020
+ | (V_regs.t0 << 14)
+#endif
+ | (V_regs.s << 13)
+#if Use68020
+ | (V_regs.m << 12)
+#endif
+ | (V_regs.intmask << 8);
+}
+
+LOCALPROC NeedToGetOut(void)
+{
+ if (V_MaxCyclesToGo <= 0) {
+ /*
+ already have gotten out, and exception processing has
+ caused another exception, such as because a bad
+ stack pointer pointing to a memory mapped device.
+ */
+ } else {
+ V_regs.MoreCyclesToGo += V_MaxCyclesToGo;
+ /* not counting the current instruction */
+ V_MaxCyclesToGo = 0;
+ }
+}
+
+LOCALPROC SetExternalInterruptPending(void)
+{
+ V_regs.ExternalInterruptPending = trueblnr;
+ NeedToGetOut();
+}
+
+LOCALPROC my_reg_call m68k_setSR(ui4rr newsr)
+{
+ CPTR *pnewstk;
+ CPTR *poldstk = (V_regs.s != 0) ? (
+#if Use68020
+ (V_regs.m != 0) ? &V_regs.msp :
+#endif
+ &V_regs.isp) : &V_regs.usp;
+ ui5r oldintmask = V_regs.intmask;
+
+ V_regs.t1 = (newsr >> 15) & 1;
+#if Use68020
+ V_regs.t0 = (newsr >> 14) & 1;
+ if (V_regs.t0 != 0) {
+ ReportAbnormalID(0x0105, "t0 flag set in m68k_setSR");
+ }
+#endif
+ V_regs.s = (newsr >> 13) & 1;
+#if Use68020
+ V_regs.m = (newsr >> 12) & 1;
+ if (V_regs.m != 0) {
+ ReportAbnormalID(0x0106, "m flag set in m68k_setSR");
+ }
+#endif
+ V_regs.intmask = (newsr >> 8) & 7;
+
+ pnewstk = (V_regs.s != 0) ? (
+#if Use68020
+ (V_regs.m != 0) ? &V_regs.msp :
+#endif
+ &V_regs.isp) : &V_regs.usp;
+
+ if (poldstk != pnewstk) {
+ *poldstk = m68k_areg(7);
+ m68k_areg(7) = *pnewstk;
+ }
+
+ if (V_regs.intmask != oldintmask) {
+ SetExternalInterruptPending();
+ }
+
+ if (V_regs.t1 != 0) {
+ NeedToGetOut();
+ } else {
+ /* V_regs.TracePending = falseblnr; */
+ }
+
+ m68k_setCR(newsr);
+}
+
+LOCALPROC my_reg_call ExceptionTo(CPTR newpc
+#if Use68020
+ , int nr
+#endif
+ )
+{
+ ui4rr saveSR = m68k_getSR();
+
+ if (0 == V_regs.s) {
+ V_regs.usp = m68k_areg(7);
+ m68k_areg(7) =
+#if Use68020
+ (V_regs.m != 0) ? V_regs.msp :
+#endif
+ V_regs.isp;
+ V_regs.s = 1;
+ }
+#if Use68020
+ switch (nr) {
+ case 5: /* Zero Divide */
+ case 6: /* CHK, CHK2 */
+ case 7: /* cpTRAPcc, TRAPCcc, TRAPv */
+ case 9: /* Trace */
+ m68k_areg(7) -= 4;
+ put_long(m68k_areg(7), m68k_getpc());
+ m68k_areg(7) -= 2;
+ put_word(m68k_areg(7), 0x2000 + nr * 4);
+ break;
+ default:
+ m68k_areg(7) -= 2;
+ put_word(m68k_areg(7), nr * 4);
+ break;
+ }
+ /* if V_regs.m should make throw away stack frame */
+#endif
+ m68k_areg(7) -= 4;
+ put_long(m68k_areg(7), m68k_getpc());
+ m68k_areg(7) -= 2;
+ put_word(m68k_areg(7), saveSR);
+ m68k_setpc(newpc);
+ V_regs.t1 = 0;
+#if Use68020
+ V_regs.t0 = 0;
+ V_regs.m = 0;
+#endif
+ V_regs.TracePending = falseblnr;
+}
+
+LOCALPROC my_reg_call Exception(int nr)
+{
+ ExceptionTo(get_long(4 * nr
+#if Use68020
+ + V_regs.vbr
+#endif
+ )
+#if Use68020
+ , nr
+#endif
+ );
+}
+
+
+LOCALIPROC DoCodeA(void)
+{
+ BackupPC();
+ Exception(0xA);
+}
+
+LOCALFUNC ui4rr nextiword_nm(void)
+/* NOT sign extended */
+{
+ return nextiword();
+}
+
+LOCALIPROC DoCodeMOVEMRmML(void)
+{
+ /* MOVEM reg to mem 01001000111100rrr */
+ si4b z;
+ ui5r regmask = nextiword_nm();
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r p = *dstp;
+
+#if Use68020
+ {
+ int n = 0;
+
+ for (z = 0; z < 16; ++z) {
+ if ((regmask & (1 << z)) != 0) {
+ n++;
+ }
+ }
+ *dstp = p - n * 4;
+ }
+#endif
+ for (z = 16; --z >= 0; ) {
+ if ((regmask & (1 << (15 - z))) != 0) {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (8 * kCycleScale + 2 * WrAvgXtraCyc);
+#endif
+ p -= 4;
+ put_long(p, V_regs.regs[z]);
+ }
+ }
+#if ! Use68020
+ *dstp = p;
+#endif
+}
+
+LOCALIPROC DoCodeMOVEMApRL(void)
+{
+ /* MOVEM mem to reg 01001100111011rrr */
+ si4b z;
+ ui5r regmask = nextiword_nm();
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r p = *dstp;
+
+ for (z = 0; z < 16; ++z) {
+ if ((regmask & (1 << z)) != 0) {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (8 * kCycleScale + 2 * RdAvgXtraCyc);
+#endif
+ V_regs.regs[z] = get_long(p);
+ p += 4;
+ }
+ }
+ *dstp = p;
+}
+
+LOCALPROC my_reg_call SetCCRforAddX(ui5r dstvalue, ui5r srcvalue,
+ ui5r result)
+{
+ ZFLG &= Bool2Bit(result == 0);
+
+ {
+ flagtype flgs = Bool2Bit(ui5r_MSBisSet(srcvalue));
+ flagtype flgo = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ flagtype flgsando = flgs & flgo;
+ flagtype flgsoro = flgs | flgo;
+ flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
+
+ NFLG = flgn;
+ flgn ^= 1;
+ VFLG = ((flgn | flgsoro) ^ 1) | (flgn & flgsando);
+ XFLG = CFLG = flgsando | (flgn & flgsoro);
+ }
+
+ ArgSetDstValue(result);
+}
+
+LOCALIPROC DoCodeAddXB(void)
+{
+ NeedDefaultLazyAllFlags();
+
+ {
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r srcvalue = V_regs.SrcVal;
+ ui5r result = ui5r_FromSByte(XFLG + dstvalue + srcvalue);
+
+ SetCCRforAddX(dstvalue, srcvalue, result);
+ }
+}
+
+LOCALIPROC DoCodeAddXW(void)
+{
+ if ((kLazyFlagsDefault != V_regs.LazyFlagKind)
+ || (kLazyFlagsDefault != V_regs.LazyXFlagKind))
+ {
+ NeedDefaultLazyAllFlags();
+ }
+
+ {
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r srcvalue = V_regs.SrcVal;
+ ui5r result = ui5r_FromSWord(XFLG + dstvalue + srcvalue);
+
+ SetCCRforAddX(dstvalue, srcvalue, result);
+ }
+}
+
+LOCALIPROC DoCodeAddXL(void)
+{
+ if (kLazyFlagsAddL == V_regs.LazyFlagKind) {
+ ui5r src = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+ ui5r result = ui5r_FromULong(dst + src);
+
+ ZFLG = Bool2Bit(result == 0);
+ XFLG = Bool2Bit(result < src);
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ } else
+ if ((kLazyFlagsDefault == V_regs.LazyFlagKind)
+ && (kLazyFlagsDefault == V_regs.LazyXFlagKind))
+ {
+ /* ok */
+ } else
+ {
+ NeedDefaultLazyAllFlags();
+ }
+
+ {
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r srcvalue = V_regs.SrcVal;
+ ui5r result = ui5r_FromSLong(XFLG + dstvalue + srcvalue);
+
+ SetCCRforAddX(dstvalue, srcvalue, result);
+ }
+}
+
+LOCALPROC my_reg_call SetCCRforSubX(ui5r dstvalue, ui5r srcvalue,
+ ui5r result)
+{
+ ZFLG &= Bool2Bit(result == 0);
+
+ {
+ flagtype flgs = Bool2Bit(ui5r_MSBisSet(srcvalue));
+ flagtype flgo = Bool2Bit(ui5r_MSBisSet(dstvalue)) ^ 1;
+ flagtype flgsando = flgs & flgo;
+ flagtype flgsoro = flgs | flgo;
+ flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
+
+ NFLG = flgn;
+ VFLG = ((flgn | flgsoro) ^ 1) | (flgn & flgsando);
+ XFLG = CFLG = flgsando | (flgn & flgsoro);
+ }
+
+ ArgSetDstValue(result);
+}
+
+LOCALIPROC DoCodeSubXB(void)
+{
+ NeedDefaultLazyAllFlags();
+
+ {
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r srcvalue = V_regs.SrcVal;
+ ui5r result = ui5r_FromSByte(dstvalue - srcvalue - XFLG);
+
+ SetCCRforSubX(dstvalue, srcvalue, result);
+ }
+}
+
+LOCALIPROC DoCodeSubXW(void)
+{
+ if ((kLazyFlagsDefault != V_regs.LazyFlagKind)
+ || (kLazyFlagsDefault != V_regs.LazyXFlagKind))
+ {
+ NeedDefaultLazyAllFlags();
+ }
+
+ {
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r srcvalue = V_regs.SrcVal;
+ ui5r result = ui5r_FromSWord(dstvalue - srcvalue - XFLG);
+
+ SetCCRforSubX(dstvalue, srcvalue, result);
+ }
+}
+
+LOCALIPROC DoCodeSubXL(void)
+{
+ if (kLazyFlagsSubL == V_regs.LazyFlagKind) {
+ ui5r src = V_regs.LazyFlagArgSrc;
+ ui5r dst = V_regs.LazyFlagArgDst;
+ ui5r result = ui5r_FromSLong(dst - src);
+
+ ZFLG = Bool2Bit(result == 0);
+ XFLG = Bool2Bit(((ui5b)dst) < ((ui5b)src));
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ } else
+ if ((kLazyFlagsDefault == V_regs.LazyFlagKind)
+ && (kLazyFlagsDefault == V_regs.LazyXFlagKind))
+ {
+ /* ok */
+ } else
+ {
+ NeedDefaultLazyAllFlags();
+ }
+
+ {
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r srcvalue = V_regs.SrcVal;
+ ui5r result = ui5r_FromSLong(dstvalue - srcvalue - XFLG);
+
+ SetCCRforSubX(dstvalue, srcvalue, result);
+ }
+}
+
+LOCALPROC my_reg_call DoCodeNullShift(ui5r dstvalue)
+{
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALPROC DoCodeOverAsl(ui5r dstvalue)
+{
+ XFLG = CFLG = 0;
+ VFLG = Bool2Bit(0 != dstvalue);
+ ZFLG = 1;
+ NFLG = 0;
+
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(0);
+}
+
+LOCALPROC my_reg_call DoCodeMaxAsr(ui5r dstvalue)
+{
+ XFLG = CFLG = dstvalue & 1;
+ VFLG = Bool2Bit(0 != dstvalue);
+ ZFLG = 1;
+ NFLG = 0;
+
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(0);
+}
+
+LOCALIPROC DoCodeAslB(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (cnt >= 8) {
+ if (cnt == 8) {
+ DoCodeMaxAsr(dstvalue);
+ } else {
+ DoCodeOverAsl(dstvalue);
+ }
+ } else {
+ ui5r result = ui5r_FromSByte(dstvalue << cnt);
+
+ V_regs.LazyFlagKind = kLazyFlagsAslB;
+ V_regs.LazyFlagArgSrc = cnt;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ V_regs.LazyXFlagKind = kLazyFlagsAslB;
+ V_regs.LazyXFlagArgSrc = cnt;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+ }
+ }
+}
+
+LOCALIPROC DoCodeAslW(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (cnt >= 16) {
+ if (cnt == 16) {
+ DoCodeMaxAsr(dstvalue);
+ } else {
+ DoCodeOverAsl(dstvalue);
+ }
+ } else {
+ ui5r result = ui5r_FromSWord(dstvalue << cnt);
+
+ V_regs.LazyFlagKind = kLazyFlagsAslW;
+ V_regs.LazyFlagArgSrc = cnt;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ V_regs.LazyXFlagKind = kLazyFlagsAslW;
+ V_regs.LazyXFlagArgSrc = cnt;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+ }
+ }
+}
+
+LOCALIPROC DoCodeAslL(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (cnt >= 32) {
+ if (cnt == 32) {
+ DoCodeMaxAsr(dstvalue);
+ } else {
+ DoCodeOverAsl(dstvalue);
+ }
+ } else {
+ ui5r result = ui5r_FromSLong(dstvalue << cnt);
+
+ V_regs.LazyFlagKind = kLazyFlagsAslL;
+ V_regs.LazyFlagArgSrc = cnt;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ V_regs.LazyXFlagKind = kLazyFlagsAslL;
+ V_regs.LazyXFlagArgSrc = cnt;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+ }
+ }
+}
+
+LOCALPROC DoCodeOverShift(void)
+{
+ XFLG = CFLG = 0;
+ ZFLG = 1;
+ NFLG = 0;
+ VFLG = 0;
+
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(0);
+}
+
+LOCALPROC DoCodeOverShiftN(void)
+{
+ NFLG = 1;
+ VFLG = 0;
+ CFLG = 1;
+ XFLG = CFLG;
+ ZFLG = 0;
+
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(~ 0);
+}
+
+LOCALPROC DoCodeOverAShift(ui5r dstvalue)
+{
+ if (ui5r_MSBisSet(dstvalue)) {
+ DoCodeOverShiftN();
+ } else {
+ DoCodeOverShift();
+ }
+}
+
+LOCALIPROC DoCodeAsrB(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (cnt >= 8) {
+ DoCodeOverAShift(dstvalue);
+ } else {
+ ui5r result = Ui5rASR(dstvalue, cnt);
+
+ V_regs.LazyFlagKind = kLazyFlagsAsrB;
+ V_regs.LazyFlagArgSrc = cnt;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ V_regs.LazyXFlagKind = kLazyFlagsAsrB;
+ V_regs.LazyXFlagArgSrc = cnt;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+ }
+ }
+}
+
+LOCALIPROC DoCodeAsrW(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (cnt >= 16) {
+ DoCodeOverAShift(dstvalue);
+ } else {
+ ui5r result = Ui5rASR(dstvalue, cnt);
+
+ V_regs.LazyFlagKind = kLazyFlagsAsrW;
+ V_regs.LazyFlagArgSrc = cnt;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ V_regs.LazyXFlagKind = kLazyFlagsAsrW;
+ V_regs.LazyXFlagArgSrc = cnt;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+ }
+ }
+}
+
+LOCALIPROC DoCodeAsrL(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (cnt >= 32) {
+ DoCodeOverAShift(dstvalue);
+ } else {
+ ui5r result = Ui5rASR(dstvalue, cnt);
+
+ V_regs.LazyFlagKind = kLazyFlagsAsrL;
+ V_regs.LazyFlagArgSrc = cnt;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ V_regs.LazyXFlagKind = kLazyFlagsAsrL;
+ V_regs.LazyXFlagArgSrc = cnt;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+ }
+ }
+}
+
+LOCALPROC my_reg_call DoCodeMaxLslShift(ui5r dstvalue)
+{
+ XFLG = CFLG = dstvalue & 1;
+ ZFLG = 1;
+ NFLG = 0;
+ VFLG = 0;
+
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(0);
+}
+
+LOCALIPROC DoCodeLslB(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (cnt >= 8) {
+ if (cnt == 8) {
+ DoCodeMaxLslShift(dstvalue);
+ } else {
+ DoCodeOverShift();
+ }
+ } else {
+ CFLG = (dstvalue >> (8 - cnt)) & 1;
+ dstvalue = dstvalue << cnt;
+ dstvalue = ui5r_FromSByte(dstvalue);
+
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+ XFLG = CFLG;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(dstvalue);
+ }
+ }
+}
+
+LOCALIPROC DoCodeLslW(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (cnt >= 16) {
+ if (cnt == 16) {
+ DoCodeMaxLslShift(dstvalue);
+ } else {
+ DoCodeOverShift();
+ }
+ } else {
+ CFLG = (dstvalue >> (16 - cnt)) & 1;
+ dstvalue = dstvalue << cnt;
+ dstvalue = ui5r_FromSWord(dstvalue);
+
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+ XFLG = CFLG;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(dstvalue);
+ }
+ }
+}
+
+LOCALIPROC DoCodeLslL(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (cnt >= 32) {
+ if (cnt == 32) {
+ DoCodeMaxLslShift(dstvalue);
+ } else {
+ DoCodeOverShift();
+ }
+ } else {
+ CFLG = (dstvalue >> (32 - cnt)) & 1;
+ dstvalue = dstvalue << cnt;
+ dstvalue = ui5r_FromSLong(dstvalue);
+
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+ XFLG = CFLG;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(dstvalue);
+ }
+ }
+}
+
+LOCALIPROC DoCodeLsrB(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else if (cnt > 32) {
+ DoCodeOverShift();
+ } else {
+ dstvalue = ui5r_FromUByte(dstvalue);
+ dstvalue = dstvalue >> (cnt - 1);
+ CFLG = XFLG = (dstvalue & 1);
+ dstvalue = dstvalue >> 1;
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = 0 /* Bool2Bit(ui5r_MSBisSet(dstvalue)) */;
+ /* if cnt != 0, always false */
+ VFLG = 0;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALIPROC DoCodeLsrW(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else if (cnt > 32) {
+ DoCodeOverShift();
+ } else {
+ dstvalue = ui5r_FromUWord(dstvalue);
+ dstvalue = dstvalue >> (cnt - 1);
+ CFLG = XFLG = (dstvalue & 1);
+ dstvalue = dstvalue >> 1;
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = 0 /* Bool2Bit(ui5r_MSBisSet(dstvalue)) */;
+ /* if cnt != 0, always false */
+ VFLG = 0;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALIPROC DoCodeLsrL(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else if (cnt > 32) {
+ DoCodeOverShift();
+ } else {
+ dstvalue = ui5r_FromULong(dstvalue);
+ dstvalue = dstvalue >> (cnt - 1);
+ CFLG = XFLG = (dstvalue & 1);
+ dstvalue = dstvalue >> 1;
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = 0 /* Bool2Bit(ui5r_MSBisSet(dstvalue)) */;
+ /* if cnt != 0, always false */
+ VFLG = 0;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALFUNC ui5r DecodeGetSrcSetDstValueDfltFlags_nm(void)
+{
+ NeedDefaultLazyAllFlags();
+
+ return DecodeGetSrcSetDstValue();
+}
+
+LOCALPROC my_reg_call DoCodeNullXShift(ui5r dstvalue)
+{
+ CFLG = XFLG;
+
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeRxlB(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullXShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ for (; cnt; --cnt) {
+ CFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ dstvalue = (dstvalue << 1) | XFLG;
+ dstvalue = ui5r_FromSByte(dstvalue);
+ XFLG = CFLG;
+ }
+
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALIPROC DoCodeRxlW(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullXShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ for (; cnt; --cnt) {
+ CFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ dstvalue = (dstvalue << 1) | XFLG;
+ dstvalue = ui5r_FromSWord(dstvalue);
+ XFLG = CFLG;
+ }
+
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALIPROC DoCodeRxlL(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullXShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ for (; cnt; --cnt) {
+ CFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ dstvalue = (dstvalue << 1) | XFLG;
+ dstvalue = ui5r_FromSLong(dstvalue);
+ XFLG = CFLG;
+ }
+
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALIPROC DoCodeRxrB(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullXShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ dstvalue = ui5r_FromUByte(dstvalue);
+ for (; cnt; --cnt) {
+ CFLG = dstvalue & 1;
+ dstvalue = (dstvalue >> 1) | (((ui5r)XFLG) << 7);
+ XFLG = CFLG;
+ }
+ dstvalue = ui5r_FromSByte(dstvalue);
+
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALIPROC DoCodeRxrW(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullXShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ dstvalue = ui5r_FromUWord(dstvalue);
+ for (; cnt; --cnt) {
+ CFLG = dstvalue & 1;
+ dstvalue = (dstvalue >> 1) | (((ui5r)XFLG) << 15);
+ XFLG = CFLG;
+ }
+ dstvalue = ui5r_FromSWord(dstvalue);
+
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALIPROC DoCodeRxrL(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+ if (0 == cnt) {
+ DoCodeNullXShift(dstvalue);
+ } else {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ dstvalue = ui5r_FromULong(dstvalue);
+ for (; cnt; --cnt) {
+ CFLG = dstvalue & 1;
+ dstvalue = (dstvalue >> 1) | (((ui5r)XFLG) << 31);
+ XFLG = CFLG;
+ }
+ dstvalue = ui5r_FromSLong(dstvalue);
+
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALIPROC DoCodeRolB(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+ cnt &= 7;
+ if (0 != cnt) {
+ ui3b dst = (ui3b)dstvalue;
+
+ dst = (dst >> (8 - cnt))
+ | ((dst & ((1 << (8 - cnt)) - 1))
+ << cnt);
+
+ dstvalue = (ui5r)(si5r)(si3b)dst;
+ }
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+ CFLG = (dstvalue & 1);
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALIPROC DoCodeRolW(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+ cnt &= 15;
+ if (0 != cnt) {
+ ui4b dst = (ui4b)dstvalue;
+
+ dst = (dst >> (16 - cnt))
+ | ((dst & ((1 << (16 - cnt)) - 1))
+ << cnt);
+
+ dstvalue = (ui5r)(si5r)(si4b)dst;
+ }
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+ CFLG = (dstvalue & 1);
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALIPROC DoCodeRolL(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+ cnt &= 31;
+ if (0 != cnt) {
+ ui5b dst = (ui5b)dstvalue;
+
+ dst = (dst >> (32 - cnt))
+ | ((dst & ((1 << (32 - cnt)) - 1))
+ << cnt);
+
+ dstvalue = (ui5r)(si5r)(si5b)dst;
+ }
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+ CFLG = (dstvalue & 1);
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALIPROC DoCodeRorB(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+ cnt &= 7;
+ if (0 != cnt) {
+ ui3b dst = (ui3b)dstvalue;
+
+ dst = (dst >> cnt)
+ | ((dst & ((1 << cnt) - 1))
+ << (8 - cnt));
+
+ dstvalue = (ui5r)(si5r)(si3b)dst;
+ }
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+ CFLG = NFLG;
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALIPROC DoCodeRorW(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+ cnt &= 15;
+ if (0 != cnt) {
+ ui4b dst = (ui4b)dstvalue;
+
+ dst = (dst >> cnt)
+ | ((dst & ((1 << cnt) - 1))
+ << (16 - cnt));
+
+ dstvalue = (ui5r)(si5r)(si4b)dst;
+ }
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+ CFLG = NFLG;
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+LOCALIPROC DoCodeRorL(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+ ui5r cnt = V_regs.SrcVal & 63;
+
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (cnt * 2 * kCycleScale);
+#endif
+
+ if (0 == cnt) {
+ DoCodeNullShift(dstvalue);
+ } else {
+ cnt &= 31;
+ if (0 != cnt) {
+ ui5b dst = (ui5b)dstvalue;
+
+ dst = (dst >> cnt)
+ | ((dst & ((1 << cnt) - 1))
+ << (32 - cnt));
+
+ dstvalue = (ui5r)(si5r)(si5b)dst;
+ }
+ ZFLG = Bool2Bit(dstvalue == 0);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = 0;
+ CFLG = NFLG;
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ ArgSetDstValue(dstvalue);
+ }
+}
+
+
+#if UseLazyZ
+LOCALPROC WillSetZFLG(void)
+{
+ if (kLazyFlagsZSet == V_regs.LazyFlagKind) {
+ /* ok */
+ } else if (kLazyFlagsDefault == V_regs.LazyFlagKind) {
+ /* also ok */
+ } else {
+ V_regs.LazyFlagZSavedKind = V_regs.LazyFlagKind;
+ V_regs.LazyFlagKind = kLazyFlagsZSet;
+ }
+}
+#else
+#define WillSetZFLG NeedDefaultLazyAllFlags
+#endif
+
+LOCALINLINEFUNC ui5r DecodeGetSrcGetDstValueSetZ(void)
+{
+ WillSetZFLG();
+
+ return DecodeGetSrcSetDstValue();
+}
+
+LOCALIPROC DoCodeBTstB(void)
+{
+ ui5r dstvalue = DecodeGetSrcGetDstValueSetZ();
+ ui5r srcvalue = V_regs.SrcVal & 7;
+
+ ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
+}
+
+LOCALIPROC DoCodeBTstL(void)
+{
+ ui5r dstvalue = DecodeGetSrcGetDstValueSetZ();
+ ui5r srcvalue = V_regs.SrcVal & 31;
+
+ ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
+}
+
+LOCALINLINEFUNC ui5r DecodeGetSrcSetDstValueSetZ(void)
+{
+ WillSetZFLG();
+
+ return DecodeGetSrcSetDstValue();
+}
+
+LOCALIPROC DoCodeBChgB(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValueSetZ();
+ ui5r srcvalue = V_regs.SrcVal & 7;
+
+ ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
+
+ dstvalue ^= (1 << srcvalue);
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeBChgL(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValueSetZ();
+ ui5r srcvalue = V_regs.SrcVal & 31;
+
+ ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
+
+ dstvalue ^= (1 << srcvalue);
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeBClrB(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValueSetZ();
+ ui5r srcvalue = V_regs.SrcVal & 7;
+
+ ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
+
+ dstvalue &= ~ (1 << srcvalue);
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeBClrL(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValueSetZ();
+ ui5r srcvalue = V_regs.SrcVal & 31;
+
+ ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
+
+ dstvalue &= ~ (1 << srcvalue);
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeBSetB(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValueSetZ();
+ ui5r srcvalue = V_regs.SrcVal & 7;
+
+ ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
+
+ dstvalue |= (1 << srcvalue);
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeBSetL(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValueSetZ();
+ ui5r srcvalue = V_regs.SrcVal & 31;
+
+ ZFLG = ((dstvalue >> srcvalue) ^ 1) & 1;
+
+ dstvalue |= (1 << srcvalue);
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeAnd(void)
+{
+ /* DoBinOpAnd(DecodeI_xxxxxxxxssmmmrrr()); */
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+
+ dstvalue &= V_regs.SrcVal;
+ /*
+ don't need to extend, since excess high
+ bits all the same as desired high bit.
+ */
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeOr(void)
+{
+ /* DoBinOr(DecodeI_xxxxxxxxssmmmrrr()); */
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+
+ dstvalue |= V_regs.SrcVal;
+ /*
+ don't need to extend, since excess high
+ bits all the same as desired high bit.
+ */
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeEor(void)
+{
+ /* Eor 1011ddd1ssmmmrrr */
+ /* DoBinOpEor(DecodeDEa_xxxxdddxssmmmrrr()); */
+ ui5r dstvalue = DecodeGetSrcSetDstValue();
+
+ dstvalue ^= V_regs.SrcVal;
+ /*
+ don't need to extend, since excess high
+ bits all the same as desired high bit.
+ */
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeNot(void)
+{
+ /* Not 01000110ssmmmrrr */
+ ui5r dstvalue = DecodeGetSetDstValue();
+
+ dstvalue = ~ dstvalue;
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALPROC DoCodeScc_t(void)
+{
+#if WantCloserCyc
+ if (kAMdRegB == V_regs.CurDecOpY.v[1].AMd) {
+ V_MaxCyclesToGo -= (2 * kCycleScale);
+ }
+#endif
+ DecodeSetDstValue(0xff);
+}
+
+LOCALPROC DoCodeScc_f(void)
+{
+ DecodeSetDstValue(0);
+}
+
+LOCALIPROC DoCodeScc(void)
+{
+ /* Scc 0101cccc11mmmrrr */
+ cctrue(DoCodeScc_t, DoCodeScc_f);
+}
+
+LOCALIPROC DoCodeEXTL(void)
+{
+ /* EXT.L */
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r dstvalue = ui5r_FromSWord(*dstp);
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ *dstp = dstvalue;
+}
+
+LOCALIPROC DoCodeEXTW(void)
+{
+ /* EXT.W */
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r dstvalue = ui5r_FromSByte(*dstp);
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+#if LittleEndianUnaligned
+ *(ui4b *)dstp = dstvalue;
+#else
+ *dstp = (*dstp & ~ 0xffff) | (dstvalue & 0xffff);
+#endif
+}
+
+LOCALIPROC DoCodeNegB(void)
+{
+ ui5r dstvalue = DecodeGetSetDstValue();
+ ui5r result = ui5r_FromSByte(0 - dstvalue);
+
+ V_regs.LazyFlagKind = kLazyFlagsNegB;
+ V_regs.LazyFlagArgDst = dstvalue;
+ V_regs.LazyXFlagKind = kLazyFlagsNegB;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+}
+
+LOCALIPROC DoCodeNegW(void)
+{
+ ui5r dstvalue = DecodeGetSetDstValue();
+ ui5r result = ui5r_FromSWord(0 - dstvalue);
+
+ V_regs.LazyFlagKind = kLazyFlagsNegW;
+ V_regs.LazyFlagArgDst = dstvalue;
+ V_regs.LazyXFlagKind = kLazyFlagsNegW;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+}
+
+LOCALIPROC DoCodeNegL(void)
+{
+ ui5r dstvalue = DecodeGetSetDstValue();
+ ui5r result = ui5r_FromSLong(0 - dstvalue);
+
+ V_regs.LazyFlagKind = kLazyFlagsNegL;
+ V_regs.LazyFlagArgDst = dstvalue;
+ V_regs.LazyXFlagKind = kLazyFlagsNegL;
+ V_regs.LazyXFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ ArgSetDstValue(result);
+}
+
+LOCALPROC my_reg_call SetCCRforNegX(ui5r dstvalue, ui5r result)
+{
+ ZFLG &= Bool2Bit(result == 0);
+
+ {
+ flagtype flgs = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ flagtype flgn = Bool2Bit(ui5r_MSBisSet(result));
+
+ NFLG = flgn;
+ VFLG = flgs & flgn;
+ XFLG = CFLG = flgs | flgn;
+ }
+
+ ArgSetDstValue(result);
+}
+
+LOCALIPROC DoCodeNegXB(void)
+{
+ NeedDefaultLazyAllFlags();
+
+ {
+ ui5r dstvalue = DecodeGetSetDstValue();
+ ui5r result = ui5r_FromSByte(0 - (XFLG + dstvalue));
+
+ SetCCRforNegX(dstvalue, result);
+ }
+}
+
+LOCALIPROC DoCodeNegXW(void)
+{
+ if ((kLazyFlagsDefault != V_regs.LazyFlagKind)
+ || (kLazyFlagsDefault != V_regs.LazyXFlagKind))
+ {
+ NeedDefaultLazyAllFlags();
+ }
+
+ {
+ ui5r dstvalue = DecodeGetSetDstValue();
+ ui5r result = ui5r_FromSWord(0 - (XFLG + dstvalue));
+
+ SetCCRforNegX(dstvalue, result);
+ }
+}
+
+LOCALIPROC DoCodeNegXL(void)
+{
+ if (kLazyFlagsNegL == V_regs.LazyFlagKind) {
+ NeedDefaultLazyFlagsNegL();
+ } else
+ if ((kLazyFlagsDefault == V_regs.LazyFlagKind)
+ && (kLazyFlagsDefault == V_regs.LazyXFlagKind))
+ {
+ /* ok */
+ } else
+ {
+ NeedDefaultLazyAllFlags();
+ }
+
+ {
+ ui5r dstvalue = DecodeGetSetDstValue();
+ ui5r result = ui5r_FromSLong(0 - (XFLG + dstvalue));
+
+ SetCCRforNegX(dstvalue, result);
+ }
+}
+
+LOCALIPROC DoCodeMulU(void)
+{
+ /* MulU 1100ddd011mmmrrr */
+ ui5r srcvalue = DecodeGetSrcValue();
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r dstvalue = *dstp;
+
+ dstvalue = ui5r_FromSLong(ui5r_FromUWord(dstvalue)
+ * ui5r_FromUWord(srcvalue));
+#if WantCloserCyc
+ {
+ ui5r v = srcvalue;
+
+ while (v != 0) {
+ if ((v & 1) != 0) {
+ V_MaxCyclesToGo -= (2 * kCycleScale);
+ }
+ v >>= 1;
+ }
+ }
+#endif
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ *dstp = dstvalue;
+}
+
+LOCALIPROC DoCodeMulS(void)
+{
+ /* MulS 1100ddd111mmmrrr */
+ ui5r srcvalue = DecodeGetSrcValue();
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r dstvalue = *dstp;
+
+ dstvalue = ui5r_FromSLong((si5b)(si4b)dstvalue
+ * (si5b)(si4b)srcvalue);
+#if WantCloserCyc
+ {
+ ui5r v = (srcvalue << 1);
+
+ while (v != 0) {
+ if ((v & 1) != ((v >> 1) & 1)) {
+ V_MaxCyclesToGo -= (2 * kCycleScale);
+ }
+ v >>= 1;
+ }
+ }
+#endif
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ *dstp = dstvalue;
+}
+
+LOCALIPROC DoCodeDivU(void)
+{
+ /* DivU 1000ddd011mmmrrr */
+ ui5r srcvalue = DecodeGetSrcValue();
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r dstvalue = *dstp;
+
+ if (srcvalue == 0) {
+#if WantCloserCyc
+ V_MaxCyclesToGo -=
+ (38 * kCycleScale + 3 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
+#endif
+ Exception(5);
+#if m68k_logExceptions
+ dbglog_WriteNote("*** zero devide exception");
+#endif
+ } else {
+ ui5b newv = (ui5b)dstvalue / (ui5b)(ui4b)srcvalue;
+ ui5b rem = (ui5b)dstvalue % (ui5b)(ui4b)srcvalue;
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (133 * kCycleScale);
+#endif
+ if (newv > 0xffff) {
+ NeedDefaultLazyAllFlags();
+
+ VFLG = NFLG = 1;
+ CFLG = 0;
+ } else {
+ VFLG = CFLG = 0;
+ ZFLG = Bool2Bit(((si4b)(newv)) == 0);
+ NFLG = Bool2Bit(((si4b)(newv)) < 0);
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ newv = (newv & 0xffff) | ((ui5b)rem << 16);
+ dstvalue = newv;
+ }
+ }
+
+ *dstp = dstvalue;
+}
+
+LOCALIPROC DoCodeDivS(void)
+{
+ /* DivS 1000ddd111mmmrrr */
+ ui5r srcvalue = DecodeGetSrcValue();
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r dstvalue = *dstp;
+
+ if (srcvalue == 0) {
+#if WantCloserCyc
+ V_MaxCyclesToGo -=
+ (38 * kCycleScale + 3 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
+#endif
+ Exception(5);
+#if m68k_logExceptions
+ dbglog_WriteNote("*** zero devide exception");
+#endif
+ } else {
+ si5b newv = (si5b)dstvalue / (si5b)(si4b)srcvalue;
+ ui4b rem = (si5b)dstvalue % (si5b)(si4b)srcvalue;
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (150 * kCycleScale);
+#endif
+ if (((newv & 0xffff8000) != 0) &&
+ ((newv & 0xffff8000) != 0xffff8000))
+ {
+ NeedDefaultLazyAllFlags();
+
+ VFLG = NFLG = 1;
+ CFLG = 0;
+ } else {
+ if (((si4b)rem < 0) != ((si5b)dstvalue < 0)) {
+ rem = - rem;
+ }
+ VFLG = CFLG = 0;
+ ZFLG = Bool2Bit(((si4b)(newv)) == 0);
+ NFLG = Bool2Bit(((si4b)(newv)) < 0);
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ newv = (newv & 0xffff) | ((ui5b)rem << 16);
+ dstvalue = newv;
+ }
+ }
+
+ *dstp = dstvalue;
+}
+
+LOCALIPROC DoCodeExg(void)
+{
+ /* Exg dd 1100ddd101000rrr, opsize = 4 */
+ /* Exg aa 1100ddd101001rrr, opsize = 4 */
+ /* Exg da 1100ddd110001rrr, opsize = 4 */
+
+ ui5r srcreg = V_regs.CurDecOpY.v[0].ArgDat;
+ ui5r *srcp = &V_regs.regs[srcreg];
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r srcvalue = *srcp;
+
+ *srcp = *dstp;
+ *dstp = srcvalue;
+}
+
+LOCALIPROC DoCodeMoveEaCR(void)
+{
+ /* 0100010011mmmrrr */
+ m68k_setCR(DecodeGetDstValue());
+}
+
+LOCALPROC DoPrivilegeViolation(void)
+{
+#if WantCloserCyc
+ V_MaxCyclesToGo += GetDcoCycles(V_regs.CurDecOp);
+ V_MaxCyclesToGo -=
+ (34 * kCycleScale + 4 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
+#endif
+ BackupPC();
+ Exception(8);
+#if m68k_logExceptions
+ dbglog_WriteNote("*** Privilege Violation exception");
+#endif
+}
+
+LOCALIPROC DoCodeMoveSREa(void)
+{
+ /* Move from SR 0100000011mmmrrr */
+#if Use68020
+ if (0 == V_regs.s) {
+ DoPrivilegeViolation();
+ } else
+#endif
+ {
+ DecodeSetDstValue(m68k_getSR());
+ }
+}
+
+LOCALIPROC DoCodeMoveEaSR(void)
+{
+ /* 0100011011mmmrrr */
+ if (0 == V_regs.s) {
+ DoPrivilegeViolation();
+ } else {
+ m68k_setSR(DecodeGetDstValue());
+ }
+}
+
+LOCALIPROC DoCodeOrISR(void)
+{
+ if (0 == V_regs.s) {
+ DoPrivilegeViolation();
+ } else {
+ V_regs.SrcVal = nextiword_nm();
+
+ m68k_setSR(m68k_getSR() | V_regs.SrcVal);
+ }
+}
+
+LOCALIPROC DoCodeAndISR(void)
+{
+ if (0 == V_regs.s) {
+ DoPrivilegeViolation();
+ } else {
+ V_regs.SrcVal = nextiword_nm();
+
+ m68k_setSR(m68k_getSR() & V_regs.SrcVal);
+ }
+}
+
+LOCALIPROC DoCodeEorISR(void)
+{
+ if (0 == V_regs.s) {
+ DoPrivilegeViolation();
+ } else {
+ V_regs.SrcVal = nextiword_nm();
+
+ m68k_setSR(m68k_getSR() ^ V_regs.SrcVal);
+ }
+}
+
+LOCALIPROC DoCodeOrICCR(void)
+{
+ V_regs.SrcVal = nextiword_nm();
+
+ m68k_setCR(m68k_getCR() | V_regs.SrcVal);
+}
+
+LOCALIPROC DoCodeAndICCR(void)
+{
+ V_regs.SrcVal = nextiword_nm();
+
+ m68k_setCR(m68k_getCR() & V_regs.SrcVal);
+}
+
+LOCALIPROC DoCodeEorICCR(void)
+{
+ V_regs.SrcVal = nextiword_nm();
+
+ m68k_setCR(m68k_getCR() ^ V_regs.SrcVal);
+}
+
+LOCALIPROC DoCodeMOVEMApRW(void)
+{
+ /* MOVEM mem to reg 01001100110011rrr */
+ si4b z;
+ ui5r regmask = nextiword_nm();
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r p = *dstp;
+
+ for (z = 0; z < 16; ++z) {
+ if ((regmask & (1 << z)) != 0) {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (4 * kCycleScale + RdAvgXtraCyc);
+#endif
+ V_regs.regs[z] = get_word(p);
+ p += 2;
+ }
+ }
+ *dstp = p;
+}
+
+LOCALIPROC DoCodeMOVEMRmMW(void)
+{
+ /* MOVEM reg to mem 01001000110100rrr */
+ si4b z;
+ ui5r regmask = nextiword_nm();
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r p = *dstp;
+
+#if Use68020
+ {
+ int n = 0;
+
+ for (z = 0; z < 16; ++z) {
+ if ((regmask & (1 << z)) != 0) {
+ n++;
+ }
+ }
+ *dstp = p - n * 2;
+ }
+#endif
+ for (z = 16; --z >= 0; ) {
+ if ((regmask & (1 << (15 - z))) != 0) {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (4 * kCycleScale + WrAvgXtraCyc);
+#endif
+ p -= 2;
+ put_word(p, V_regs.regs[z]);
+ }
+ }
+#if ! Use68020
+ *dstp = p;
+#endif
+}
+
+LOCALIPROC DoCodeMOVEMrmW(void)
+{
+ /* MOVEM reg to mem 010010001ssmmmrrr */
+ si4b z;
+ ui5r regmask = nextiword_nm();
+ ui5r p = DecodeDst();
+
+ for (z = 0; z < 16; ++z) {
+ if ((regmask & (1 << z)) != 0) {
+#if WantCloserCyc
+ V_MaxCyclesToGo -=
+ (4 * kCycleScale + WrAvgXtraCyc);
+#endif
+ put_word(p, V_regs.regs[z]);
+ p += 2;
+ }
+ }
+}
+
+LOCALIPROC DoCodeMOVEMrmL(void)
+{
+ /* MOVEM reg to mem 010010001ssmmmrrr */
+ si4b z;
+ ui5r regmask = nextiword_nm();
+ ui5r p = DecodeDst();
+
+ for (z = 0; z < 16; ++z) {
+ if ((regmask & (1 << z)) != 0) {
+#if WantCloserCyc
+ V_MaxCyclesToGo -=
+ (8 * kCycleScale + 2 * WrAvgXtraCyc);
+#endif
+ put_long(p, V_regs.regs[z]);
+ p += 4;
+ }
+ }
+}
+
+LOCALIPROC DoCodeMOVEMmrW(void)
+{
+ /* MOVEM mem to reg 0100110011smmmrrr */
+ si4b z;
+ ui5r regmask = nextiword_nm();
+ ui5r p = DecodeDst();
+
+ for (z = 0; z < 16; ++z) {
+ if ((regmask & (1 << z)) != 0) {
+#if WantCloserCyc
+ V_MaxCyclesToGo -=
+ (4 * kCycleScale + RdAvgXtraCyc);
+#endif
+ V_regs.regs[z] = get_word(p);
+ p += 2;
+ }
+ }
+}
+
+LOCALIPROC DoCodeMOVEMmrL(void)
+{
+ /* MOVEM mem to reg 0100110011smmmrrr */
+ si4b z;
+ ui5r regmask = nextiword_nm();
+ ui5r p = DecodeDst();
+
+ for (z = 0; z < 16; ++z) {
+ if ((regmask & (1 << z)) != 0) {
+#if WantCloserCyc
+ V_MaxCyclesToGo -=
+ (8 * kCycleScale + 2 * RdAvgXtraCyc);
+#endif
+ V_regs.regs[z] = get_long(p);
+ p += 4;
+ }
+ }
+}
+
+LOCALIPROC DoCodeAbcd(void)
+{
+ /* ABCD r 1100ddd100000rrr */
+ /* ABCD m 1100ddd100001rrr */
+
+ ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
+ ui5r srcvalue = V_regs.SrcVal;
+
+ {
+ /* if (V_regs.opsize != 1) a bug */
+ int flgs = ui5r_MSBisSet(srcvalue);
+ int flgo = ui5r_MSBisSet(dstvalue);
+ ui4b newv_lo =
+ (srcvalue & 0xF) + (dstvalue & 0xF) + XFLG;
+ ui4b newv_hi = (srcvalue & 0xF0) + (dstvalue & 0xF0);
+ ui4b newv;
+
+ if (newv_lo > 9) {
+ newv_lo += 6;
+ }
+ newv = newv_hi + newv_lo;
+ CFLG = XFLG = Bool2Bit((newv & 0x1F0) > 0x90);
+ if (CFLG != 0) {
+ newv += 0x60;
+ }
+ dstvalue = ui5r_FromSByte(newv);
+ if (dstvalue != 0) {
+ ZFLG = 0;
+ }
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = Bool2Bit((flgs != flgo) && ((NFLG != 0) != flgo));
+ /*
+ but according to my reference book,
+ VFLG is Undefined for ABCD
+ */
+ }
+
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeSbcd(void)
+{
+ ui5r dstvalue = DecodeGetSrcSetDstValueDfltFlags_nm();
+ ui5r srcvalue = V_regs.SrcVal;
+
+ {
+ int flgs = ui5r_MSBisSet(srcvalue);
+ int flgo = ui5r_MSBisSet(dstvalue);
+ ui4b newv_lo =
+ (dstvalue & 0xF) - (srcvalue & 0xF) - XFLG;
+ ui4b newv_hi = (dstvalue & 0xF0) - (srcvalue & 0xF0);
+ ui4b newv;
+
+ if (newv_lo > 9) {
+ newv_lo -= 6;
+ newv_hi -= 0x10;
+ }
+ newv = newv_hi + (newv_lo & 0xF);
+ CFLG = XFLG = Bool2Bit((newv_hi & 0x1F0) > 0x90);
+ if (CFLG != 0) {
+ newv -= 0x60;
+ }
+ dstvalue = ui5r_FromSByte(newv);
+ if (dstvalue != 0) {
+ ZFLG = 0;
+ }
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ VFLG = Bool2Bit((flgs != flgo) && ((NFLG != 0) != flgo));
+ /*
+ but according to my reference book,
+ VFLG is Undefined for SBCD
+ */
+ }
+
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeNbcd(void)
+{
+ /* Nbcd 0100100000mmmrrr */
+ ui5r dstvalue = DecodeGetSetDstValue();
+
+ NeedDefaultLazyAllFlags();
+
+ {
+ ui4b newv_lo = - (dstvalue & 0xF) - XFLG;
+ ui4b newv_hi = - (dstvalue & 0xF0);
+ ui4b newv;
+
+ if (newv_lo > 9) {
+ newv_lo -= 6;
+ newv_hi -= 0x10;
+ }
+ newv = newv_hi + (newv_lo & 0xF);
+ CFLG = XFLG = Bool2Bit((newv_hi & 0x1F0) > 0x90);
+ if (CFLG != 0) {
+ newv -= 0x60;
+ }
+
+ dstvalue = ui5r_FromSByte(newv);
+ NFLG = Bool2Bit(ui5r_MSBisSet(dstvalue));
+ if (dstvalue != 0) {
+ ZFLG = 0;
+ }
+ }
+
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeRte(void)
+{
+ /* Rte 0100111001110011 */
+ if (0 == V_regs.s) {
+ DoPrivilegeViolation();
+ } else {
+ ui5r NewPC;
+ CPTR stackp = m68k_areg(7);
+ ui5r NewSR = get_word(stackp);
+ stackp += 2;
+ NewPC = get_long(stackp);
+ stackp += 4;
+
+#if Use68020
+ {
+ ui4b format = get_word(stackp);
+ stackp += 2;
+
+ switch ((format >> 12) & 0x0F) {
+ case 0:
+ /* ReportAbnormal("rte stack frame format 0"); */
+ break;
+ case 1:
+ ReportAbnormalID(0x0107,
+ "rte stack frame format 1");
+ NewPC = m68k_getpc() - 2;
+ /* rerun instruction */
+ break;
+ case 2:
+ ReportAbnormalID(0x0108,
+ "rte stack frame format 2");
+ stackp += 4;
+ break;
+ case 9:
+ ReportAbnormalID(0x0109,
+ "rte stack frame format 9");
+ stackp += 12;
+ break;
+ case 10:
+ ReportAbnormalID(0x010A,
+ "rte stack frame format 10");
+ stackp += 24;
+ break;
+ case 11:
+ ReportAbnormalID(0x010B,
+ "rte stack frame format 11");
+ stackp += 84;
+ break;
+ default:
+ ReportAbnormalID(0x010C,
+ "unknown rte stack frame format");
+ Exception(14);
+ return;
+ break;
+ }
+ }
+#endif
+ m68k_areg(7) = stackp;
+ m68k_setSR(NewSR);
+ m68k_setpc(NewPC);
+ }
+}
+
+LOCALIPROC DoCodeNop(void)
+{
+ /* Nop 0100111001110001 */
+}
+
+LOCALIPROC DoCodeMoveP0(void)
+{
+ /* MoveP 0000ddd1mm001aaa */
+ ui5r srcreg = V_regs.CurDecOpY.v[0].ArgDat;
+ ui5r *srcp = &V_regs.regs[srcreg];
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+
+ ui5r Displacement = nextiword_nm();
+ /* shouldn't this sign extend ? */
+ CPTR memp = *srcp + Displacement;
+
+ ui4b val = ((get_byte(memp) & 0x00FF) << 8)
+ | (get_byte(memp + 2) & 0x00FF);
+
+ *dstp =
+ (*dstp & ~ 0xffff) | (val & 0xffff);
+
+#if 0
+ if ((Displacement & 0x00008000) != 0) {
+ /* **** for testing only **** */
+ BackupPC();
+ op_illg();
+ }
+#endif
+}
+
+LOCALIPROC DoCodeMoveP1(void)
+{
+ /* MoveP 0000ddd1mm001aaa */
+ ui5r srcreg = V_regs.CurDecOpY.v[0].ArgDat;
+ ui5r *srcp = &V_regs.regs[srcreg];
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+
+ ui5r Displacement = nextiword_nm();
+ /* shouldn't this sign extend ? */
+ CPTR memp = *srcp + Displacement;
+
+ ui5b val = ((get_byte(memp) & 0x00FF) << 24)
+ | ((get_byte(memp + 2) & 0x00FF) << 16)
+ | ((get_byte(memp + 4) & 0x00FF) << 8)
+ | (get_byte(memp + 6) & 0x00FF);
+
+ *dstp = val;
+}
+
+LOCALIPROC DoCodeMoveP2(void)
+{
+ /* MoveP 0000ddd1mm001aaa */
+ ui5r srcreg = V_regs.CurDecOpY.v[0].ArgDat;
+ ui5r *srcp = &V_regs.regs[srcreg];
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+
+ ui5r Displacement = nextiword_nm();
+ /* shouldn't this sign extend ? */
+ CPTR memp = *srcp + Displacement;
+
+ si4b val = *dstp;
+
+ put_byte(memp, val >> 8);
+ put_byte(memp + 2, val);
+}
+
+LOCALIPROC DoCodeMoveP3(void)
+{
+ /* MoveP 0000ddd1mm001aaa */
+ ui5r srcreg = V_regs.CurDecOpY.v[0].ArgDat;
+ ui5r *srcp = &V_regs.regs[srcreg];
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+
+ ui5r Displacement = nextiword_nm();
+ /* shouldn't this sign extend ? */
+ CPTR memp = *srcp + Displacement;
+
+ si5b val = *dstp;
+
+ put_byte(memp, val >> 24);
+ put_byte(memp + 2, val >> 16);
+ put_byte(memp + 4, val >> 8);
+ put_byte(memp + 6, val);
+}
+
+LOCALPROC op_illg(void)
+{
+ BackupPC();
+ Exception(4);
+#if m68k_logExceptions
+ dbglog_WriteNote("*** illegal instruction exception");
+#endif
+}
+
+LOCALIPROC DoCodeChk(void)
+{
+ ui5r dstvalue = DecodeGetSrcGetDstValue();
+ ui5r srcvalue = V_regs.SrcVal;
+
+ if (ui5r_MSBisSet(srcvalue)) {
+ NeedDefaultLazyAllFlags();
+
+#if WantCloserCyc
+ V_MaxCyclesToGo -=
+ (30 * kCycleScale + 3 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
+#endif
+ NFLG = 1;
+ Exception(6);
+ } else if (((si5r)srcvalue) > ((si5r)dstvalue)) {
+ NeedDefaultLazyAllFlags();
+
+#if WantCloserCyc
+ V_MaxCyclesToGo -=
+ (30 * kCycleScale + 3 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
+#endif
+ NFLG = 0;
+ Exception(6);
+ }
+}
+
+LOCALIPROC DoCodeTrap(void)
+{
+ /* Trap 010011100100vvvv */
+ Exception(V_regs.CurDecOpY.v[1].ArgDat);
+}
+
+LOCALIPROC DoCodeTrapV(void)
+{
+ /* TrapV 0100111001110110 */
+ NeedDefaultLazyAllFlags();
+
+ if (VFLG != 0) {
+#if WantCloserCyc
+ V_MaxCyclesToGo += GetDcoCycles(V_regs.CurDecOp);
+ V_MaxCyclesToGo -=
+ (34 * kCycleScale + 4 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
+#endif
+ Exception(7);
+ }
+}
+
+LOCALIPROC DoCodeRtr(void)
+{
+ /* Rtr 0100111001110111 */
+ ui5r NewPC;
+ CPTR stackp = m68k_areg(7);
+ ui5r NewCR = get_word(stackp);
+ stackp += 2;
+ NewPC = get_long(stackp);
+ stackp += 4;
+ m68k_areg(7) = stackp;
+ m68k_setCR(NewCR);
+ m68k_setpc(NewPC);
+}
+
+LOCALIPROC DoCodeLink(void)
+{
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ CPTR stackp = m68k_areg(7);
+
+ stackp -= 4;
+ m68k_areg(7) = stackp; /* only matters if dstreg == 7 + 8 */
+ put_long(stackp, *dstp);
+ *dstp = stackp;
+ m68k_areg(7) += ui5r_FromSWord(nextiword_nm());
+}
+
+LOCALIPROC DoCodeUnlk(void)
+{
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+
+ if (dstreg != 7 + 8) {
+ ui5r src = *dstp;
+ *dstp = get_long(src);
+ m68k_areg(7) = src + 4;
+ } else {
+ /* wouldn't expect this to happen */
+ m68k_areg(7) = get_long(m68k_areg(7)) + 4;
+ }
+}
+
+LOCALIPROC DoCodeMoveRUSP(void)
+{
+ /* MOVE USP 0100111001100aaa */
+ if (0 == V_regs.s) {
+ DoPrivilegeViolation();
+ } else {
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+
+ V_regs.usp = *dstp;
+ }
+}
+
+LOCALIPROC DoCodeMoveUSPR(void)
+{
+ /* MOVE USP 0100111001101aaa */
+ if (0 == V_regs.s) {
+ DoPrivilegeViolation();
+ } else {
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+
+ *dstp = V_regs.usp;
+ }
+}
+
+LOCALIPROC DoCodeTas(void)
+{
+ /* Tas 0100101011mmmrrr */
+ ui5r dstvalue = DecodeGetSetDstValue();
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ dstvalue |= 0x80;
+
+ ArgSetDstValue(dstvalue);
+}
+
+LOCALIPROC DoCodeFdefault(void)
+{
+ BackupPC();
+ Exception(0xB);
+}
+
+LOCALPROC m68k_setstopped(void)
+{
+ /* not implemented. doesn't seemed to be used on Mac Plus */
+ Exception(4); /* fake an illegal instruction */
+#if m68k_logExceptions
+ dbglog_WriteNote("*** set stopped");
+#endif
+}
+
+LOCALIPROC DoCodeStop(void)
+{
+ /* Stop 0100111001110010 */
+ if (0 == V_regs.s) {
+ DoPrivilegeViolation();
+ } else {
+ m68k_setSR(nextiword_nm());
+ m68k_setstopped();
+ }
+}
+
+FORWARDPROC local_customreset(void);
+
+LOCALIPROC DoCodeReset(void)
+{
+ /* Reset 0100111001100000 */
+ if (0 == V_regs.s) {
+ DoPrivilegeViolation();
+ } else {
+ local_customreset();
+ }
+}
+
+#if Use68020
+LOCALIPROC DoCodeCallMorRtm(void)
+{
+ /* CALLM or RTM 0000011011mmmrrr */
+ ReportAbnormalID(0x010D, "CALLM or RTM instruction");
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoCodeMoveCCREa(void)
+{
+ /* Move from CCR 0100001011mmmrrr */
+ DecodeSetDstValue(m68k_getCR());
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoCodeBraL(void)
+{
+ /* Bra 0110ccccnnnnnnnn */
+ si5r offset = ((si5b)(ui5b)nextilong()) - 4;
+ ui3p s = V_pc_p + offset;
+
+ V_pc_p = s;
+
+#if USE_PCLIMIT
+ if (my_cond_rare(s >= V_pc_pHi)
+ || my_cond_rare(s < V_regs.pc_pLo))
+ {
+ Recalc_PC_Block();
+ }
+#endif
+}
+#endif
+
+#if Use68020
+LOCALPROC SkipiLong(void)
+{
+ V_pc_p += 4;
+
+#if USE_PCLIMIT
+ if (my_cond_rare(V_pc_p >= V_pc_pHi)) {
+ Recalc_PC_Block();
+ }
+#endif
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoCodeBccL(void)
+{
+ /* Bcc 0110ccccnnnnnnnn */
+ cctrue(DoCodeBraL, SkipiLong);
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoCodeBsrL(void)
+{
+ si5r offset = ((si5b)(ui5b)nextilong()) - 4;
+ ui3p s = V_pc_p + offset;
+
+ m68k_areg(7) -= 4;
+ put_long(m68k_areg(7), m68k_getpc());
+ V_pc_p = s;
+
+#if USE_PCLIMIT
+ if (my_cond_rare(s >= V_pc_pHi)
+ || my_cond_rare(s < V_regs.pc_pLo))
+ {
+ Recalc_PC_Block();
+ }
+#endif
+
+ /* ReportAbnormal("long branch in DoCode6"); */
+ /* Used by various Apps */
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoCodeEXTBL(void)
+{
+ /* EXTB.L */
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ ui5r dstvalue = ui5r_FromSByte(*dstp);
+
+ V_regs.LazyFlagKind = kLazyFlagsTstL;
+ V_regs.LazyFlagArgDst = dstvalue;
+
+ HaveSetUpFlags();
+
+ *dstp = dstvalue;
+}
+#endif
+
+#if Use68020
+LOCALPROC DoCHK2orCMP2(void)
+{
+ /* CHK2 or CMP2 00000ss011mmmrrr */
+ ui5r regv;
+ ui5r lower;
+ ui5r upper;
+ ui5r extra = nextiword_nm();
+ ui5r DstAddr = DecodeDst();
+ ui5r srcreg = (extra >> 12) & 0x0F;
+ ui5r *srcp = &V_regs.regs[srcreg];
+
+ /* ReportAbnormal("CHK2 or CMP2 instruction"); */
+ switch (V_regs.CurDecOpY.v[0].ArgDat) {
+ case 1:
+ if ((extra & 0x8000) == 0) {
+ regv = ui5r_FromSByte(*srcp);
+ } else {
+ regv = ui5r_FromSLong(*srcp);
+ }
+ lower = get_byte(DstAddr);
+ upper = get_byte(DstAddr + 1);
+ break;
+ case 2:
+ if ((extra & 0x8000) == 0) {
+ regv = ui5r_FromSWord(*srcp);
+ } else {
+ regv = ui5r_FromSLong(*srcp);
+ }
+ lower = get_word(DstAddr);
+ upper = get_word(DstAddr + 2);
+ break;
+ default:
+#if ExtraAbnormalReports
+ if (4 != V_regs.CurDecOpY.v[0].ArgDat) {
+ ReportAbnormalID(0x010E,
+ "illegal opsize in CHK2 or CMP2");
+ }
+#endif
+ if ((extra & 0x8000) == 0) {
+ regv = ui5r_FromSLong(*srcp);
+ } else {
+ regv = ui5r_FromSLong(*srcp);
+ }
+ lower = get_long(DstAddr);
+ upper = get_long(DstAddr + 4);
+ break;
+ }
+
+ NeedDefaultLazyAllFlags();
+
+ ZFLG = Bool2Bit((upper == regv) || (lower == regv));
+ CFLG = Bool2Bit((((si5r)lower) <= ((si5r)upper))
+ ? (((si5r)regv) < ((si5r)lower)
+ || ((si5r)regv) > ((si5r)upper))
+ : (((si5r)regv) > ((si5r)upper)
+ || ((si5r)regv) < ((si5r)lower)));
+
+ if ((extra & 0x800) && (CFLG != 0)) {
+ Exception(6);
+ }
+}
+#endif
+
+#if Use68020
+LOCALPROC DoCAS(void)
+{
+ /* CAS 00001ss011mmmrrr */
+ ui5r srcvalue;
+ ui5r dstvalue;
+
+ ui4b src = nextiword_nm();
+ int ru = (src >> 6) & 7;
+ int rc = src & 7;
+
+ ReportAbnormalID(0x010F, "CAS instruction");
+ switch (V_regs.CurDecOpY.v[0].ArgDat) {
+ case 1:
+ srcvalue = ui5r_FromSByte(V_regs.regs[rc]);
+ break;
+ case 2:
+ srcvalue = ui5r_FromSWord(V_regs.regs[rc]);
+ break;
+ default:
+#if ExtraAbnormalReports
+ if (4 != V_regs.CurDecOpY.v[0].ArgDat) {
+ ReportAbnormalID(0x0110, "illegal opsize in DoCAS");
+ }
+#endif
+ srcvalue = ui5r_FromSLong(V_regs.regs[rc]);
+ break;
+ }
+ dstvalue = DecodeGetSetDstValue();
+
+ {
+ int flgs = ((si5b)srcvalue) < 0;
+ int flgo = ((si5b)dstvalue) < 0;
+ ui5r newv = dstvalue - srcvalue;
+ if (V_regs.CurDecOpY.v[0].ArgDat == 1) {
+ newv = ui5r_FromSByte(newv);
+ } else if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
+ newv = ui5r_FromSWord(newv);
+ } else {
+ newv = ui5r_FromSLong(newv);
+ }
+ ZFLG = Bool2Bit(((si5b)newv) == 0);
+ NFLG = Bool2Bit(((si5b)newv) < 0);
+ VFLG = Bool2Bit((flgs != flgo) && ((NFLG != 0) != flgo));
+ CFLG = Bool2Bit(
+ (flgs && ! flgo) || ((NFLG != 0) && ((! flgo) || flgs)));
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ if (ZFLG != 0) {
+ ArgSetDstValue(m68k_dreg(ru));
+ } else {
+ V_regs.ArgAddr.rga = &V_regs.regs[rc];
+
+ if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
+ *V_regs.ArgAddr.rga =
+ (*V_regs.ArgAddr.rga & ~ 0xffff)
+ | ((dstvalue) & 0xffff);
+ } else if (V_regs.CurDecOpY.v[0].ArgDat < 2) {
+ *V_regs.ArgAddr.rga =
+ (*V_regs.ArgAddr.rga & ~ 0xff)
+ | ((dstvalue) & 0xff);
+ } else {
+ *V_regs.ArgAddr.rga = dstvalue;
+ }
+ }
+ }
+}
+#endif
+
+#if Use68020
+LOCALPROC DoCAS2(void)
+{
+ /* CAS2 00001ss011111100 */
+ ui5b extra = nextilong();
+ int dc2 = extra & 7;
+ int du2 = (extra >> 6) & 7;
+ int dc1 = (extra >> 16) & 7;
+ int du1 = (extra >> 22) & 7;
+ CPTR rn1 = V_regs.regs[(extra >> 28) & 0x0F];
+ CPTR rn2 = V_regs.regs[(extra >> 12) & 0x0F];
+ si5b src = m68k_dreg(dc1);
+ si5r dst1;
+ si5r dst2;
+
+ ReportAbnormalID(0x0111, "DoCAS2 instruction");
+ if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
+ dst1 = get_word(rn1);
+ dst2 = get_word(rn2);
+ src = (si5b)(si4b)src;
+ } else {
+ dst1 = get_long(rn1);
+ dst2 = get_long(rn2);
+ }
+ {
+ int flgs = src < 0;
+ int flgo = dst1 < 0;
+ si5b newv = dst1 - src;
+ if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
+ newv = (ui4b)newv;
+ }
+ ZFLG = Bool2Bit(newv == 0);
+ NFLG = Bool2Bit(newv < 0);
+ VFLG = Bool2Bit((flgs != flgo) && ((NFLG != 0) != flgo));
+ CFLG = Bool2Bit(
+ (flgs && ! flgo) || ((NFLG != 0) && ((! flgo) || flgs)));
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ if (ZFLG != 0) {
+ src = m68k_dreg(dc2);
+ if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
+ src = (si5b)(si4b)src;
+ }
+ flgs = src < 0;
+ flgo = dst2 < 0;
+ newv = dst2 - src;
+ if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
+ newv = (ui4b)newv;
+ }
+ ZFLG = Bool2Bit(newv == 0);
+ NFLG = Bool2Bit(newv < 0);
+ VFLG = Bool2Bit((flgs != flgo) && ((NFLG != 0) != flgo));
+ CFLG = Bool2Bit((flgs && ! flgo)
+ || ((NFLG != 0) && ((! flgo) || flgs)));
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ if (ZFLG != 0) {
+ if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
+ put_word(rn1, m68k_dreg(du1));
+ put_word(rn2, m68k_dreg(du2));
+ } else {
+ put_word(rn1, m68k_dreg(du1));
+ put_word(rn2, m68k_dreg(du2));
+ }
+ }
+ }
+ }
+ if (ZFLG == 0) {
+ if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
+ m68k_dreg(du1) =
+ (m68k_dreg(du1) & ~ 0xffff) | ((ui5b)dst1 & 0xffff);
+ m68k_dreg(du2) =
+ (m68k_dreg(du2) & ~ 0xffff) | ((ui5b)dst2 & 0xffff);
+ } else {
+ m68k_dreg(du1) = dst1;
+ m68k_dreg(du2) = dst2;
+ }
+ }
+}
+#endif
+
+#if Use68020
+LOCALPROC DoMOVES(void)
+{
+ /* MoveS 00001110ssmmmrrr */
+ ReportAbnormalID(0x0112, "MoveS instruction");
+ if (0 == V_regs.s) {
+ DoPrivilegeViolation();
+ } else {
+ ui4b extra = nextiword_nm();
+ if (extra & 0x0800) {
+ ui5b src = V_regs.regs[(extra >> 12) & 0x0F];
+ DecodeSetDstValue(src);
+ } else {
+ ui5r srcvalue = DecodeGetDstValue();
+ ui5b rr = (extra >> 12) & 7;
+ if (extra & 0x8000) {
+ m68k_areg(rr) = srcvalue;
+ } else {
+ V_regs.ArgAddr.rga = &V_regs.regs[rr];
+
+ if (V_regs.CurDecOpY.v[0].ArgDat == 2) {
+ *V_regs.ArgAddr.rga =
+ (*V_regs.ArgAddr.rga & ~ 0xffff)
+ | ((srcvalue) & 0xffff);
+ } else if (V_regs.CurDecOpY.v[0].ArgDat < 2) {
+ *V_regs.ArgAddr.rga =
+ (*V_regs.ArgAddr.rga & ~ 0xff)
+ | ((srcvalue) & 0xff);
+ } else {
+ *V_regs.ArgAddr.rga = srcvalue;
+ }
+ }
+ }
+ }
+}
+#endif
+
+#define ui5b_lo(x) ((x) & 0x0000FFFF)
+#define ui5b_hi(x) (((x) >> 16) & 0x0000FFFF)
+
+#if Use68020
+struct ui6r0 {
+ ui5b hi;
+ ui5b lo;
+};
+typedef struct ui6r0 ui6r0;
+#endif
+
+#if Use68020
+LOCALPROC Ui6r_Negate(ui6r0 *v)
+{
+ v->hi = ~ v->hi;
+ v->lo = - v->lo;
+ if (v->lo == 0) {
+ v->hi++;
+ }
+}
+#endif
+
+#if Use68020
+LOCALFUNC blnr my_reg_call Ui6r_IsZero(ui6r0 *v)
+{
+ return (v->hi == 0) && (v->lo == 0);
+}
+#endif
+
+#if Use68020
+LOCALFUNC blnr my_reg_call Ui6r_IsNeg(ui6r0 *v)
+{
+ return ((si5b)v->hi) < 0;
+}
+#endif
+
+#if Use68020
+LOCALPROC mul_unsigned(ui5b src1, ui5b src2, ui6r0 *dst)
+{
+ ui5b src1_lo = ui5b_lo(src1);
+ ui5b src2_lo = ui5b_lo(src2);
+ ui5b src1_hi = ui5b_hi(src1);
+ ui5b src2_hi = ui5b_hi(src2);
+
+ ui5b r0 = src1_lo * src2_lo;
+ ui5b r1 = src1_hi * src2_lo;
+ ui5b r2 = src1_lo * src2_hi;
+ ui5b r3 = src1_hi * src2_hi;
+
+ ui5b ra1 = ui5b_hi(r0) + ui5b_lo(r1) + ui5b_lo(r2);
+
+ dst->lo = (ui5b_lo(ra1) << 16) | ui5b_lo(r0);
+ dst->hi = ui5b_hi(ra1) + ui5b_hi(r1) + ui5b_hi(r2) + r3;
+}
+#endif
+
+#if Use68020
+LOCALFUNC blnr div_unsigned(ui6r0 *src, ui5b div,
+ ui5b *quot, ui5b *rem)
+{
+ int i;
+ ui5b q = 0;
+ ui5b cbit = 0;
+ ui5b src_hi = src->hi;
+ ui5b src_lo = src->lo;
+
+ if (div <= src_hi) {
+ return trueblnr;
+ }
+ for (i = 0 ; i < 32 ; i++) {
+ cbit = src_hi & 0x80000000ul;
+ src_hi <<= 1;
+ if (src_lo & 0x80000000ul) {
+ src_hi++;
+ }
+ src_lo <<= 1;
+ q = q << 1;
+ if (cbit || div <= src_hi) {
+ q |= 1;
+ src_hi -= div;
+ }
+ }
+ *quot = q;
+ *rem = src_hi;
+ return falseblnr;
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoCodeMulL(void)
+{
+ /* MULU 0100110000mmmrrr 0rrr0s0000000rrr */
+ /* MULS 0100110000mmmrrr 0rrr1s0000000rrr */
+ ui6r0 dst;
+ ui4b extra = nextiword();
+ ui5b r2 = (extra >> 12) & 7;
+ ui5b dstvalue = m68k_dreg(r2);
+ ui5r srcvalue = DecodeGetDstValue();
+
+ if (extra & 0x800) {
+ /* MULS.L - signed */
+
+ si5b src1 = (si5b)srcvalue;
+ si5b src2 = (si5b)dstvalue;
+ blnr s1 = src1 < 0;
+ blnr s2 = src2 < 0;
+ blnr sr = s1 != s2;
+
+ /* ReportAbnormal("MULS.L"); */
+ /* used by Sys 7.5.5 boot extensions */
+ if (s1) {
+ src1 = - src1;
+ }
+ if (s2) {
+ src2 = - src2;
+ }
+ mul_unsigned((ui5b)src1, (ui5b)src2, &dst);
+ if (sr) {
+ Ui6r_Negate(&dst);
+ }
+ VFLG = CFLG = 0;
+ ZFLG = Bool2Bit(Ui6r_IsZero(&dst));
+ NFLG = Bool2Bit(Ui6r_IsNeg(&dst));
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ if (extra & 0x400) {
+ m68k_dreg(extra & 7) = dst.hi;
+ } else {
+ if ((dst.lo & 0x80000000) != 0) {
+ if ((dst.hi & 0xffffffff) != 0xffffffff) {
+ VFLG = 1;
+ }
+ } else {
+ if (dst.hi != 0) {
+ VFLG = 1;
+ }
+ }
+ }
+ } else {
+ /* MULU.L - unsigned */
+
+ /* ReportAbnormal("MULU.U"); */
+ /* Used by various Apps */
+
+ mul_unsigned(srcvalue, dstvalue, &dst);
+
+ VFLG = CFLG = 0;
+ ZFLG = Bool2Bit(Ui6r_IsZero(&dst));
+ NFLG = Bool2Bit(Ui6r_IsNeg(&dst));
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ if (extra & 0x400) {
+ m68k_dreg(extra & 7) = dst.hi;
+ } else {
+ if (dst.hi != 0) {
+ VFLG = 1;
+ }
+ }
+ }
+ m68k_dreg(r2) = dst.lo;
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoCodeDivL(void)
+{
+ /* DIVU 0100110001mmmrrr 0rrr0s0000000rrr */
+ /* DIVS 0100110001mmmrrr 0rrr1s0000000rrr */
+ /* ReportAbnormal("DIVS/DIVU long"); */
+ ui6r0 v2;
+ ui5b quot;
+ ui5b rem;
+ ui4b extra = nextiword();
+ ui5b rDr = extra & 7;
+ ui5b rDq = (extra >> 12) & 7;
+ ui5r src = (ui5b)(si5b)DecodeGetDstValue();
+
+ if (src == 0) {
+ Exception(5);
+#if m68k_logExceptions
+ dbglog_WriteNote("*** zero devide exception");
+#endif
+ return;
+ }
+ if (0 != (extra & 0x0800)) {
+ /* signed variant */
+ blnr sr;
+ blnr s2;
+ blnr s1 = ((si5b)src < 0);
+
+ v2.lo = (si5b)m68k_dreg(rDq);
+ if (extra & 0x0400) {
+ v2.hi = (si5b)m68k_dreg(rDr);
+ } else {
+ v2.hi = ((si5b)v2.lo) < 0 ? -1 : 0;
+ }
+ s2 = Ui6r_IsNeg(&v2);
+ sr = (s1 != s2);
+ if (s2) {
+ Ui6r_Negate(&v2);
+ }
+ if (s1) {
+ src = - src;
+ }
+ if (div_unsigned(&v2, src, ", &rem)
+ || (sr ? quot > 0x80000000 : quot > 0x7fffffff))
+ {
+ NeedDefaultLazyAllFlags();
+
+ VFLG = NFLG = 1;
+ CFLG = 0;
+ } else {
+ if (sr) {
+ quot = - quot;
+ }
+ if (((si5b)rem < 0) != s2) {
+ rem = - rem;
+ }
+ VFLG = CFLG = 0;
+ ZFLG = Bool2Bit(((si5b)quot) == 0);
+ NFLG = Bool2Bit(((si5b)quot) < 0);
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ m68k_dreg(rDr) = rem;
+ m68k_dreg(rDq) = quot;
+ }
+ } else {
+ /* unsigned */
+
+ v2.lo = (ui5b)m68k_dreg(rDq);
+ if (extra & 0x400) {
+ v2.hi = (ui5b)m68k_dreg(rDr);
+ } else {
+ v2.hi = 0;
+ }
+ if (div_unsigned(&v2, src, ", &rem)) {
+ NeedDefaultLazyAllFlags();
+
+ VFLG = NFLG = 1;
+ CFLG = 0;
+ } else {
+ VFLG = CFLG = 0;
+ ZFLG = Bool2Bit(((si5b)quot) == 0);
+ NFLG = Bool2Bit(((si5b)quot) < 0);
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ m68k_dreg(rDr) = rem;
+ m68k_dreg(rDq) = quot;
+ }
+ }
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoMoveToControl(void)
+{
+ if (0 == V_regs.s) {
+ DoPrivilegeViolation();
+ } else {
+ ui4b src = nextiword_nm();
+ int regno = (src >> 12) & 0x0F;
+ ui5b v = V_regs.regs[regno];
+
+ switch (src & 0x0FFF) {
+ case 0x0000:
+ V_regs.sfc = v & 7;
+ /* ReportAbnormal("DoMoveToControl: sfc"); */
+ /* happens on entering macsbug */
+ break;
+ case 0x0001:
+ V_regs.dfc = v & 7;
+ /* ReportAbnormal("DoMoveToControl: dfc"); */
+ break;
+ case 0x0002:
+ V_regs.cacr = v & 0x3;
+ /* ReportAbnormal("DoMoveToControl: cacr"); */
+ /* used by Sys 7.5.5 boot */
+ break;
+ case 0x0800:
+ V_regs.usp = v;
+ ReportAbnormalID(0x0113, "DoMoveToControl: usp");
+ break;
+ case 0x0801:
+ V_regs.vbr = v;
+ /* ReportAbnormal("DoMoveToControl: vbr"); */
+ /* happens on entering macsbug */
+ break;
+ case 0x0802:
+ V_regs.caar = v &0xfc;
+ /* ReportAbnormal("DoMoveToControl: caar"); */
+ /* happens on entering macsbug */
+ break;
+ case 0x0803:
+ V_regs.msp = v;
+ if (V_regs.m == 1) {
+ m68k_areg(7) = V_regs.msp;
+ }
+ /* ReportAbnormal("DoMoveToControl: msp"); */
+ /* happens on entering macsbug */
+ break;
+ case 0x0804:
+ V_regs.isp = v;
+ if (V_regs.m == 0) {
+ m68k_areg(7) = V_regs.isp;
+ }
+ ReportAbnormalID(0x0114, "DoMoveToControl: isp");
+ break;
+ default:
+ op_illg();
+ ReportAbnormalID(0x0115,
+ "DoMoveToControl: unknown reg");
+ break;
+ }
+ }
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoMoveFromControl(void)
+{
+ if (0 == V_regs.s) {
+ DoPrivilegeViolation();
+ } else {
+ ui5b v;
+ ui4b src = nextiword_nm();
+ int regno = (src >> 12) & 0x0F;
+
+ switch (src & 0x0FFF) {
+ case 0x0000:
+ v = V_regs.sfc;
+ /* ReportAbnormal("DoMoveFromControl: sfc"); */
+ /* happens on entering macsbug */
+ break;
+ case 0x0001:
+ v = V_regs.dfc;
+ /* ReportAbnormal("DoMoveFromControl: dfc"); */
+ /* happens on entering macsbug */
+ break;
+ case 0x0002:
+ v = V_regs.cacr;
+ /* ReportAbnormal("DoMoveFromControl: cacr"); */
+ /* used by Sys 7.5.5 boot */
+ break;
+ case 0x0800:
+ v = V_regs.usp;
+ ReportAbnormalID(0x0116, "DoMoveFromControl: usp");
+ break;
+ case 0x0801:
+ v = V_regs.vbr;
+ /* ReportAbnormal("DoMoveFromControl: vbr"); */
+ /* happens on entering macsbug */
+ break;
+ case 0x0802:
+ v = V_regs.caar;
+ /* ReportAbnormal("DoMoveFromControl: caar"); */
+ /* happens on entering macsbug */
+ break;
+ case 0x0803:
+ v = (V_regs.m == 1)
+ ? m68k_areg(7)
+ : V_regs.msp;
+ /* ReportAbnormal("DoMoveFromControl: msp"); */
+ /* happens on entering macsbug */
+ break;
+ case 0x0804:
+ v = (V_regs.m == 0)
+ ? m68k_areg(7)
+ : V_regs.isp;
+ ReportAbnormalID(0x0117, "DoMoveFromControl: isp");
+ break;
+ default:
+ v = 0;
+ ReportAbnormalID(0x0118,
+ "DoMoveFromControl: unknown reg");
+ op_illg();
+ break;
+ }
+ V_regs.regs[regno] = v;
+ }
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoCodeBkpt(void)
+{
+ /* BKPT 0100100001001rrr */
+ ReportAbnormalID(0x0119, "BKPT instruction");
+ op_illg();
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoCodeRtd(void)
+{
+ /* Rtd 0100111001110100 */
+ ui5r NewPC = get_long(m68k_areg(7));
+ si5b offs = nextiSWord();
+ /* ReportAbnormal("RTD"); */
+ /* used by Sys 7.5.5 boot */
+ m68k_areg(7) += (4 + offs);
+ m68k_setpc(NewPC);
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoCodeLinkL(void)
+{
+ /* Link.L 0100100000001rrr */
+
+ ui5r dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui5r *dstp = &V_regs.regs[dstreg];
+ CPTR stackp = m68k_areg(7);
+
+ ReportAbnormalID(0x011A, "Link.L");
+
+ stackp -= 4;
+ m68k_areg(7) = stackp; /* only matters if dstreg == 7 + 8 */
+ put_long(stackp, *dstp);
+ *dstp = stackp;
+ m68k_areg(7) += (si5b)nextilong();
+}
+#endif
+
+#if Use68020
+LOCALPROC DoCodeTRAPcc_t(void)
+{
+ ReportAbnormalID(0x011B, "TRAPcc trapping");
+ Exception(7);
+ /* pc pushed onto stack wrong */
+}
+#endif
+
+#if Use68020
+LOCALPROC DoCodeTRAPcc_f(void)
+{
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoCodeTRAPcc(void)
+{
+ /* TRAPcc 0101cccc11111sss */
+ /* ReportAbnormal("TRAPcc"); */
+ switch (V_regs.CurDecOpY.v[1].ArgDat) {
+ case 2:
+ ReportAbnormalID(0x011C, "TRAPcc word data");
+ SkipiWord();
+ break;
+ case 3:
+ ReportAbnormalID(0x011D, "TRAPcc long data");
+ SkipiLong();
+ break;
+ case 4:
+ /* ReportAbnormal("TRAPcc no data"); */
+ /* no optional data */
+ break;
+ default:
+ ReportAbnormalID(0x011E, "TRAPcc illegal format");
+ op_illg();
+ break;
+ }
+ cctrue(DoCodeTRAPcc_t, DoCodeTRAPcc_f);
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoCodePack(void)
+{
+ ui5r offs = nextiSWord();
+ ui5r val = DecodeGetSrcValue();
+
+ ReportAbnormalID(0x011F, "PACK");
+
+ val += offs;
+ val = ((val >> 4) & 0xf0) | (val & 0xf);
+
+ DecodeSetDstValue(val);
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoCodeUnpk(void)
+{
+ ui5r offs = nextiSWord();
+ ui5r val = DecodeGetSrcValue();
+
+ ReportAbnormalID(0x0120, "UNPK");
+
+ val = (((val & 0xF0) << 4) | (val & 0x0F)) + offs;
+
+ DecodeSetDstValue(val);
+}
+#endif
+
+#if Use68020
+LOCALIPROC DoBitField(void)
+{
+ ui5b tmp;
+ ui5b newtmp;
+ CPTR dsta;
+ ui5b bf0;
+ ui3b bf1;
+ ui5b dstreg = V_regs.CurDecOpY.v[1].ArgDat;
+ ui4b extra = nextiword();
+ ui5b offset = ((extra & 0x0800) != 0)
+ ? m68k_dreg((extra >> 6) & 7)
+ : ((extra >> 6) & 0x1f);
+ ui5b width = ((extra & 0x0020) != 0)
+ ? m68k_dreg(extra & 7)
+ : extra;
+ ui3b bfa[5];
+ ui5b offwid;
+
+ /* ReportAbnormal("Bit Field operator"); */
+ /* width = ((width - 1) & 0x1f) + 1; */ /* 0 -> 32 */
+ width &= 0x001F; /* except width == 0 really means 32 */
+ if (V_regs.CurDecOpY.v[0].AMd == 0) {
+ bf0 = m68k_dreg(dstreg);
+ offset &= 0x1f;
+ tmp = bf0;
+ if (0 != offset) {
+ tmp = (tmp << offset) | (tmp >> (32 - offset));
+ }
+ } else {
+ /*
+ V_regs.ArgKind == AKMemory,
+ otherwise illegal and don't get here
+ */
+ dsta = DecodeDst();
+ dsta += Ui5rASR(offset, 3);
+ offset &= 7;
+ offwid = offset + ((width == 0) ? 32 : width);
+
+ /* if (offwid > 0) */ {
+ bf1 = get_byte(dsta);
+ bfa[0] = bf1;
+ tmp = ((ui5b)bf1) << (24 + offset);
+ }
+ if (offwid > 8) {
+ bf1 = get_byte(dsta + 1);
+ bfa[1] = bf1;
+ tmp |= ((ui5b)bf1) << (16 + offset);
+ }
+ if (offwid > 16) {
+ bf1 = get_byte(dsta + 2);
+ bfa[2] = bf1;
+ tmp |= ((ui5r)bf1) << (8 + offset);
+ }
+ if (offwid > 24) {
+ bf1 = get_byte(dsta + 3);
+ bfa[3] = bf1;
+ tmp |= ((ui5r)bf1) << (offset);
+ }
+ if (offwid > 32) {
+ bf1 = get_byte(dsta + 4);
+ bfa[4] = bf1;
+ tmp |= ((ui5r)bf1) >> (8 - offset);
+ }
+ }
+
+ NFLG = Bool2Bit(((si5b)tmp) < 0);
+ if (width != 0) {
+ tmp >>= (32 - width);
+ }
+ ZFLG = tmp == 0;
+ VFLG = 0;
+ CFLG = 0;
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+
+ newtmp = tmp;
+
+ switch (V_regs.CurDecOpY.v[0].ArgDat) {
+ case 0: /* BFTST */
+ /* do nothing */
+ break;
+ case 1: /* BFEXTU */
+ m68k_dreg((extra >> 12) & 7) = tmp;
+ break;
+ case 2: /* BFCHG */
+ newtmp = ~ newtmp;
+ if (width != 0) {
+ newtmp &= ((1 << width) - 1);
+ }
+ break;
+ case 3: /* BFEXTS */
+ if (NFLG != 0) {
+ m68k_dreg((extra >> 12) & 7) = tmp
+ | ((width == 0) ? 0 : (-1 << width));
+ } else {
+ m68k_dreg((extra >> 12) & 7) = tmp;
+ }
+ break;
+ case 4: /* BFCLR */
+ newtmp = 0;
+ break;
+ case 5: /* BFFFO */
+ {
+ ui5b mask = 1 << ((width == 0) ? 31 : (width - 1));
+ ui5r i = offset;
+
+ while ((0 != mask) && (0 == (tmp & mask))) {
+ mask >>= 1;
+ i++;
+ }
+ m68k_dreg((extra >> 12) & 7) = i;
+ }
+ break;
+ case 6: /* BFSET */
+ newtmp = (width == 0) ? ~ 0 : ((1 << width) - 1);
+ break;
+ case 7: /* BFINS */
+ newtmp = m68k_dreg((extra >> 12) & 7);
+ if (width != 0) {
+ newtmp &= ((1 << width) - 1);
+ }
+ break;
+ }
+
+ if (newtmp != tmp) {
+
+ if (width != 0) {
+ newtmp <<= (32 - width);
+ }
+
+ if (V_regs.CurDecOpY.v[0].AMd == 0) {
+ ui5b mask = ~ 0;
+
+ if (width != 0) {
+ mask <<= (32 - width);
+ }
+
+ if (0 != offset) {
+ newtmp = (newtmp >> offset) | (newtmp << (32 - offset));
+ mask = (mask >> offset) | (mask << (32 - offset));
+ }
+
+ bf0 = (bf0 & ~ mask) | (newtmp);
+ m68k_dreg(dstreg) = bf0;
+ } else {
+
+ /* if (offwid > 0) */ {
+ ui3b mask = ~ (0xFF >> offset);
+
+ bf1 = newtmp >> (24 + offset);
+ if (offwid < 8) {
+ mask |= (0xFF >> offwid);
+ }
+ if (mask != 0) {
+ bf1 |= bfa[0] & mask;
+ }
+ put_byte(dsta + 0, bf1);
+ }
+ if (offwid > 8) {
+ bf1 = newtmp >> (16 + offset);
+ if (offwid < 16) {
+ bf1 |= (bfa[1] & (0xFF >> (offwid - 8)));
+ }
+ put_byte(dsta + 1, bf1);
+ }
+ if (offwid > 16) {
+ bf1 = newtmp >> (8 + offset);
+ if (offwid < 24) {
+ bf1 |= (bfa[2] & (0xFF >> (offwid - 16)));
+ }
+ put_byte(dsta + 2, bf1);
+ }
+ if (offwid > 24) {
+ bf1 = newtmp >> (offset);
+ if (offwid < 32) {
+ bf1 |= (bfa[3] & (0xFF >> (offwid - 24)));
+ }
+ put_byte(dsta + 3, bf1);
+ }
+ if (offwid > 32) {
+ bf1 = newtmp << (8 - offset);
+ bf1 |= (bfa[4] & (0xFF >> (offwid - 32)));
+ put_byte(dsta + 4, bf1);
+ }
+ }
+ }
+}
+#endif
+
+#if EmMMU | EmFPU
+LOCALFUNC blnr DecodeModeRegister(ui5b sz)
+{
+ blnr IsOk;
+ ui4r Dat = V_regs.CurDecOpY.v[0].ArgDat;
+ ui4r themode = (Dat >> 3) & 7;
+ ui4r thereg = Dat & 7;
+
+ switch (themode) {
+ case 0 :
+ V_regs.ArgKind = AKRegister;
+ V_regs.ArgAddr.rga = &V_regs.regs[thereg];
+ IsOk = trueblnr;
+ break;
+ case 1 :
+ V_regs.ArgKind = AKRegister;
+ V_regs.ArgAddr.rga = &V_regs.regs[thereg + 8];
+ IsOk = trueblnr;
+ break;
+ case 2 :
+ V_regs.ArgKind = AKMemory;
+ V_regs.ArgAddr.mem = m68k_areg(thereg);
+ IsOk = trueblnr;
+ break;
+ case 3 :
+ V_regs.ArgKind = AKMemory;
+ V_regs.ArgAddr.mem = m68k_areg(thereg);
+ if ((thereg == 7) && (sz == 1)) {
+ m68k_areg(thereg) += 2;
+ } else {
+ m68k_areg(thereg) += sz;
+ }
+ IsOk = trueblnr;
+ break;
+ case 4 :
+ V_regs.ArgKind = AKMemory;
+ if ((thereg == 7) && (sz == 1)) {
+ m68k_areg(thereg) -= 2;
+ } else {
+ m68k_areg(thereg) -= sz;
+ }
+ V_regs.ArgAddr.mem = m68k_areg(thereg);
+ IsOk = trueblnr;
+ break;
+ case 5 :
+ V_regs.ArgKind = AKMemory;
+ V_regs.ArgAddr.mem = m68k_areg(thereg)
+ + nextiSWord();
+ IsOk = trueblnr;
+ break;
+ case 6 :
+ V_regs.ArgKind = AKMemory;
+ V_regs.ArgAddr.mem = get_disp_ea(m68k_areg(thereg));
+ IsOk = trueblnr;
+ break;
+ case 7 :
+ switch (thereg) {
+ case 0 :
+ V_regs.ArgKind = AKMemory;
+ V_regs.ArgAddr.mem = nextiSWord();
+ IsOk = trueblnr;
+ break;
+ case 1 :
+ V_regs.ArgKind = AKMemory;
+ V_regs.ArgAddr.mem = nextilong();
+ IsOk = trueblnr;
+ break;
+ case 2 :
+ V_regs.ArgKind = AKMemory;
+ V_regs.ArgAddr.mem = m68k_getpc();
+ V_regs.ArgAddr.mem += nextiSWord();
+ IsOk = trueblnr;
+ break;
+ case 3 :
+ V_regs.ArgKind = AKMemory;
+ V_regs.ArgAddr.mem = get_disp_ea(m68k_getpc());
+ IsOk = trueblnr;
+ break;
+ case 4 :
+ V_regs.ArgKind = AKMemory;
+ V_regs.ArgAddr.mem = m68k_getpc();
+ if (sz == 1) {
+ ++V_regs.ArgAddr.mem;
+ }
+ m68k_setpc(V_regs.ArgAddr.mem + sz);
+ IsOk = trueblnr;
+ break;
+ default:
+ IsOk = falseblnr;
+ break;
+ }
+ break;
+ default:
+ IsOk = falseblnr;
+ break;
+ }
+
+ return IsOk;
+}
+#endif
+
+#if EmMMU | EmFPU
+LOCALFUNC ui5r GetArgValueL(void)
+{
+ ui5r v;
+
+ if (AKMemory == V_regs.ArgKind) {
+ v = get_long(V_regs.ArgAddr.mem);
+ } else {
+ /* must be AKRegister */
+ v = ui5r_FromSLong(*V_regs.ArgAddr.rga);
+ }
+
+ return v;
+}
+#endif
+
+#if EmMMU | EmFPU
+LOCALFUNC ui5r GetArgValueW(void)
+{
+ ui5r v;
+
+ if (AKMemory == V_regs.ArgKind) {
+ v = get_word(V_regs.ArgAddr.mem);
+ } else {
+ /* must be AKRegister */
+ v = ui5r_FromSWord(*V_regs.ArgAddr.rga);
+ }
+
+ return v;
+}
+#endif
+
+#if EmMMU | EmFPU
+LOCALFUNC ui5r GetArgValueB(void)
+{
+ ui5r v;
+
+ if (AKMemory == V_regs.ArgKind) {
+ v = get_byte(V_regs.ArgAddr.mem);
+ } else {
+ /* must be AKRegister */
+ v = ui5r_FromSByte(*V_regs.ArgAddr.rga);
+ }
+
+ return v;
+}
+#endif
+
+#if EmMMU | EmFPU
+LOCALPROC SetArgValueL(ui5r v)
+{
+ if (AKMemory == V_regs.ArgKind) {
+ put_long(V_regs.ArgAddr.mem, v);
+ } else {
+ /* must be AKRegister */
+ *V_regs.ArgAddr.rga = v;
+ }
+}
+#endif
+
+#if EmMMU | EmFPU
+LOCALPROC SetArgValueW(ui5r v)
+{
+ if (AKMemory == V_regs.ArgKind) {
+ put_word(V_regs.ArgAddr.mem, v);
+ } else {
+ /* must be AKRegister */
+ *V_regs.ArgAddr.rga =
+ (*V_regs.ArgAddr.rga & ~ 0xffff) | ((v) & 0xffff);
+ }
+}
+#endif
+
+#if EmMMU | EmFPU
+LOCALPROC SetArgValueB(ui5r v)
+{
+ if (AKMemory == V_regs.ArgKind) {
+ put_byte(V_regs.ArgAddr.mem, v);
+ } else {
+ /* must be AKRegister */
+ *V_regs.ArgAddr.rga =
+ (*V_regs.ArgAddr.rga & ~ 0xff) | ((v) & 0xff);
+ }
+}
+#endif
+
+
+#if EmMMU
+LOCALIPROC DoCodeMMU(void)
+{
+ /*
+ Emulate enough of MMU for System 7.5.5 universal
+ to boot on Mac Plus 68020. There is one
+ spurious "PMOVE TC, (A0)".
+ And implement a few more PMOVE operations seen
+ when running Disk Copy 6.3.3 and MacsBug.
+ */
+ ui4r opcode = ((ui4r)(V_regs.CurDecOpY.v[0].AMd) << 8)
+ | V_regs.CurDecOpY.v[0].ArgDat;
+ if (opcode == 0xF010) {
+ ui4b ew = (int)nextiword_nm();
+ if (ew == 0x4200) {
+ /* PMOVE TC, (A0) */
+ /* fprintf(stderr, "0xF010 0x4200\n"); */
+ if (DecodeModeRegister(4)) {
+ SetArgValueL(0);
+ return;
+ }
+ } else if ((ew == 0x4E00) || (ew == 0x4A00)) {
+ /* PMOVE CRP, (A0) and PMOVE SRP, (A0) */
+ /* fprintf(stderr, "0xF010 %x\n", ew); */
+ if (DecodeModeRegister(4)) {
+ SetArgValueL(0x7FFF0001);
+ V_regs.ArgAddr.mem += 4;
+ SetArgValueL(0);
+ return;
+ }
+ } else if (ew == 0x6200) {
+ /* PMOVE MMUSR, (A0) */
+ /* fprintf(stderr, "0xF010 %x\n", ew); */
+ if (DecodeModeRegister(2)) {
+ SetArgValueW(0);
+ return;
+ }
+ }
+ /* fprintf(stderr, "extensions %x\n", ew); */
+ BackupPC();
+ }
+ /* fprintf(stderr, "opcode %x\n", (int)opcode); */
+ ReportAbnormalID(0x0121, "MMU op");
+ DoCodeFdefault();
+}
+#endif
+
+#if EmFPU
+
+#include "FPMATHEM.h"
+#include "FPCPEMDV.h"
+
+#endif
+
+#if HaveGlbReg
+LOCALPROC Em_Swap(void)
+{
+#ifdef r_pc_p
+ {
+ ui3p t = g_pc_p;
+ g_pc_p = regs.pc_p;
+ regs.pc_p = t;
+ }
+#endif
+#ifdef r_MaxCyclesToGo
+ {
+ si5rr t = g_MaxCyclesToGo;
+ g_MaxCyclesToGo = regs.MaxCyclesToGo;
+ regs.MaxCyclesToGo = t;
+ }
+#endif
+#ifdef r_pc_pHi
+ {
+ ui3p t = g_pc_pHi;
+ g_pc_pHi = regs.pc_pHi;
+ regs.pc_pHi = t;
+ }
+#endif
+#ifdef r_regs
+ {
+ struct regstruct *t = g_regs;
+ g_regs = regs.save_regs;
+ regs.save_regs = t;
+ }
+#endif
+}
+#endif
+
+#if HaveGlbReg
+#define Em_Enter Em_Swap
+#else
+#define Em_Enter()
+#endif
+
+#if HaveGlbReg
+#define Em_Exit Em_Swap
+#else
+#define Em_Exit()
+#endif
+
+#if HaveGlbReg
+LOCALFUNC blnr LocalMemAccessNtfy(ATTep pT)
+{
+ blnr v;
+
+ Em_Exit();
+ v = MemAccessNtfy(pT);
+ Em_Enter();
+
+ return v;
+}
+#else
+#define LocalMemAccessNtfy MemAccessNtfy
+#endif
+
+#if HaveGlbReg
+LOCALFUNC ui5b LocalMMDV_Access(ATTep p, ui5b Data,
+ blnr WriteMem, blnr ByteSize, CPTR addr)
+{
+ ui5b v;
+
+ Em_Exit();
+ v = MMDV_Access(p, Data, WriteMem, ByteSize, addr);
+ Em_Enter();
+
+ return v;
+}
+#else
+#define LocalMMDV_Access MMDV_Access
+#endif
+
+LOCALPROC local_customreset(void)
+{
+ Em_Exit();
+ customreset();
+ Em_Enter();
+}
+
+LOCALFUNC ATTep LocalFindATTel(CPTR addr)
+{
+ ATTep prev;
+ ATTep p;
+
+ p = V_regs.HeadATTel;
+ if ((addr & p->cmpmask) != p->cmpvalu) {
+ do {
+ prev = p;
+ p = p->Next;
+ } while ((addr & p->cmpmask) != p->cmpvalu);
+
+ {
+ ATTep next = p->Next;
+
+ if (nullpr == next) {
+ /* don't move the end guard */
+ } else {
+ /* move to first */
+ prev->Next = next;
+ p->Next = V_regs.HeadATTel;
+ V_regs.HeadATTel = p;
+ }
+ }
+ }
+
+ return p;
+}
+
+LOCALPROC SetUpMATC(
+ MATCp CurMATC,
+ ATTep p)
+{
+ CurMATC->cmpmask = p->cmpmask;
+ CurMATC->usemask = p->usemask;
+ CurMATC->cmpvalu = p->cmpvalu;
+ CurMATC->usebase = p->usebase;
+}
+
+LOCALFUNC ui5r my_reg_call get_byte_ext(CPTR addr)
+{
+ ATTep p;
+ ui3p m;
+ ui5r AccFlags;
+ ui5r Data;
+
+Label_Retry:
+ p = LocalFindATTel(addr);
+ AccFlags = p->Access;
+
+ if (0 != (AccFlags & kATTA_readreadymask)) {
+ SetUpMATC(&V_regs.MATCrdB, p);
+ m = p->usebase + (addr & p->usemask);
+
+ Data = *m;
+ } else if (0 != (AccFlags & kATTA_mmdvmask)) {
+ Data = LocalMMDV_Access(p, 0, falseblnr, trueblnr, addr);
+ } else if (0 != (AccFlags & kATTA_ntfymask)) {
+ if (LocalMemAccessNtfy(p)) {
+ goto Label_Retry;
+ } else {
+ Data = 0; /* fail */
+ }
+ } else {
+ Data = 0; /* fail */
+ }
+
+ return ui5r_FromSByte(Data);
+}
+
+LOCALPROC my_reg_call put_byte_ext(CPTR addr, ui5r b)
+{
+ ATTep p;
+ ui3p m;
+ ui5r AccFlags;
+
+Label_Retry:
+ p = LocalFindATTel(addr);
+ AccFlags = p->Access;
+
+ if (0 != (AccFlags & kATTA_writereadymask)) {
+ SetUpMATC(&V_regs.MATCwrB, p);
+ m = p->usebase + (addr & p->usemask);
+ *m = b;
+ } else if (0 != (AccFlags & kATTA_mmdvmask)) {
+ (void) LocalMMDV_Access(p, b & 0x00FF,
+ trueblnr, trueblnr, addr);
+ } else if (0 != (AccFlags & kATTA_ntfymask)) {
+ if (LocalMemAccessNtfy(p)) {
+ goto Label_Retry;
+ } else {
+ /* fail */
+ }
+ } else {
+ /* fail */
+ }
+}
+
+LOCALFUNC ui5r my_reg_call get_word_ext(CPTR addr)
+{
+ ui5r Data;
+
+ if (0 != (addr & 0x01)) {
+ ui5r hi = get_byte(addr);
+ ui5r lo = get_byte(addr + 1);
+ Data = ((hi << 8) & 0x0000FF00)
+ | (lo & 0x000000FF);
+ } else {
+ ATTep p;
+ ui3p m;
+ ui5r AccFlags;
+
+Label_Retry:
+ p = LocalFindATTel(addr);
+ AccFlags = p->Access;
+
+ if (0 != (AccFlags & kATTA_readreadymask)) {
+ SetUpMATC(&V_regs.MATCrdW, p);
+ V_regs.MATCrdW.cmpmask |= 0x01;
+ m = p->usebase + (addr & p->usemask);
+ Data = do_get_mem_word(m);
+ } else if (0 != (AccFlags & kATTA_mmdvmask)) {
+ Data = LocalMMDV_Access(p, 0, falseblnr, falseblnr, addr);
+ } else if (0 != (AccFlags & kATTA_ntfymask)) {
+ if (LocalMemAccessNtfy(p)) {
+ goto Label_Retry;
+ } else {
+ Data = 0; /* fail */
+ }
+ } else {
+ Data = 0; /* fail */
+ }
+ }
+
+ return ui5r_FromSWord(Data);
+}
+
+LOCALPROC my_reg_call put_word_ext(CPTR addr, ui5r w)
+{
+ if (0 != (addr & 0x01)) {
+ put_byte(addr, w >> 8);
+ put_byte(addr + 1, w);
+ } else {
+ ATTep p;
+ ui3p m;
+ ui5r AccFlags;
+
+Label_Retry:
+ p = LocalFindATTel(addr);
+ AccFlags = p->Access;
+
+ if (0 != (AccFlags & kATTA_writereadymask)) {
+ SetUpMATC(&V_regs.MATCwrW, p);
+ V_regs.MATCwrW.cmpmask |= 0x01;
+ m = p->usebase + (addr & p->usemask);
+ do_put_mem_word(m, w);
+ } else if (0 != (AccFlags & kATTA_mmdvmask)) {
+ (void) LocalMMDV_Access(p, w & 0x0000FFFF,
+ trueblnr, falseblnr, addr);
+ } else if (0 != (AccFlags & kATTA_ntfymask)) {
+ if (LocalMemAccessNtfy(p)) {
+ goto Label_Retry;
+ } else {
+ /* fail */
+ }
+ } else {
+ /* fail */
+ }
+ }
+}
+
+LOCALFUNC ui5r my_reg_call get_long_misaligned_ext(CPTR addr)
+{
+ ui5r hi = get_word(addr);
+ ui5r lo = get_word(addr + 2);
+ ui5r Data = ((hi << 16) & 0xFFFF0000)
+ | (lo & 0x0000FFFF);
+
+ return ui5r_FromSLong(Data);
+}
+
+LOCALPROC my_reg_call put_long_misaligned_ext(CPTR addr, ui5r l)
+{
+ put_word(addr, l >> 16);
+ put_word(addr + 2, l);
+}
+
+#if FasterAlignedL
+LOCALFUNC ui5r my_reg_call get_long_ext(CPTR addr)
+{
+ ui5r Data;
+
+ if (0 != (addr & 0x03)) {
+ ui5r hi = get_word(addr);
+ ui5r lo = get_word(addr + 2);
+ Data = ((hi << 16) & 0xFFFF0000)
+ | (lo & 0x0000FFFF);
+ } else {
+ ATTep p;
+ ui3p m;
+ ui5r AccFlags;
+
+Label_Retry:
+ p = LocalFindATTel(addr);
+ AccFlags = p->Access;
+
+ if (0 != (AccFlags & kATTA_readreadymask)) {
+ SetUpMATC(&V_regs.MATCrdL, p);
+ V_regs.MATCrdL.cmpmask |= 0x03;
+ m = p->usebase + (addr & p->usemask);
+ Data = do_get_mem_long(m);
+ } else if (0 != (AccFlags & kATTA_mmdvmask)) {
+ ui5r hi = LocalMMDV_Access(p, 0,
+ falseblnr, falseblnr, addr);
+ ui5r lo = LocalMMDV_Access(p, 0,
+ falseblnr, falseblnr, addr + 2);
+ Data = ((hi << 16) & 0xFFFF0000)
+ | (lo & 0x0000FFFF);
+ } else if (0 != (AccFlags & kATTA_ntfymask)) {
+ if (LocalMemAccessNtfy(p)) {
+ goto Label_Retry;
+ } else {
+ Data = 0; /* fail */
+ }
+ } else {
+ Data = 0; /* fail */
+ }
+ }
+
+ return ui5r_FromSLong(Data);
+}
+#endif
+
+#if FasterAlignedL
+LOCALPROC my_reg_call put_long_ext(CPTR addr, ui5r l)
+{
+ if (0 != (addr & 0x03)) {
+ put_word(addr, l >> 16);
+ put_word(addr + 2, l);
+ } else {
+ ATTep p;
+ ui3p m;
+ ui5r AccFlags;
+
+Label_Retry:
+ p = LocalFindATTel(addr);
+ AccFlags = p->Access;
+
+ if (0 != (AccFlags & kATTA_writereadymask)) {
+ SetUpMATC(&V_regs.MATCwrL, p);
+ V_regs.MATCwrL.cmpmask |= 0x03;
+ m = p->usebase + (addr & p->usemask);
+ do_put_mem_long(m, l);
+ } else if (0 != (AccFlags & kATTA_mmdvmask)) {
+ (void) LocalMMDV_Access(p, (l >> 16) & 0x0000FFFF,
+ trueblnr, falseblnr, addr);
+ (void) LocalMMDV_Access(p, l & 0x0000FFFF,
+ trueblnr, falseblnr, addr + 2);
+ } else if (0 != (AccFlags & kATTA_ntfymask)) {
+ if (LocalMemAccessNtfy(p)) {
+ goto Label_Retry;
+ } else {
+ /* fail */
+ }
+ } else {
+ /* fail */
+ }
+ }
+}
+#endif
+
+LOCALPROC Recalc_PC_Block(void)
+{
+ ATTep p;
+ CPTR curpc = m68k_getpc();
+
+Label_Retry:
+ p = LocalFindATTel(curpc);
+ if (my_cond_rare(0 == (p->Access & kATTA_readreadymask))) {
+ if (0 != (p->Access & kATTA_ntfymask)) {
+ if (LocalMemAccessNtfy(p)) {
+ goto Label_Retry;
+ }
+ }
+ /* in trouble if get here */
+#if ExtraAbnormalReports
+ ReportAbnormalID(0x0122, "Recalc_PC_Block fails");
+ /* happens on Restart */
+#endif
+
+ V_regs.pc_pLo = V_regs.fakeword;
+ V_pc_p = V_regs.pc_pLo;
+ V_pc_pHi = V_regs.pc_pLo + 2;
+ V_regs.pc = curpc;
+ } else {
+ ui5r m2 = p->usemask & ~ p->cmpmask;
+ m2 = m2 & ~ (m2 + 1);
+
+ V_pc_p = p->usebase + (curpc & p->usemask);
+ V_regs.pc_pLo = V_pc_p - (curpc & m2);
+ V_pc_pHi = V_regs.pc_pLo + m2 + 1;
+ V_regs.pc = curpc - (V_pc_p - V_regs.pc_pLo);
+ }
+}
+
+LOCALFUNC ui5r my_reg_call Recalc_PC_BlockReturnUi5r(ui5r v)
+{
+ /*
+ Used to prevent compiler from saving
+ register on the stack in calling
+ functions, when Recalc_PC_Block isn't being called.
+ */
+ Recalc_PC_Block();
+
+ return v;
+}
+
+LOCALFUNC ui5r nextilong_ext(void)
+{
+ ui5r r;
+
+ V_pc_p -= 4;
+
+ {
+ ui5r hi = nextiword();
+ ui5r lo = nextiword();
+ r = ((hi << 16) & 0xFFFF0000)
+ | (lo & 0x0000FFFF);
+ }
+
+ return r;
+}
+
+LOCALPROC DoCheckExternalInterruptPending(void)
+{
+ ui3r level = *V_regs.fIPL;
+ if ((level > V_regs.intmask) || (level == 7)) {
+#if WantCloserCyc
+ V_MaxCyclesToGo -=
+ (44 * kCycleScale + 5 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
+#endif
+ Exception(24 + level);
+ V_regs.intmask = level;
+ }
+}
+
+LOCALPROC do_trace(void)
+{
+ V_regs.TracePending = trueblnr;
+ NeedToGetOut();
+}
+
+GLOBALPROC m68k_go_nCycles(ui5b n)
+{
+ Em_Enter();
+ V_MaxCyclesToGo += (n + V_regs.ResidualCycles);
+ while (V_MaxCyclesToGo > 0) {
+
+#if 0
+ if (V_regs.ResetPending) {
+ m68k_DoReset();
+ }
+#endif
+ if (V_regs.TracePending) {
+#if WantCloserCyc
+ V_MaxCyclesToGo -= (34 * kCycleScale
+ + 4 * RdAvgXtraCyc + 3 * WrAvgXtraCyc);
+#endif
+ Exception(9);
+ }
+ if (V_regs.ExternalInterruptPending) {
+ V_regs.ExternalInterruptPending = falseblnr;
+ DoCheckExternalInterruptPending();
+ }
+ if (V_regs.t1 != 0) {
+ do_trace();
+ }
+ m68k_go_MaxCycles();
+ V_MaxCyclesToGo += V_regs.MoreCyclesToGo;
+ V_regs.MoreCyclesToGo = 0;
+ }
+
+ V_regs.ResidualCycles = V_MaxCyclesToGo;
+ V_MaxCyclesToGo = 0;
+ Em_Exit();
+}
+
+GLOBALFUNC si5r GetCyclesRemaining(void)
+{
+ si5r v;
+
+ Em_Enter();
+ v = V_regs.MoreCyclesToGo + V_MaxCyclesToGo;
+ Em_Exit();
+
+ return v;
+}
+
+GLOBALPROC SetCyclesRemaining(si5r n)
+{
+ Em_Enter();
+
+ if (V_MaxCyclesToGo >= n) {
+ V_regs.MoreCyclesToGo = 0;
+ V_MaxCyclesToGo = n;
+ } else {
+ V_regs.MoreCyclesToGo = n - V_MaxCyclesToGo;
+ }
+
+ Em_Exit();
+}
+
+GLOBALFUNC ATTep FindATTel(CPTR addr)
+{
+ ATTep v;
+
+ Em_Enter();
+ v = LocalFindATTel(addr);
+ Em_Exit();
+
+ return v;
+}
+
+GLOBALFUNC ui3r get_vm_byte(CPTR addr)
+{
+ ui3r v;
+
+ Em_Enter();
+ v = (ui3b) get_byte(addr);
+ Em_Exit();
+
+ return v;
+}
+
+GLOBALFUNC ui4r get_vm_word(CPTR addr)
+{
+ ui4r v;
+
+ Em_Enter();
+ v = (ui4b) get_word(addr);
+ Em_Exit();
+
+ return v;
+}
+
+GLOBALFUNC ui5r get_vm_long(CPTR addr)
+{
+ ui5r v;
+
+ Em_Enter();
+ v = (ui5b) get_long(addr);
+ Em_Exit();
+
+ return v;
+}
+
+GLOBALPROC put_vm_byte(CPTR addr, ui3r b)
+{
+ Em_Enter();
+ put_byte(addr, ui5r_FromSByte(b));
+ Em_Exit();
+}
+
+GLOBALPROC put_vm_word(CPTR addr, ui4r w)
+{
+ Em_Enter();
+ put_word(addr, ui5r_FromSWord(w));
+ Em_Exit();
+}
+
+GLOBALPROC put_vm_long(CPTR addr, ui5r l)
+{
+ Em_Enter();
+ put_long(addr, ui5r_FromSLong(l));
+ Em_Exit();
+}
+
+GLOBALPROC SetHeadATTel(ATTep p)
+{
+ Em_Enter();
+
+ V_regs.MATCrdB.cmpmask = 0;
+ V_regs.MATCrdB.cmpvalu = 0xFFFFFFFF;
+ V_regs.MATCwrB.cmpmask = 0;
+ V_regs.MATCwrB.cmpvalu = 0xFFFFFFFF;
+ V_regs.MATCrdW.cmpmask = 0;
+ V_regs.MATCrdW.cmpvalu = 0xFFFFFFFF;
+ V_regs.MATCwrW.cmpmask = 0;
+ V_regs.MATCwrW.cmpvalu = 0xFFFFFFFF;
+#if FasterAlignedL
+ V_regs.MATCrdL.cmpmask = 0;
+ V_regs.MATCrdL.cmpvalu = 0xFFFFFFFF;
+ V_regs.MATCwrL.cmpmask = 0;
+ V_regs.MATCwrL.cmpvalu = 0xFFFFFFFF;
+#endif
+ /* force Recalc_PC_Block soon */
+ V_regs.pc = m68k_getpc();
+ V_regs.pc_pLo = V_pc_p;
+ V_pc_pHi = V_regs.pc_pLo + 2;
+ V_regs.HeadATTel = p;
+
+ Em_Exit();
+}
+
+GLOBALPROC DiskInsertedPsuedoException(CPTR newpc, ui5b data)
+{
+ Em_Enter();
+ ExceptionTo(newpc
+#if Use68020
+ , 0
+#endif
+ );
+ m68k_areg(7) -= 4;
+ put_long(m68k_areg(7), data);
+ Em_Exit();
+}
+
+GLOBALPROC m68k_IPLchangeNtfy(void)
+{
+ Em_Enter();
+ {
+ ui3r level = *V_regs.fIPL;
+
+ if ((level > V_regs.intmask) || (level == 7)) {
+ SetExternalInterruptPending();
+ }
+ }
+ Em_Exit();
+}
+
+#if WantDumpTable
+LOCALPROC InitDumpTable(void)
+{
+ si5b i;
+
+ for (i = 0; i < kNumIKinds; ++i) {
+ DumpTable[i] = 0;
+ }
+}
+
+LOCALPROC DumpATable(ui5b *p, ui5b n)
+{
+ si5b i;
+
+ for (i = 0; i < n; ++i) {
+ dbglog_writeNum(p[i]);
+ dbglog_writeReturn();
+ }
+}
+
+EXPORTPROC DoDumpTable(void);
+GLOBALPROC DoDumpTable(void)
+{
+ DumpATable(DumpTable, kNumIKinds);
+}
+#endif
+
+GLOBALPROC m68k_reset(void)
+{
+ Em_Enter();
+
+#if WantDumpTable
+ InitDumpTable();
+#endif
+ V_MaxCyclesToGo = 0;
+ V_regs.MoreCyclesToGo = 0;
+ V_regs.ResidualCycles = 0;
+ V_pc_p = (ui3p)nullpr;
+ V_pc_pHi = (ui3p)nullpr;
+ V_regs.pc_pLo = (ui3p)nullpr;
+
+ do_put_mem_word(V_regs.fakeword, 0x4AFC);
+ /* illegal instruction opcode */
+
+#if 0
+ V_regs.ResetPending = trueblnr;
+ NeedToGetOut();
+#else
+/* Sets the MC68000 reset jump vector... */
+ m68k_setpc(get_long(0x00000004));
+
+/* Sets the initial stack vector... */
+ m68k_areg(7) = get_long(0x00000000);
+
+ V_regs.s = 1;
+#if Use68020
+ V_regs.m = 0;
+ V_regs.t0 = 0;
+#endif
+ V_regs.t1 = 0;
+ ZFLG = CFLG = NFLG = VFLG = 0;
+
+ V_regs.LazyFlagKind = kLazyFlagsDefault;
+ V_regs.LazyXFlagKind = kLazyFlagsDefault;
+
+ V_regs.ExternalInterruptPending = falseblnr;
+ V_regs.TracePending = falseblnr;
+ V_regs.intmask = 7;
+
+#if Use68020
+ V_regs.sfc = 0;
+ V_regs.dfc = 0;
+ V_regs.vbr = 0;
+ V_regs.cacr = 0;
+ V_regs.caar = 0;
+#endif
+#endif
+
+ Em_Exit();
+}
+
+#if SmallGlobals
+GLOBALPROC MINEM68K_ReserveAlloc(void)
+{
+ ReserveAllocOneBlock((ui3p *)®s.disp_table,
+ disp_table_sz * 8, 6, falseblnr);
+}
+#endif
+
+GLOBALPROC MINEM68K_Init(
+ ui3b *fIPL)
+{
+ regs.fIPL = fIPL;
+#ifdef r_regs
+ regs.save_regs = ®s;
+#endif
+
+ M68KITAB_setup(regs.disp_table);
+}
--- /dev/null
+++ b/src/MINEM68K.h
@@ -1,0 +1,53 @@
+/*
+ MINEM68K.h
+
+ Copyright (C) 2004 Bernd Schmidt, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef MINEM68K_H
+#error "header already included"
+#else
+#define MINEM68K_H
+#endif
+
+EXPORTPROC MINEM68K_Init(
+ ui3b *fIPL);
+#if SmallGlobals
+EXPORTPROC MINEM68K_ReserveAlloc(void);
+#endif
+
+EXPORTPROC m68k_IPLchangeNtfy(void);
+EXPORTPROC DiskInsertedPsuedoException(CPTR newpc, ui5b data);
+EXPORTPROC m68k_reset(void);
+
+EXPORTFUNC si5r GetCyclesRemaining(void);
+EXPORTPROC SetCyclesRemaining(si5r n);
+
+EXPORTPROC m68k_go_nCycles(ui5b n);
+
+/*
+ general purpose access of address space
+ of emulated computer. (memory and
+ memory mapped hardware.)
+*/
+
+EXPORTFUNC ui3r get_vm_byte(CPTR addr);
+EXPORTFUNC ui4r get_vm_word(CPTR addr);
+EXPORTFUNC ui5r get_vm_long(CPTR addr);
+
+EXPORTPROC put_vm_byte(CPTR addr, ui3r b);
+EXPORTPROC put_vm_word(CPTR addr, ui4r w);
+EXPORTPROC put_vm_long(CPTR addr, ui5r l);
+
+EXPORTPROC SetHeadATTel(ATTep p);
+EXPORTFUNC ATTep FindATTel(CPTR addr);
--- /dev/null
+++ b/src/MOUSEMDV.c
@@ -1,0 +1,129 @@
+/*
+ MOUSEMDV.c
+
+ Copyright (C) 2006 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ MOUSe EMulated DeVice
+
+ Emulation of the mouse in the Mac Plus.
+
+ This code descended from "Mouse-MacOS.c" in Richard F. Bannister's
+ Macintosh port of vMac, by Philip Cummins.
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+#include "MYOSGLUE.h"
+#include "ENDIANAC.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#include "SCCEMDEV.h"
+#include "MINEM68K.h"
+#endif
+
+#include "MOUSEMDV.h"
+
+GLOBALPROC Mouse_Update(void)
+{
+#if HaveMasterMyEvtQLock
+ if (0 != MasterMyEvtQLock) {
+ --MasterMyEvtQLock;
+ }
+#endif
+
+ /*
+ Check mouse position first. After mouse button or key event,
+ can't process another mouse position until following tick,
+ otherwise button or key will be in wrong place.
+ */
+
+ /*
+ if start doing this too soon after boot,
+ will mess up memory check
+ */
+ if (Mouse_Enabled()) {
+ MyEvtQEl *p;
+
+ if (
+#if HaveMasterMyEvtQLock
+ (0 == MasterMyEvtQLock) &&
+#endif
+ (nullpr != (p = MyEvtQOutP())))
+ {
+#if EmClassicKbrd
+#if EnableMouseMotion
+ if (MyEvtQElKindMouseDelta == p->kind) {
+
+ if ((p->u.pos.h != 0) || (p->u.pos.v != 0)) {
+ put_ram_word(0x0828,
+ get_ram_word(0x0828) + p->u.pos.v);
+ put_ram_word(0x082A,
+ get_ram_word(0x082A) + p->u.pos.h);
+ put_ram_byte(0x08CE, get_ram_byte(0x08CF));
+ /* Tell MacOS to redraw the Mouse */
+ }
+ MyEvtQOutDone();
+ } else
+#endif
+#endif
+ if (MyEvtQElKindMousePos == p->kind) {
+ ui5r NewMouse = (p->u.pos.v << 16) | p->u.pos.h;
+
+ if (get_ram_long(0x0828) != NewMouse) {
+ put_ram_long(0x0828, NewMouse);
+ /* Set Mouse Position */
+ put_ram_long(0x082C, NewMouse);
+#if EmClassicKbrd
+ put_ram_byte(0x08CE, get_ram_byte(0x08CF));
+ /* Tell MacOS to redraw the Mouse */
+#else
+ put_ram_long(0x0830, NewMouse);
+ put_ram_byte(0x08CE, 0xFF);
+ /* Tell MacOS to redraw the Mouse */
+#endif
+ }
+ MyEvtQOutDone();
+ }
+ }
+ }
+
+#if EmClassicKbrd
+ {
+ MyEvtQEl *p;
+
+ if (
+#if HaveMasterMyEvtQLock
+ (0 == MasterMyEvtQLock) &&
+#endif
+ (nullpr != (p = MyEvtQOutP())))
+ {
+ if (MyEvtQElKindMouseButton == p->kind) {
+ MouseBtnUp = p->u.press.down ? 0 : 1;
+ MyEvtQOutDone();
+ MasterMyEvtQLock = 4;
+ }
+ }
+ }
+#endif
+}
+
+GLOBALPROC Mouse_EndTickNotify(void)
+{
+ if (Mouse_Enabled()) {
+ /* tell platform specific code where the mouse went */
+ CurMouseV = get_ram_word(0x082C);
+ CurMouseH = get_ram_word(0x082E);
+ }
+}
--- /dev/null
+++ b/src/MOUSEMDV.h
@@ -1,0 +1,24 @@
+/*
+ MOUSEMDV.h
+
+ Copyright (C) 2003 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef MOUSEMDV_H
+#error "header already included"
+#else
+#define MOUSEMDV_H
+#endif
+
+EXPORTPROC Mouse_Update(void);
+EXPORTPROC Mouse_EndTickNotify(void);
--- /dev/null
+++ b/src/MYOSGLUE.h
@@ -1,0 +1,441 @@
+/*
+ MYOSGLUE.h
+
+ Copyright (C) 2006 Philip Cummins, Richard F. Bannister,
+ Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ MY Operating System GLUE.
+
+ header file for operating system dependent code.
+ the same header is used for all platforms.
+
+ This code is descended from Richard F. Bannister's Macintosh
+ port of vMac, by Philip Cummins.
+*/
+
+#ifdef MYOSGLUE_H
+#ifndef AllFiles
+#error "header already included"
+#endif
+#else
+#define MYOSGLUE_H
+#endif
+
+
+#if WantAbnormalReports
+EXPORTOSGLUPROC WarnMsgAbnormalID(ui4r id);
+#endif
+
+#if dbglog_HAVE
+EXPORTOSGLUPROC dbglog_writeCStr(char *s);
+EXPORTOSGLUPROC dbglog_writeReturn(void);
+EXPORTOSGLUPROC dbglog_writeHex(ui5r x);
+EXPORTOSGLUPROC dbglog_writeNum(ui5r x);
+EXPORTOSGLUPROC dbglog_writeMacChar(ui3r x);
+EXPORTOSGLUPROC dbglog_writeln(char *s);
+EXPORTOSGLUPROC dbglog_writelnNum(char *s, simr v);
+#endif
+
+EXPORTOSGLUPROC ReserveAllocOneBlock(ui3p *p, uimr n, ui3r align,
+ blnr FillOnes);
+
+EXPORTOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount);
+
+
+EXPORTVAR(ui3p, ROM)
+
+/*
+ error codes returned by Mini vMac extensions
+ (passed back to the emulated 68k code).
+*/
+
+#define tMacErr ui4r
+
+#define mnvm_noErr ((tMacErr) 0x0000)
+ /* (ui4b) 0 - No Error */
+#define mnvm_miscErr ((tMacErr) 0xFFFF)
+ /* (ui4b) - 1 - Should probably replace these */
+#define mnvm_controlErr ((tMacErr) 0xFFEF)
+ /* (ui4b) - 17 - I/O System Errors */
+#define mnvm_statusErr ((tMacErr) 0xFFEE)
+ /* (ui4b) - 18 - Driver can't respond to Status call */
+#define mnvm_closErr ((tMacErr) 0xFFE8)
+ /* (ui4b) - 24 - I/O System Errors */
+#define mnvm_eofErr ((tMacErr) 0xFFD9)
+ /* (ui4b) - 39 - End of file */
+#define mnvm_tmfoErr ((tMacErr) 0xFFD6)
+ /* (ui4b) - 42 - too many files open */
+#define mnvm_fnfErr ((tMacErr) 0xFFD5)
+ /* (ui4b) - 43 - File not found */
+#define mnvm_wPrErr ((tMacErr) 0xFFD4)
+ /* (ui4b) - 44 - diskette is write protected */
+#define mnvm_vLckdErr ((tMacErr) 0xFFD2)
+ /* (ui4b) - 46 - volume is locked */
+#define mnvm_dupFNErr ((tMacErr) 0xFFD0)
+ /* (ui4b) - 48 - duplicate filename */
+#define mnvm_opWrErr ((tMacErr) 0xFFCF)
+ /* (ui4b) - 49 - file already open with with write permission */
+#define mnvm_paramErr ((tMacErr) 0xFFCE)
+ /* (ui4b) - 50 - error in parameter list */
+#define mnvm_permErr ((tMacErr) 0xFFCA)
+ /* (ui4b) - 54 - permissions error (on file open) */
+#define mnvm_nsDrvErr ((tMacErr) 0xFFC8)
+ /* (ui4b) - 56 - No Such Drive */
+#define mnvm_wrPermErr ((tMacErr) 0xFFC3)
+ /* (ui4b) - 61 - write permissions error */
+#define mnvm_offLinErr ((tMacErr) 0xFFBF)
+ /* (ui4b) - 65 - off-line drive */
+#define mnvm_dirNFErr ((tMacErr) 0xFF88)
+ /* (ui4b) - 120 - directory not found */
+#define mnvm_afpAccessDenied ((tMacErr) 0xEC78)
+ /* (ui4b) - 5000 - Insufficient access privileges for operation */
+
+#if IncludePbufs
+
+#define tPbuf ui4r
+
+#define NotAPbuf ((tPbuf)0xFFFF)
+
+EXPORTOSGLUFUNC tMacErr CheckPbuf(tPbuf Pbuf_No);
+EXPORTOSGLUFUNC tMacErr PbufGetSize(tPbuf Pbuf_No, ui5r *Count);
+
+EXPORTOSGLUFUNC tMacErr PbufNew(ui5b count, tPbuf *r);
+EXPORTOSGLUPROC PbufDispose(tPbuf i);
+EXPORTOSGLUPROC PbufTransfer(ui3p Buffer,
+ tPbuf i, ui5r offset, ui5r count, blnr IsWrite);
+
+#endif
+
+#define tDrive ui4r
+
+EXPORTVAR(ui5b, vSonyWritableMask)
+EXPORTVAR(ui5b, vSonyInsertedMask)
+
+#define vSonyIsInserted(Drive_No) \
+ ((vSonyInsertedMask & ((ui5b)1 << (Drive_No))) != 0)
+
+EXPORTOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer,
+ tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
+ ui5r *Sony_ActCount);
+EXPORTOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No);
+EXPORTOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count);
+
+EXPORTOSGLUFUNC blnr AnyDiskInserted(void);
+EXPORTOSGLUPROC DiskRevokeWritable(tDrive Drive_No);
+
+#if IncludeSonyRawMode
+EXPORTVAR(blnr, vSonyRawMode)
+#endif
+
+#if IncludeSonyNew
+EXPORTVAR(blnr, vSonyNewDiskWanted)
+EXPORTVAR(ui5b, vSonyNewDiskSize)
+EXPORTOSGLUFUNC tMacErr vSonyEjectDelete(tDrive Drive_No);
+#endif
+
+#if IncludeSonyNameNew
+EXPORTVAR(tPbuf, vSonyNewDiskName)
+#endif
+
+#if IncludeSonyGetName
+EXPORTOSGLUFUNC tMacErr vSonyGetName(tDrive Drive_No, tPbuf *r);
+#endif
+
+#if IncludeHostTextClipExchange
+EXPORTOSGLUFUNC tMacErr HTCEexport(tPbuf i);
+EXPORTOSGLUFUNC tMacErr HTCEimport(tPbuf *r);
+#endif
+
+EXPORTVAR(ui5b, OnTrueTime)
+
+EXPORTVAR(ui5b, CurMacDateInSeconds)
+#if AutoLocation
+EXPORTVAR(ui5b, CurMacLatitude)
+EXPORTVAR(ui5b, CurMacLongitude)
+#endif
+#if AutoTimeZone
+EXPORTVAR(ui5b, CurMacDelta)
+ /* (dlsDelta << 24) | (gmtDelta & 0x00FFFFFF) */
+#endif
+
+
+#define vMacScreenNumPixels \
+ ((long)vMacScreenHeight * (long)vMacScreenWidth)
+#define vMacScreenNumBits (vMacScreenNumPixels << vMacScreenDepth)
+#define vMacScreenNumBytes (vMacScreenNumBits / 8)
+#define vMacScreenBitWidth ((long)vMacScreenWidth << vMacScreenDepth)
+#define vMacScreenByteWidth (vMacScreenBitWidth / 8)
+
+#define vMacScreenMonoNumBytes (vMacScreenNumPixels / 8)
+#define vMacScreenMonoByteWidth ((long)vMacScreenWidth / 8)
+
+#if 0 != vMacScreenDepth
+EXPORTVAR(blnr, UseColorMode)
+EXPORTVAR(blnr, ColorModeWorks)
+#endif
+
+#if 0 != vMacScreenDepth
+EXPORTVAR(blnr, ColorMappingChanged)
+#endif
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+#define CLUT_size (1 << (1 << vMacScreenDepth))
+
+EXPORTVAR(ui4r, CLUT_reds[CLUT_size])
+EXPORTVAR(ui4r, CLUT_greens[CLUT_size])
+EXPORTVAR(ui4r, CLUT_blues[CLUT_size])
+#endif
+
+EXPORTVAR(blnr, EmVideoDisable)
+EXPORTVAR(si3b, EmLagTime)
+
+EXPORTOSGLUPROC Screen_OutputFrame(ui3p screencurrentbuff);
+EXPORTOSGLUPROC DoneWithDrawingForTick(void);
+
+EXPORTVAR(blnr, ForceMacOff)
+
+EXPORTVAR(blnr, WantMacInterrupt)
+
+EXPORTVAR(blnr, WantMacReset)
+
+EXPORTOSGLUFUNC blnr ExtraTimeNotOver(void);
+
+EXPORTVAR(ui3b, SpeedValue)
+
+#if EnableAutoSlow
+EXPORTVAR(blnr, WantNotAutoSlow)
+#endif
+
+/* where emulated machine thinks mouse is */
+EXPORTVAR(ui4b, CurMouseV)
+EXPORTVAR(ui4b, CurMouseH)
+
+#if EnableAutoSlow
+EXPORTVAR(ui5r, QuietTime)
+EXPORTVAR(ui5r, QuietSubTicks)
+
+#define QuietEnds() \
+{ \
+ QuietTime = 0; \
+ QuietSubTicks = 0; \
+}
+#else
+#define QuietEnds()
+#endif
+
+#if 3 == kLn2SoundSampSz
+#define trSoundSamp ui3r
+#define tbSoundSamp ui3b
+#define tpSoundSamp ui3p
+#define kCenterSound 0x80
+#elif 4 == kLn2SoundSampSz
+#define trSoundSamp ui4r
+#define tbSoundSamp ui4b
+#define tpSoundSamp ui4p
+#define kCenterSound 0x8000
+#else
+#error "unsupported kLn2SoundSampSz"
+#endif
+
+#if MySoundEnabled
+
+EXPORTOSGLUFUNC tpSoundSamp MySound_BeginWrite(ui4r n, ui4r *actL);
+EXPORTOSGLUPROC MySound_EndWrite(ui4r actL);
+
+/* 370 samples per tick = 22,254.54 per second */
+#endif
+
+#if EmLocalTalk
+
+#define LT_TxBfMxSz 1024
+EXPORTVAR(ui3p, LT_TxBuffer)
+EXPORTVAR(ui4r, LT_TxBuffSz)
+
+EXPORTOSGLUPROC LT_TransmitPacket(void);
+
+EXPORTVAR(ui3p, LT_RxBuffer)
+EXPORTVAR(ui5r, LT_RxBuffSz)
+
+EXPORTOSGLUPROC LT_ReceivePacket(void);
+
+#endif
+
+EXPORTOSGLUPROC WaitForNextTick(void);
+
+#define MyEvtQElKindKey 0
+#define MyEvtQElKindMouseButton 1
+#define MyEvtQElKindMousePos 2
+#define MyEvtQElKindMouseDelta 3
+
+struct MyEvtQEl {
+ /* expected size : 8 bytes */
+ ui3b kind;
+ ui3b pad[3];
+ union {
+ struct {
+ ui3b down;
+ ui3b key;
+ } press;
+ struct {
+ ui4b h;
+ ui4b v;
+ } pos;
+ } u;
+};
+typedef struct MyEvtQEl MyEvtQEl;
+
+EXPORTOSGLUFUNC MyEvtQEl * MyEvtQOutP(void);
+EXPORTOSGLUPROC MyEvtQOutDone(void);
+
+#define MKC_A 0x00
+#define MKC_B 0x0B
+#define MKC_C 0x08
+#define MKC_D 0x02
+#define MKC_E 0x0E
+#define MKC_F 0x03
+#define MKC_G 0x05
+#define MKC_H 0x04
+#define MKC_I 0x22
+#define MKC_J 0x26
+#define MKC_K 0x28
+#define MKC_L 0x25
+#define MKC_M 0x2E
+#define MKC_N 0x2D
+#define MKC_O 0x1F
+#define MKC_P 0x23
+#define MKC_Q 0x0C
+#define MKC_R 0x0F
+#define MKC_S 0x01
+#define MKC_T 0x11
+#define MKC_U 0x20
+#define MKC_V 0x09
+#define MKC_W 0x0D
+#define MKC_X 0x07
+#define MKC_Y 0x10
+#define MKC_Z 0x06
+
+#define MKC_1 0x12
+#define MKC_2 0x13
+#define MKC_3 0x14
+#define MKC_4 0x15
+#define MKC_5 0x17
+#define MKC_6 0x16
+#define MKC_7 0x1A
+#define MKC_8 0x1C
+#define MKC_9 0x19
+#define MKC_0 0x1D
+
+#define MKC_Command 0x37
+#define MKC_Shift 0x38
+#define MKC_CapsLock 0x39
+#define MKC_Option 0x3A
+
+#define MKC_Space 0x31
+#define MKC_Return 0x24
+#define MKC_BackSpace 0x33
+#define MKC_Tab 0x30
+
+#define MKC_Left /* 0x46 */ 0x7B
+#define MKC_Right /* 0x42 */ 0x7C
+#define MKC_Down /* 0x48 */ 0x7D
+#define MKC_Up /* 0x4D */ 0x7E
+
+#define MKC_Minus 0x1B
+#define MKC_Equal 0x18
+#define MKC_BackSlash 0x2A
+#define MKC_Comma 0x2B
+#define MKC_Period 0x2F
+#define MKC_Slash 0x2C
+#define MKC_SemiColon 0x29
+#define MKC_SingleQuote 0x27
+#define MKC_LeftBracket 0x21
+#define MKC_RightBracket 0x1E
+#define MKC_Grave 0x32
+#define MKC_Clear 0x47
+#define MKC_KPEqual 0x51
+#define MKC_KPDevide 0x4B
+#define MKC_KPMultiply 0x43
+#define MKC_KPSubtract 0x4E
+#define MKC_KPAdd 0x45
+#define MKC_Enter 0x4C
+
+#define MKC_KP1 0x53
+#define MKC_KP2 0x54
+#define MKC_KP3 0x55
+#define MKC_KP4 0x56
+#define MKC_KP5 0x57
+#define MKC_KP6 0x58
+#define MKC_KP7 0x59
+#define MKC_KP8 0x5B
+#define MKC_KP9 0x5C
+#define MKC_KP0 0x52
+#define MKC_Decimal 0x41
+
+/* these aren't on the Mac Plus keyboard */
+
+#define MKC_Control 0x3B
+#define MKC_Escape 0x35
+#define MKC_F1 0x7a
+#define MKC_F2 0x78
+#define MKC_F3 0x63
+#define MKC_F4 0x76
+#define MKC_F5 0x60
+#define MKC_F6 0x61
+#define MKC_F7 0x62
+#define MKC_F8 0x64
+#define MKC_F9 0x65
+#define MKC_F10 0x6d
+#define MKC_F11 0x67
+#define MKC_F12 0x6f
+
+#define MKC_Home 0x73
+#define MKC_End 0x77
+#define MKC_PageUp 0x74
+#define MKC_PageDown 0x79
+#define MKC_Help 0x72 /* = Insert */
+#define MKC_ForwardDel 0x75
+#define MKC_Print 0x69
+#define MKC_ScrollLock 0x6B
+#define MKC_Pause 0x71
+
+#define MKC_AngleBracket 0x0A /* found on german keyboard */
+
+/*
+ Additional codes found in Apple headers
+
+ #define MKC_RightShift 0x3C
+ #define MKC_RightOption 0x3D
+ #define MKC_RightControl 0x3E
+ #define MKC_Function 0x3F
+
+ #define MKC_VolumeUp 0x48
+ #define MKC_VolumeDown 0x49
+ #define MKC_Mute 0x4A
+
+ #define MKC_F16 0x6A
+ #define MKC_F17 0x40
+ #define MKC_F18 0x4F
+ #define MKC_F19 0x50
+ #define MKC_F20 0x5A
+
+ #define MKC_F13 MKC_Print
+ #define MKC_F14 MKC_ScrollLock
+ #define MKC_F15 MKC_Pause
+*/
+
+/* not Apple key codes, only for Mini vMac */
+
+#define MKC_CM 0x80
+#define MKC_None 0xFF
--- /dev/null
+++ b/src/OSGLUCCO.m
@@ -1,0 +1,4993 @@
+/*
+ OSGLUCCO.m
+
+ Copyright (C) 2012 Paul C. Pratt, SDL by Sam Lantinga and others
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Operating System GLUe for mac os CoCOa
+
+ All operating system dependent code for the
+ Mac OS Cocoa should go here.
+
+ Originally derived from Cocoa port of SDL Library
+ by Sam Lantinga (but little trace of that remains).
+*/
+
+#include "CNFGRAPI.h"
+#include "SYSDEPNS.h"
+#include "ENDIANAC.h"
+
+#include "MYOSGLUE.h"
+
+#include "STRCONST.h"
+
+/* --- adapting to API/ABI version differences --- */
+
+
+#ifndef MAC_OS_X_VERSION_10_5
+#define MAC_OS_X_VERSION_10_5 1050
+#endif
+
+#ifndef MAC_OS_X_VERSION_10_6
+#define MAC_OS_X_VERSION_10_6 1060
+#endif
+
+
+#ifndef WantGraphicsSwitching
+#define WantGraphicsSwitching 0
+#endif
+
+#if MAC_OS_X_VERSION_10_5 > MAC_OS_X_VERSION_MAX_ALLOWED
+
+typedef unsigned long NSUInteger;
+typedef long NSInteger;
+
+typedef struct __CFError * CFErrorRef;
+
+#if WantGraphicsSwitching
+#define NSOpenGLPFAAllowOfflineRenderers \
+ (NSOpenGLPixelFormatAttribute)96
+#endif
+
+#endif
+
+#if MAC_OS_X_VERSION_10_6 > MAC_OS_X_VERSION_MAX_ALLOWED
+
+@protocol NSWindowDelegate <NSObject> @end
+@protocol NSApplicationDelegate <NSObject> @end
+
+#endif
+
+
+LOCALVAR CFBundleRef AppServBunRef;
+
+LOCALVAR blnr DidApplicationServicesBun = falseblnr;
+
+LOCALFUNC blnr HaveApplicationServicesBun(void)
+{
+ if (! DidApplicationServicesBun) {
+ AppServBunRef = CFBundleGetBundleWithIdentifier(
+ CFSTR("com.apple.ApplicationServices"));
+ DidApplicationServicesBun = trueblnr;
+ }
+ return (AppServBunRef != NULL);
+}
+
+#if MayFullScreen
+
+LOCALVAR CFBundleRef HIToolboxBunRef;
+
+LOCALVAR blnr DidHIToolboxBunRef = falseblnr;
+
+LOCALFUNC blnr HaveHIToolboxBunRef(void)
+{
+ if (! DidHIToolboxBunRef) {
+ HIToolboxBunRef = CFBundleGetBundleWithIdentifier(
+ CFSTR("com.apple.HIToolbox"));
+ DidHIToolboxBunRef = trueblnr;
+ }
+ return (HIToolboxBunRef != NULL);
+}
+
+#endif
+
+
+#if MayFullScreen
+
+/* SetSystemUIModeProcPtr API always not available */
+
+typedef UInt32 MySystemUIMode;
+typedef OptionBits MySystemUIOptions;
+
+enum {
+ MykUIModeNormal = 0,
+ MykUIModeAllHidden = 3
+};
+
+enum {
+ MykUIOptionAutoShowMenuBar = 1 << 0,
+ MykUIOptionDisableAppleMenu = 1 << 2,
+ MykUIOptionDisableProcessSwitch = 1 << 3,
+ MykUIOptionDisableForceQuit = 1 << 4,
+ MykUIOptionDisableSessionTerminate = 1 << 5,
+ MykUIOptionDisableHide = 1 << 6
+};
+
+typedef OSStatus (*SetSystemUIModeProcPtr)
+ (MySystemUIMode inMode, MySystemUIOptions inOptions);
+LOCALVAR SetSystemUIModeProcPtr MySetSystemUIMode = NULL;
+LOCALVAR blnr DidSetSystemUIMode = falseblnr;
+
+LOCALFUNC blnr HaveMySetSystemUIMode(void)
+{
+ if (! DidSetSystemUIMode) {
+ if (HaveHIToolboxBunRef()) {
+ MySetSystemUIMode =
+ (SetSystemUIModeProcPtr)
+ CFBundleGetFunctionPointerForName(
+ HIToolboxBunRef, CFSTR("SetSystemUIMode"));
+ }
+ DidSetSystemUIMode = trueblnr;
+ }
+ return (MySetSystemUIMode != NULL);
+}
+
+#endif
+
+
+typedef Boolean (*CFURLCopyResourcePropertyForKeyProcPtr) (
+ CFURLRef url,
+ CFStringRef key,
+ void *propertyValueTypeRefPtr,
+ CFErrorRef *error
+ );
+LOCALVAR CFURLCopyResourcePropertyForKeyProcPtr
+ MyCFURLCopyResourcePropertyForKey = NULL;
+LOCALVAR blnr DidCFURLCopyResourcePropertyForKey = falseblnr;
+
+LOCALFUNC blnr HaveMyCFURLCopyResourcePropertyForKey(void)
+{
+ if (! DidCFURLCopyResourcePropertyForKey) {
+ if (HaveApplicationServicesBun()) {
+ MyCFURLCopyResourcePropertyForKey =
+ (CFURLCopyResourcePropertyForKeyProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef,
+ CFSTR("CFURLCopyResourcePropertyForKey"));
+ }
+ DidCFURLCopyResourcePropertyForKey = trueblnr;
+ }
+ return (MyCFURLCopyResourcePropertyForKey != NULL);
+}
+
+
+LOCALVAR const CFStringRef *MykCFURLIsAliasFileKey
+ = NULL;
+LOCALVAR blnr DidkCFURLIsAliasFileKey = falseblnr;
+
+LOCALFUNC blnr HaveMykCFURLIsAliasFileKey(void)
+{
+ if (! DidkCFURLIsAliasFileKey) {
+ if (HaveApplicationServicesBun()) {
+ MykCFURLIsAliasFileKey =
+ (const CFStringRef *)
+ CFBundleGetDataPointerForName(
+ AppServBunRef, CFSTR("kCFURLIsAliasFileKey"));
+ }
+ DidkCFURLIsAliasFileKey = trueblnr;
+ }
+ return (MykCFURLIsAliasFileKey != NULL);
+}
+
+
+LOCALVAR const CFStringRef *MykCFURLIsSymbolicLinkKey
+ = NULL;
+LOCALVAR blnr DidkCFURLIsSymbolicLinkKey = falseblnr;
+
+LOCALFUNC blnr HaveMykCFURLIsSymbolicLinkKey(void)
+{
+ if (! DidkCFURLIsSymbolicLinkKey) {
+ if (HaveApplicationServicesBun()) {
+ MykCFURLIsSymbolicLinkKey =
+ (const CFStringRef *)
+ CFBundleGetDataPointerForName(
+ AppServBunRef, CFSTR("kCFURLIsSymbolicLinkKey"));
+ }
+ DidkCFURLIsSymbolicLinkKey = trueblnr;
+ }
+ return (MykCFURLIsSymbolicLinkKey != NULL);
+}
+
+
+typedef CFDataRef (*CFURLCreateBookmarkDataFromFileProcPtr) (
+ CFAllocatorRef allocator, CFURLRef fileURL, CFErrorRef *errorRef);
+LOCALVAR CFURLCreateBookmarkDataFromFileProcPtr
+ MyCFURLCreateBookmarkDataFromFile = NULL;
+LOCALVAR blnr DidCFURLCreateBookmarkDataFromFile = falseblnr;
+
+LOCALFUNC blnr HaveMyCFURLCreateBookmarkDataFromFile(void)
+{
+ if (! DidCFURLCreateBookmarkDataFromFile) {
+ if (HaveApplicationServicesBun()) {
+ MyCFURLCreateBookmarkDataFromFile =
+ (CFURLCreateBookmarkDataFromFileProcPtr)
+ CFBundleGetFunctionPointerForName(AppServBunRef,
+ CFSTR("CFURLCreateBookmarkDataFromFile"));
+ }
+ DidCFURLCreateBookmarkDataFromFile = trueblnr;
+ }
+ return (MyCFURLCreateBookmarkDataFromFile != NULL);
+}
+
+
+typedef CFOptionFlags MyCFURLBookmarkResolutionOptions;
+
+typedef CFURLRef (*CFURLCreateByResolvingBookmarkDataProcPtr) (
+ CFAllocatorRef allocator, CFDataRef bookmark,
+ MyCFURLBookmarkResolutionOptions options, CFURLRef relativeToURL,
+ CFArrayRef resourcePropertiesToInclude,
+ Boolean* isStale, CFErrorRef* error);
+LOCALVAR CFURLCreateByResolvingBookmarkDataProcPtr
+ MyCFURLCreateByResolvingBookmarkData = NULL;
+LOCALVAR blnr DidCFURLCreateByResolvingBookmarkData = falseblnr;
+
+LOCALFUNC blnr HaveMyCFURLCreateByResolvingBookmarkData(void)
+{
+ if (! DidCFURLCreateByResolvingBookmarkData) {
+ if (HaveApplicationServicesBun()) {
+ MyCFURLCreateByResolvingBookmarkData =
+ (CFURLCreateByResolvingBookmarkDataProcPtr)
+ CFBundleGetFunctionPointerForName(AppServBunRef,
+ CFSTR("CFURLCreateByResolvingBookmarkData"));
+ }
+ DidCFURLCreateByResolvingBookmarkData = trueblnr;
+ }
+ return (MyCFURLCreateByResolvingBookmarkData != NULL);
+}
+
+
+typedef boolean_t (*CGCursorIsVisibleProcPtr)(void);
+
+LOCALVAR CGCursorIsVisibleProcPtr MyCGCursorIsVisible = NULL;
+LOCALVAR blnr DidCGCursorIsVisible = falseblnr;
+
+LOCALFUNC blnr HaveMyCGCursorIsVisible(void)
+{
+ if (! DidCGCursorIsVisible) {
+ if (HaveApplicationServicesBun()) {
+ MyCGCursorIsVisible =
+ (CGCursorIsVisibleProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("CGCursorIsVisible"));
+ }
+ DidCGCursorIsVisible = trueblnr;
+ }
+ return (MyCGCursorIsVisible != NULL);
+}
+
+
+/* --- some simple utilities --- */
+
+GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount)
+{
+ (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount);
+}
+
+/* --- control mode and internationalization --- */
+
+#define NeedCell2UnicodeMap 1
+
+#include "INTLCHAR.h"
+
+/* --- sending debugging info to file --- */
+
+LOCALVAR NSString *myAppName = nil;
+LOCALVAR NSString *MyDataPath = nil;
+
+#if dbglog_HAVE
+
+#define dbglog_ToStdErr 0
+
+#if ! dbglog_ToStdErr
+LOCALVAR FILE *dbglog_File = NULL;
+#endif
+
+LOCALFUNC blnr dbglog_open0(void)
+{
+#if dbglog_ToStdErr
+ return trueblnr;
+#else
+ NSString *myLogPath = [MyDataPath
+ stringByAppendingPathComponent: @"dbglog.txt"];
+ const char *path = [myLogPath fileSystemRepresentation];
+
+ dbglog_File = fopen(path, "w");
+ return (NULL != dbglog_File);
+#endif
+}
+
+LOCALPROC dbglog_write0(char *s, uimr L)
+{
+#if dbglog_ToStdErr
+ (void) fwrite(s, 1, L, stderr);
+#else
+ if (NULL != dbglog_File) {
+ (void) fwrite(s, 1, L, dbglog_File);
+ }
+#endif
+}
+
+LOCALPROC dbglog_close0(void)
+{
+#if ! dbglog_ToStdErr
+ if (NULL != dbglog_File) {
+ fclose(dbglog_File);
+ dbglog_File = NULL;
+ }
+#endif
+}
+
+#endif
+
+/* --- information about the environment --- */
+
+#define WantColorTransValid 1
+
+#include "COMOSGLU.h"
+
+#define WantKeyboard_RemapMac 1
+
+#include "PBUFSTDC.h"
+
+#include "CONTROLM.h"
+
+/* --- text translation --- */
+
+LOCALPROC UniCharStrFromSubstCStr(int *L, unichar *x, char *s)
+{
+ int i;
+ int L0;
+ ui3b ps[ClStrMaxLength];
+
+ ClStrFromSubstCStr(&L0, ps, s);
+
+ for (i = 0; i < L0; ++i) {
+ x[i] = Cell2UnicodeMap[ps[i]];
+ }
+
+ *L = L0;
+}
+
+LOCALFUNC NSString * NSStringCreateFromSubstCStr(char *s)
+{
+ int L;
+ unichar x[ClStrMaxLength];
+
+ UniCharStrFromSubstCStr(&L, x, s);
+
+ return [NSString stringWithCharacters:x length:L];
+}
+
+#if IncludeSonyNameNew
+LOCALFUNC blnr MacRomanFileNameToNSString(tPbuf i,
+ NSString **r)
+{
+ ui3p p;
+ void *Buffer = PbufDat[i];
+ ui5b L = PbufSize[i];
+
+ p = (ui3p)malloc(L /* + 1 */);
+ if (p != NULL) {
+ NSData *d;
+ ui3b *p0 = (ui3b *)Buffer;
+ ui3b *p1 = (ui3b *)p;
+
+ if (L > 0) {
+ ui5b j = L;
+
+ do {
+ ui3b x = *p0++;
+ if (x < 32) {
+ x = '-';
+ } else if (x >= 128) {
+ } else {
+ switch (x) {
+ case '/':
+ case '<':
+ case '>':
+ case '|':
+ case ':':
+ x = '-';
+ default:
+ break;
+ }
+ }
+ *p1++ = x;
+ } while (--j > 0);
+
+ if ('.' == p[0]) {
+ p[0] = '-';
+ }
+ }
+
+#if 0
+ *p1 = 0;
+ *r = [NSString stringWithCString:(char *)p
+ encoding:NSMacOSRomanStringEncoding];
+ /* only as of OS X 10.4 */
+ free(p);
+#endif
+
+ d = [[NSData alloc] initWithBytesNoCopy:p length:L];
+
+ *r = [[[NSString alloc]
+ initWithData:d encoding:NSMacOSRomanStringEncoding]
+ autorelease];
+
+ [d release];
+
+ return trueblnr;
+ }
+
+ return falseblnr;
+}
+#endif
+
+#if IncludeSonyGetName || IncludeHostTextClipExchange
+LOCALFUNC tMacErr NSStringToRomanPbuf(NSString *string, tPbuf *r)
+{
+ tMacErr v = mnvm_miscErr;
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+#if 0
+ const char *s = [s0
+ cStringUsingEncoding: NSMacOSRomanStringEncoding];
+ ui5r L = strlen(s);
+ /* only as of OS X 10.4 */
+#endif
+#if 0
+ NSData *d0 = [string dataUsingEncoding: NSMacOSRomanStringEncoding];
+#endif
+ NSData *d0 = [string dataUsingEncoding: NSMacOSRomanStringEncoding
+ allowLossyConversion: YES];
+ const void *s = [d0 bytes];
+ NSUInteger L = [d0 length];
+
+ if (NULL == s) {
+ v = mnvm_miscErr;
+ } else {
+ ui3p p = (ui3p)malloc(L);
+
+ if (NULL == p) {
+ v = mnvm_miscErr;
+ } else {
+ /* memcpy((char *)p, s, L); */
+ ui3b *p0 = (ui3b *)s;
+ ui3b *p1 = (ui3b *)p;
+ int i;
+
+ for (i = L; --i >= 0; ) {
+ ui3b v = *p0++;
+ if (10 == v) {
+ v = 13;
+ }
+ *p1++ = v;
+ }
+
+ v = PbufNewFromPtr(p, L, r);
+ }
+ }
+
+ [pool release];
+
+ return v;
+}
+#endif
+
+/* --- drives --- */
+
+LOCALFUNC blnr FindNamedChildPath(NSString *parentPath,
+ char *ChildName, NSString **childPath)
+{
+ blnr v = falseblnr;
+
+#if 0
+ NSString *ss = [NSString stringWithCString:s
+ encoding:NSASCIIStringEncoding];
+ /* only as of OS X 10.4 */
+#endif
+#if 0
+ NSData *d = [NSData dataWithBytes: ChildName
+ length: strlen(ChildName)];
+ NSString *ss = [[[NSString alloc]
+ initWithData:d encoding:NSASCIIStringEncoding]
+ autorelease];
+#endif
+ NSString *ss = NSStringCreateFromSubstCStr(ChildName);
+ if (nil != ss) {
+ NSString *r = [parentPath stringByAppendingPathComponent: ss];
+ if (nil != r) {
+ *childPath = r;
+ v = trueblnr;
+ }
+ }
+
+ return v;
+}
+
+LOCALFUNC NSString *MyResolveAlias(NSString *filePath,
+ Boolean *targetIsFolder)
+{
+ NSString *resolvedPath = nil;
+ CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
+ (CFStringRef)filePath, kCFURLPOSIXPathStyle, NO);
+
+
+ if (url != NULL) {
+ if (HaveMyCFURLCopyResourcePropertyForKey()
+ && HaveMykCFURLIsAliasFileKey()
+ && HaveMykCFURLIsSymbolicLinkKey()
+ && HaveMyCFURLCreateBookmarkDataFromFile()
+ && HaveMyCFURLCreateByResolvingBookmarkData())
+ {
+ BOOL isDir;
+ Boolean isStale;
+ CFBooleanRef is_alias_file = NULL;
+ CFBooleanRef is_symbolic_link = NULL;
+ CFDataRef bookmark = NULL;
+ CFURLRef resolvedurl = NULL;
+
+ if (MyCFURLCopyResourcePropertyForKey(url,
+ *MykCFURLIsAliasFileKey, &is_alias_file, NULL))
+ if (CFBooleanGetValue(is_alias_file))
+ if (MyCFURLCopyResourcePropertyForKey(url,
+ *MykCFURLIsSymbolicLinkKey, &is_symbolic_link, NULL))
+ if (! CFBooleanGetValue(is_symbolic_link))
+ if (NULL != (bookmark = MyCFURLCreateBookmarkDataFromFile(
+ kCFAllocatorDefault, url, NULL)))
+ if (NULL != (resolvedurl =
+ MyCFURLCreateByResolvingBookmarkData(
+ kCFAllocatorDefault,
+ bookmark,
+ 0 /* MyCFURLBookmarkResolutionOptions options */,
+ NULL /* relativeToURL */,
+ NULL /* resourcePropertiesToInclude */,
+ &isStale,
+ NULL /* error */)))
+ if (nil != (resolvedPath =
+ (NSString *)CFURLCopyFileSystemPath(
+ resolvedurl, kCFURLPOSIXPathStyle)))
+ {
+ if ([[NSFileManager defaultManager]
+ fileExistsAtPath: resolvedPath isDirectory: &isDir])
+ {
+ *targetIsFolder = isDir;
+ } else
+ {
+ *targetIsFolder = FALSE;
+ }
+
+ [resolvedPath autorelease];
+ }
+
+ if (NULL != resolvedurl) {
+ CFRelease(resolvedurl);
+ }
+ if (NULL != bookmark) {
+ CFRelease(bookmark);
+ }
+ if (NULL != is_alias_file) {
+ CFRelease(is_alias_file);
+ }
+ if (NULL != is_symbolic_link) {
+ CFRelease(is_symbolic_link);
+ }
+ } else {
+ FSRef fsRef;
+ Boolean wasAliased;
+
+ if (CFURLGetFSRef(url, &fsRef)) {
+ /*
+ FSResolveAliasFile deprecated in 10.8
+ */
+
+ if ((FSResolveAliasFile(&fsRef,
+ TRUE /*resolveAliasChains*/,
+ targetIsFolder, &wasAliased) == noErr)
+ && wasAliased)
+ {
+ CFURLRef resolvedurl =
+ CFURLCreateFromFSRef(kCFAllocatorDefault,
+ &fsRef);
+ if (resolvedurl != NULL) {
+ resolvedPath =
+ (NSString *)CFURLCopyFileSystemPath(
+ resolvedurl, kCFURLPOSIXPathStyle);
+ [resolvedPath autorelease];
+ CFRelease(resolvedurl);
+ }
+ }
+ }
+ }
+
+ CFRelease(url);
+ }
+
+ return resolvedPath;
+}
+
+LOCALFUNC blnr FindNamedChildDirPath(NSString *parentPath,
+ char *ChildName, NSString **childPath)
+{
+ NSString *r;
+ BOOL isDir;
+ Boolean isDirectory;
+ blnr v = falseblnr;
+
+ if (FindNamedChildPath(parentPath, ChildName, &r))
+ if ([[NSFileManager defaultManager]
+ fileExistsAtPath:r isDirectory: &isDir])
+ {
+ if (isDir) {
+ *childPath = r;
+ v = trueblnr;
+ } else {
+ NSString *RslvPath = MyResolveAlias(r, &isDirectory);
+ if (nil != RslvPath) {
+ if (isDirectory) {
+ *childPath = RslvPath;
+ v = trueblnr;
+ }
+ }
+ }
+ }
+
+ return v;
+}
+
+LOCALFUNC blnr FindNamedChildFilePath(NSString *parentPath,
+ char *ChildName, NSString **childPath)
+{
+ NSString *r;
+ BOOL isDir;
+ Boolean isDirectory;
+ blnr v = falseblnr;
+
+ if (FindNamedChildPath(parentPath, ChildName, &r))
+ if ([[NSFileManager defaultManager]
+ fileExistsAtPath:r isDirectory: &isDir])
+ {
+ if (! isDir) {
+ NSString *RslvPath = MyResolveAlias(r, &isDirectory);
+ if (nil != RslvPath) {
+ if (! isDirectory) {
+ *childPath = RslvPath;
+ v = trueblnr;
+ }
+ } else {
+ *childPath = r;
+ v = trueblnr;
+ }
+ }
+ }
+
+ return v;
+}
+
+
+#define NotAfileRef NULL
+
+LOCALVAR FILE *Drives[NumDrives]; /* open disk image files */
+#if IncludeSonyGetName || IncludeSonyNew
+LOCALVAR NSString *DriveNames[NumDrives];
+#endif
+
+LOCALPROC InitDrives(void)
+{
+ /*
+ This isn't really needed, Drives[i] and DriveNames[i]
+ need not have valid values when not vSonyIsInserted[i].
+ */
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ Drives[i] = NotAfileRef;
+#if IncludeSonyGetName || IncludeSonyNew
+ DriveNames[i] = nil;
+#endif
+ }
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer,
+ tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
+ ui5r *Sony_ActCount)
+{
+ tMacErr err = mnvm_miscErr;
+ FILE *refnum = Drives[Drive_No];
+ ui5r NewSony_Count = 0;
+
+ if (0 == fseek(refnum, Sony_Start, SEEK_SET)) {
+ if (IsWrite) {
+ NewSony_Count = fwrite(Buffer, 1, Sony_Count, refnum);
+ } else {
+ NewSony_Count = fread(Buffer, 1, Sony_Count, refnum);
+ }
+
+ if (NewSony_Count == Sony_Count) {
+ err = mnvm_noErr;
+ }
+ }
+
+ if (nullpr != Sony_ActCount) {
+ *Sony_ActCount = NewSony_Count;
+ }
+
+ return err; /*& figure out what really to return &*/
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count)
+{
+ tMacErr err = mnvm_miscErr;
+ FILE *refnum = Drives[Drive_No];
+ long v;
+
+ if (0 == fseek(refnum, 0, SEEK_END)) {
+ v = ftell(refnum);
+ if (v >= 0) {
+ *Sony_Count = v;
+ err = mnvm_noErr;
+ }
+ }
+
+ return err; /*& figure out what really to return &*/
+}
+
+#ifndef HaveAdvisoryLocks
+#define HaveAdvisoryLocks 1
+#endif
+
+/*
+ What is the difference between fcntl(fd, F_SETLK ...
+ and flock(fd ... ?
+*/
+
+#if HaveAdvisoryLocks
+LOCALFUNC blnr MyLockFile(FILE *refnum)
+{
+ blnr IsOk = falseblnr;
+
+#if 0
+ struct flock fl;
+ int fd = fileno(refnum);
+
+ fl.l_start = 0; /* starting offset */
+ fl.l_len = 0; /* len = 0 means until end of file */
+ /* fl.pid_t l_pid; */ /* lock owner, don't need to set */
+ fl.l_type = F_WRLCK; /* lock type: read/write, etc. */
+ fl.l_whence = SEEK_SET; /* type of l_start */
+ if (-1 == fcntl(fd, F_SETLK, &fl)) {
+ MacMsg(kStrImageInUseTitle, kStrImageInUseMessage,
+ falseblnr);
+ } else {
+ IsOk = trueblnr;
+ }
+#else
+ int fd = fileno(refnum);
+
+ if (-1 == flock(fd, LOCK_EX | LOCK_NB)) {
+ if (EWOULDBLOCK == errno) {
+ /* already locked */
+ MacMsg(kStrImageInUseTitle, kStrImageInUseMessage,
+ falseblnr);
+ } else
+ {
+ /*
+ Failed for other reasons, such as unsupported
+ for this volume.
+ Don't prevent opening.
+ */
+ IsOk = trueblnr;
+ }
+ } else {
+ IsOk = trueblnr;
+ }
+#endif
+
+ return IsOk;
+}
+#endif
+
+#if HaveAdvisoryLocks
+LOCALPROC MyUnlockFile(FILE *refnum)
+{
+#if 0
+ struct flock fl;
+ int fd = fileno(refnum);
+
+ fl.l_start = 0; /* starting offset */
+ fl.l_len = 0; /* len = 0 means until end of file */
+ /* fl.pid_t l_pid; */ /* lock owner, don't need to set */
+ fl.l_type = F_UNLCK; /* lock type: read/write, etc. */
+ fl.l_whence = SEEK_SET; /* type of l_start */
+ if (-1 == fcntl(fd, F_SETLK, &fl)) {
+ /* an error occurred */
+ }
+#else
+ int fd = fileno(refnum);
+
+ if (-1 == flock(fd, LOCK_UN)) {
+ }
+#endif
+}
+#endif
+
+LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit)
+{
+ FILE *refnum = Drives[Drive_No];
+
+ DiskEjectedNotify(Drive_No);
+
+#if HaveAdvisoryLocks
+ MyUnlockFile(refnum);
+#endif
+
+ fclose(refnum);
+ Drives[Drive_No] = NotAfileRef; /* not really needed */
+
+#if IncludeSonyGetName || IncludeSonyNew
+ {
+ NSString *filePath = DriveNames[Drive_No];
+ if (NULL != filePath) {
+ if (deleteit) {
+ NSAutoreleasePool *pool =
+ [[NSAutoreleasePool alloc] init];
+ const char *s = [filePath fileSystemRepresentation];
+ remove(s);
+ [pool release];
+ }
+ [filePath release];
+ DriveNames[Drive_No] = NULL; /* not really needed */
+ }
+ }
+#endif
+
+ return mnvm_noErr;
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No)
+{
+ return vSonyEject0(Drive_No, falseblnr);
+}
+
+#if IncludeSonyNew
+GLOBALOSGLUFUNC tMacErr vSonyEjectDelete(tDrive Drive_No)
+{
+ return vSonyEject0(Drive_No, trueblnr);
+}
+#endif
+
+LOCALPROC UnInitDrives(void)
+{
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ if (vSonyIsInserted(i)) {
+ (void) vSonyEject(i);
+ }
+ }
+}
+
+#if IncludeSonyGetName
+GLOBALOSGLUFUNC tMacErr vSonyGetName(tDrive Drive_No, tPbuf *r)
+{
+ tMacErr v = mnvm_miscErr;
+ NSString *filePath = DriveNames[Drive_No];
+ if (NULL != filePath) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSString *s0 = [filePath lastPathComponent];
+ v = NSStringToRomanPbuf(s0, r);
+
+ [pool release];
+ }
+
+ return v;
+}
+#endif
+
+LOCALFUNC blnr Sony_Insert0(FILE *refnum, blnr locked,
+ NSString *filePath)
+{
+ tDrive Drive_No;
+ blnr IsOk = falseblnr;
+
+ if (! FirstFreeDisk(&Drive_No)) {
+ MacMsg(kStrTooManyImagesTitle, kStrTooManyImagesMessage,
+ falseblnr);
+ } else {
+ /* printf("Sony_Insert0 %d\n", (int)Drive_No); */
+
+#if HaveAdvisoryLocks
+ if (locked || MyLockFile(refnum))
+#endif
+ {
+ Drives[Drive_No] = refnum;
+ DiskInsertNotify(Drive_No, locked);
+
+#if IncludeSonyGetName || IncludeSonyNew
+ DriveNames[Drive_No] = [filePath retain];
+#endif
+
+ IsOk = trueblnr;
+ }
+ }
+
+ if (! IsOk) {
+ fclose(refnum);
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr Sony_Insert1(NSString *filePath, blnr silentfail)
+{
+ /* const char *drivepath = [filePath UTF8String]; */
+ const char *drivepath = [filePath fileSystemRepresentation];
+ blnr locked = falseblnr;
+ /* printf("Sony_Insert1 %s\n", drivepath); */
+ FILE *refnum = fopen(drivepath, "rb+");
+ if (NULL == refnum) {
+ locked = trueblnr;
+ refnum = fopen(drivepath, "rb");
+ }
+ if (NULL == refnum) {
+ if (! silentfail) {
+ MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
+ }
+ } else {
+ return Sony_Insert0(refnum, locked, filePath);
+ }
+ return falseblnr;
+}
+
+LOCALFUNC blnr Sony_Insert2(char *s)
+{
+ NSString *sPath;
+
+ if (! FindNamedChildFilePath(MyDataPath, s, &sPath)) {
+ return falseblnr;
+ } else {
+ return Sony_Insert1(sPath, trueblnr);
+ }
+}
+
+LOCALFUNC tMacErr LoadMacRomPath(NSString *RomPath)
+{
+ FILE *ROM_File;
+ int File_Size;
+ tMacErr err = mnvm_fnfErr;
+ const char *path = [RomPath fileSystemRepresentation];
+
+ ROM_File = fopen(path, "rb");
+ if (NULL != ROM_File) {
+ File_Size = fread(ROM, 1, kROM_Size, ROM_File);
+ if (kROM_Size != File_Size) {
+ if (feof(ROM_File)) {
+ MacMsgOverride(kStrShortROMTitle,
+ kStrShortROMMessage);
+ err = mnvm_eofErr;
+ } else {
+ MacMsgOverride(kStrNoReadROMTitle,
+ kStrNoReadROMMessage);
+ err = mnvm_miscErr;
+ }
+ } else {
+ err = ROM_IsValid();
+ }
+ fclose(ROM_File);
+ }
+
+ return err;
+}
+
+LOCALFUNC blnr Sony_Insert1a(NSString *filePath)
+{
+ blnr v;
+
+ if (! ROM_loaded) {
+ v = (mnvm_noErr == LoadMacRomPath(filePath));
+ } else {
+ v = Sony_Insert1(filePath, falseblnr);
+ }
+
+ return v;
+}
+
+LOCALPROC Sony_ResolveInsert(NSString *filePath)
+{
+ Boolean isDirectory;
+ NSString *RslvPath = MyResolveAlias(filePath, &isDirectory);
+ if (nil != RslvPath) {
+ if (! isDirectory) {
+ (void) Sony_Insert1a(RslvPath);
+ }
+ } else {
+ (void) Sony_Insert1a(filePath);
+ }
+}
+
+LOCALFUNC blnr Sony_InsertIth(int i)
+{
+ blnr v;
+
+ if ((i > 9) || ! FirstFreeDisk(nullpr)) {
+ v = falseblnr;
+ } else {
+ char s[] = "disk?.dsk";
+
+ s[4] = '0' + i;
+
+ v = Sony_Insert2(s);
+ }
+
+ return v;
+}
+
+LOCALFUNC blnr LoadInitialImages(void)
+{
+ if (! AnyDiskInserted()) {
+ int i;
+
+ for (i = 1; Sony_InsertIth(i); ++i) {
+ /* stop on first error (including file not found) */
+ }
+ }
+
+ return trueblnr;
+}
+
+#if IncludeSonyNew
+LOCALFUNC blnr WriteZero(FILE *refnum, ui5b L)
+{
+#define ZeroBufferSize 2048
+ ui5b i;
+ ui3b buffer[ZeroBufferSize];
+
+ memset(&buffer, 0, ZeroBufferSize);
+
+ while (L > 0) {
+ i = (L > ZeroBufferSize) ? ZeroBufferSize : L;
+ if (fwrite(buffer, 1, i, refnum) != i) {
+ return falseblnr;
+ }
+ L -= i;
+ }
+ return trueblnr;
+}
+#endif
+
+#if IncludeSonyNew
+LOCALPROC MakeNewDisk0(ui5b L, NSString *sPath)
+{
+ blnr IsOk = falseblnr;
+ const char *drivepath = [sPath fileSystemRepresentation];
+ FILE *refnum = fopen(drivepath, "wb+");
+ if (NULL == refnum) {
+ MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
+ } else {
+ if (WriteZero(refnum, L)) {
+ IsOk = Sony_Insert0(refnum, falseblnr, sPath);
+ refnum = NULL;
+ }
+ if (refnum != NULL) {
+ fclose(refnum);
+ }
+ if (! IsOk) {
+ (void) remove(drivepath);
+ }
+ }
+}
+#endif
+
+/* --- ROM --- */
+
+LOCALFUNC tMacErr LoadMacRomFrom(NSString *parentPath)
+{
+ NSString *RomPath;
+ tMacErr err = mnvm_fnfErr;
+
+ if (FindNamedChildFilePath(parentPath, RomFileName, &RomPath)) {
+ err = LoadMacRomPath(RomPath);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr LoadMacRomFromAppDir(void)
+{
+ return LoadMacRomFrom(MyDataPath);
+}
+
+LOCALFUNC tMacErr LoadMacRomFromPrefDir(void)
+{
+ NSString *PrefsPath;
+ NSString *GryphelPath;
+ NSString *RomsPath;
+ tMacErr err = mnvm_fnfErr;
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(
+ NSLibraryDirectory, NSUserDomainMask, YES);
+ if ((nil != paths) && ([paths count] > 0))
+ {
+ NSString *LibPath = [paths objectAtIndex:0];
+ if (FindNamedChildDirPath(LibPath, "Preferences", &PrefsPath))
+ if (FindNamedChildDirPath(PrefsPath, "Gryphel", &GryphelPath))
+ if (FindNamedChildDirPath(GryphelPath, "mnvm_rom", &RomsPath))
+ {
+ err = LoadMacRomFrom(RomsPath);
+ }
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr LoadMacRomFromGlobalDir(void)
+{
+ NSString *GryphelPath;
+ NSString *RomsPath;
+ tMacErr err = mnvm_fnfErr;
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(
+ NSApplicationSupportDirectory, NSLocalDomainMask, NO);
+ if ((nil != paths) && ([paths count] > 0))
+ {
+ NSString *LibPath = [paths objectAtIndex:0];
+ if (FindNamedChildDirPath(LibPath, "Gryphel", &GryphelPath))
+ if (FindNamedChildDirPath(GryphelPath, "mnvm_rom", &RomsPath))
+ {
+ err = LoadMacRomFrom(RomsPath);
+ }
+ }
+
+ return err;
+}
+
+LOCALFUNC blnr LoadMacRom(void)
+{
+ tMacErr err;
+
+ if (mnvm_fnfErr == (err = LoadMacRomFromAppDir()))
+ if (mnvm_fnfErr == (err = LoadMacRomFromPrefDir()))
+ if (mnvm_fnfErr == (err = LoadMacRomFromGlobalDir()))
+ {
+ }
+
+ return trueblnr; /* keep launching Mini vMac, regardless */
+}
+
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEexport(tPbuf i)
+{
+ void *Buffer;
+ ui5r L;
+ tMacErr err = mnvm_miscErr;
+
+ PbufKillToPtr(&Buffer, &L, i);
+
+ if (L > 0) {
+ int j;
+ ui3b *p = (ui3b *)Buffer;
+
+ for (j = L; --j >= 0; ) {
+ ui3b v = *p;
+ if (13 == v) {
+ *p = 10;
+ }
+ ++p;
+ }
+ }
+
+ {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSData *d = [[NSData alloc]
+ initWithBytesNoCopy: Buffer length: L];
+ /* NSData *d = [NSData dataWithBytes: Buffer length: L]; */
+ NSString *ss = [[[NSString alloc]
+ initWithData:d encoding:NSMacOSRomanStringEncoding]
+ autorelease];
+ NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
+ NSArray *newTypes =
+ [NSArray arrayWithObject: NSStringPboardType];
+
+ (void) [pasteboard declareTypes: newTypes owner: nil];
+ if ([pasteboard setString: ss forType: NSStringPboardType]) {
+ err = mnvm_noErr;
+ }
+
+ [d release];
+
+ [pool release];
+ }
+
+ return err;
+}
+#endif
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEimport(tPbuf *r)
+{
+ tMacErr err = mnvm_miscErr;
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
+ NSArray *supportedTypes = [NSArray
+ arrayWithObject: NSStringPboardType];
+ NSString *available = [pasteboard
+ availableTypeFromArray: supportedTypes];
+
+ if (nil != available) {
+ NSString *string = [pasteboard
+ stringForType: NSStringPboardType];
+ if (nil != string) {
+ err = NSStringToRomanPbuf(string, r);
+ }
+ }
+
+ [pool release];
+
+ return err;
+}
+#endif
+
+
+#if EmLocalTalk
+
+#include "BPFILTER.h"
+
+#endif
+
+
+#define UseCGContextDrawImage 0
+
+LOCALVAR NSWindow *MyWindow = nil;
+LOCALVAR NSView *MyNSview = nil;
+#if UseCGContextDrawImage
+LOCALVAR NSGraphicsContext *MyNSgfxContext = nil;
+LOCALVAR CGContextRef MyCGcontext = nil;
+LOCALVAR void *MyPixels = NULL;
+LOCALVAR ui4b MyPitch;
+LOCALVAR ui3b MyBytesPerPixel;
+#endif
+
+LOCALVAR NSOpenGLContext *MyNSOpnGLCntxt = nil;
+LOCALVAR short GLhOffset;
+LOCALVAR short GLvOffset;
+ /* OpenGL coordinates of upper left point of drawing area */
+
+
+LOCALPROC MyHideCursor(void)
+{
+ [NSCursor hide];
+}
+
+LOCALPROC MyShowCursor(void)
+{
+ if (nil != MyWindow) {
+ [MyWindow invalidateCursorRectsForView:
+ MyNSview];
+ }
+#if 0
+ [cursor->nscursor performSelectorOnMainThread: @selector(set)
+ withObject: nil waitUntilDone: NO];
+#endif
+#if 0
+ [[NSCursor arrowCursor] set];
+#endif
+ [NSCursor unhide];
+}
+
+#if EnableMoveMouse
+LOCALFUNC CGPoint QZ_PrivateSDLToCG(NSPoint *p)
+{
+ CGPoint cgp;
+
+ *p = [MyNSview convertPoint: *p toView: nil];
+ p->y = [MyNSview frame].size.height - p->y;
+ *p = [MyWindow convertBaseToScreen: *p];
+
+ cgp.x = p->x;
+ cgp.y = CGDisplayPixelsHigh(kCGDirectMainDisplay)
+ - p->y;
+
+ return cgp;
+}
+#endif
+
+LOCALPROC QZ_GetMouseLocation(NSPoint *p)
+{
+ /* incorrect while window is being dragged */
+
+ *p = [NSEvent mouseLocation]; /* global coordinates */
+ if (nil != MyWindow) {
+ *p = [MyWindow convertScreenToBase: *p];
+ }
+ *p = [MyNSview convertPoint: *p fromView: nil];
+ p->y = [MyNSview frame].size.height - p->y;
+}
+
+/* --- keyboard --- */
+
+LOCALVAR NSUInteger MyCurrentMods = 0;
+
+/*
+ Apple documentation says:
+ "The lower 16 bits of the modifier flags are reserved
+ for device-dependent bits."
+
+ observed to be:
+*/
+#define My_NSLShiftKeyMask 0x0002
+#define My_NSRShiftKeyMask 0x0004
+#define My_NSLControlKeyMask 0x0001
+#define My_NSRControlKeyMask 0x2000
+#define My_NSLCommandKeyMask 0x0008
+#define My_NSRCommandKeyMask 0x0010
+#define My_NSLOptionKeyMask 0x0020
+#define My_NSROptionKeyMask 0x0040
+/*
+ Avoid using the above unless it is
+ really needed.
+*/
+
+LOCALPROC MyUpdateKeyboardModifiers(NSUInteger newMods)
+{
+ NSUInteger changeMask = MyCurrentMods ^ newMods;
+
+ if (0 != changeMask) {
+ if (0 != (changeMask & NSAlphaShiftKeyMask)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_CapsLock,
+ 0 != (newMods & NSAlphaShiftKeyMask));
+ }
+
+#if MKC_formac_RShift == MKC_formac_Shift
+ if (0 != (changeMask & NSShiftKeyMask)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_Shift,
+ 0 != (newMods & NSShiftKeyMask));
+ }
+#else
+ if (0 != (changeMask & My_NSLShiftKeyMask)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_Shift,
+ 0 != (newMods & My_NSLShiftKeyMask));
+ }
+ if (0 != (changeMask & My_NSRShiftKeyMask)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_RShift,
+ 0 != (newMods & My_NSRShiftKeyMask));
+ }
+#endif
+
+#if MKC_formac_RControl == MKC_formac_Control
+ if (0 != (changeMask & NSControlKeyMask)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_Control,
+ 0 != (newMods & NSControlKeyMask));
+ }
+#else
+ if (0 != (changeMask & My_NSLControlKeyMask)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_Control,
+ 0 != (newMods & My_NSLControlKeyMask));
+ }
+ if (0 != (changeMask & My_NSRControlKeyMask)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_RControl,
+ 0 != (newMods & My_NSRControlKeyMask));
+ }
+#endif
+
+#if MKC_formac_RCommand == MKC_formac_Command
+ if (0 != (changeMask & NSCommandKeyMask)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_Command,
+ 0 != (newMods & NSCommandKeyMask));
+ }
+#else
+ if (0 != (changeMask & My_NSLCommandKeyMask)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_Command,
+ 0 != (newMods & My_NSLCommandKeyMask));
+ }
+ if (0 != (changeMask & My_NSRCommandKeyMask)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_RCommand,
+ 0 != (newMods & My_NSRCommandKeyMask));
+ }
+#endif
+
+#if MKC_formac_ROption == MKC_formac_Option
+ if (0 != (changeMask & NSAlternateKeyMask)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_Option,
+ 0 != (newMods & NSAlternateKeyMask));
+ }
+#else
+ if (0 != (changeMask & My_NSLOptionKeyMask)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_Option,
+ 0 != (newMods & My_NSLOptionKeyMask));
+ }
+ if (0 != (changeMask & My_NSROptionKeyMask)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_ROption,
+ 0 != (newMods & My_NSROptionKeyMask));
+ }
+#endif
+
+ MyCurrentMods = newMods;
+ }
+}
+
+/* --- mouse --- */
+
+/* cursor hiding */
+
+LOCALVAR blnr WantCursorHidden = falseblnr;
+
+#if MayFullScreen
+LOCALVAR short hOffset;
+ /* number of pixels to left of drawing area in window */
+LOCALVAR short vOffset;
+ /* number of pixels above drawing area in window */
+#endif
+
+#if MayFullScreen
+LOCALVAR blnr GrabMachine = falseblnr;
+#endif
+
+#if VarFullScreen
+LOCALVAR blnr UseFullScreen = (0 != WantInitFullScreen);
+#endif
+
+#if EnableMagnify
+LOCALVAR blnr UseMagnify = (0 != WantInitMagnify);
+#endif
+
+LOCALVAR blnr gBackgroundFlag = falseblnr;
+LOCALVAR blnr CurSpeedStopped = trueblnr;
+
+#if EnableMagnify
+#define MaxScale MyWindowScale
+#else
+#define MaxScale 1
+#endif
+
+LOCALVAR blnr HaveCursorHidden = falseblnr;
+
+LOCALPROC ForceShowCursor(void)
+{
+ if (HaveCursorHidden) {
+ HaveCursorHidden = falseblnr;
+ MyShowCursor();
+ }
+}
+
+/* cursor moving */
+
+#if EnableMoveMouse
+LOCALFUNC blnr MyMoveMouse(si4b h, si4b v)
+{
+ NSPoint p;
+ CGPoint cgp;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ h -= ViewHStart;
+ v -= ViewVStart;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ h *= MyWindowScale;
+ v *= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ h += hOffset;
+ v += vOffset;
+ }
+#endif
+
+ p = NSMakePoint(h, v);
+ cgp = QZ_PrivateSDLToCG(&p);
+
+ /*
+ this is the magic call that fixes cursor "freezing"
+ after warp
+ */
+ CGAssociateMouseAndMouseCursorPosition(0);
+ CGWarpMouseCursorPosition(cgp);
+ CGAssociateMouseAndMouseCursorPosition(1);
+
+#if 0
+ if (noErr != CGSetLocalEventsSuppressionInterval(0.0)) {
+ /* don't use MacMsg which can call MyMoveMouse */
+ }
+ if (noErr != CGWarpMouseCursorPosition(cgp)) {
+ /* don't use MacMsg which can call MyMoveMouse */
+ }
+#endif
+
+ return trueblnr;
+}
+#endif
+
+#if EnableFSMouseMotion
+LOCALPROC AdjustMouseMotionGrab(void)
+{
+#if MayFullScreen
+ if (GrabMachine) {
+ /*
+ if magnification changes, need to reset,
+ even if HaveMouseMotion already true
+ */
+ if (MyMoveMouse(ViewHStart + (ViewHSize / 2),
+ ViewVStart + (ViewVSize / 2)))
+ {
+ SavedMouseH = ViewHStart + (ViewHSize / 2);
+ SavedMouseV = ViewVStart + (ViewVSize / 2);
+ HaveMouseMotion = trueblnr;
+ }
+ } else
+#endif
+ {
+ if (HaveMouseMotion) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ HaveMouseMotion = falseblnr;
+ }
+ }
+}
+#endif
+
+#if EnableFSMouseMotion
+LOCALPROC MyMouseConstrain(void)
+{
+ si4b shiftdh;
+ si4b shiftdv;
+
+ if (SavedMouseH < ViewHStart + (ViewHSize / 4)) {
+ shiftdh = ViewHSize / 2;
+ } else if (SavedMouseH > ViewHStart + ViewHSize - (ViewHSize / 4)) {
+ shiftdh = - ViewHSize / 2;
+ } else {
+ shiftdh = 0;
+ }
+ if (SavedMouseV < ViewVStart + (ViewVSize / 4)) {
+ shiftdv = ViewVSize / 2;
+ } else if (SavedMouseV > ViewVStart + ViewVSize - (ViewVSize / 4)) {
+ shiftdv = - ViewVSize / 2;
+ } else {
+ shiftdv = 0;
+ }
+ if ((shiftdh != 0) || (shiftdv != 0)) {
+ SavedMouseH += shiftdh;
+ SavedMouseV += shiftdv;
+ if (! MyMoveMouse(SavedMouseH, SavedMouseV)) {
+ HaveMouseMotion = falseblnr;
+ }
+ }
+}
+#endif
+
+/* cursor state */
+
+LOCALPROC MousePositionNotify(int NewMousePosh, int NewMousePosv)
+{
+ blnr ShouldHaveCursorHidden = trueblnr;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewMousePosh -= hOffset;
+ NewMousePosv -= vOffset;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ NewMousePosh /= MyWindowScale;
+ NewMousePosv /= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewMousePosh += ViewHStart;
+ NewMousePosv += ViewVStart;
+ }
+#endif
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMousePositionSetDelta(NewMousePosh - SavedMouseH,
+ NewMousePosv - SavedMouseV);
+ SavedMouseH = NewMousePosh;
+ SavedMouseV = NewMousePosv;
+ } else
+#endif
+ {
+ if (NewMousePosh < 0) {
+ NewMousePosh = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosh >= vMacScreenWidth) {
+ NewMousePosh = vMacScreenWidth - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+ if (NewMousePosv < 0) {
+ NewMousePosv = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosv >= vMacScreenHeight) {
+ NewMousePosv = vMacScreenHeight - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ ShouldHaveCursorHidden = trueblnr;
+ }
+#endif
+
+ /* if (ShouldHaveCursorHidden || CurMouseButton) */
+ /*
+ for a game like arkanoid, would like mouse to still
+ move even when outside window in one direction
+ */
+ MyMousePositionSet(NewMousePosh, NewMousePosv);
+ }
+
+ WantCursorHidden = ShouldHaveCursorHidden;
+}
+
+LOCALPROC CheckMouseState(void)
+{
+ /*
+ incorrect while window is being dragged
+ so only call when needed.
+ */
+ NSPoint p;
+
+ QZ_GetMouseLocation(&p);
+ MousePositionNotify((int) p.x, (int) p.y);
+}
+
+LOCALVAR blnr gTrueBackgroundFlag = falseblnr;
+
+
+LOCALVAR ui3p ScalingBuff = nullpr;
+
+LOCALVAR ui3p CLUT_final;
+
+#define CLUT_finalsz1 (256 * 8)
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+
+#define CLUT_finalClrSz (256 << (5 - vMacScreenDepth))
+
+#define CLUT_finalsz ((CLUT_finalClrSz > CLUT_finalsz1) \
+ ? CLUT_finalClrSz : CLUT_finalsz1)
+
+#else
+#define CLUT_finalsz CLUT_finalsz1
+#endif
+
+
+#define ScrnMapr_DoMap UpdateBWLuminanceCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+
+#define ScrnMapr_DoMap UpdateMappedColorCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#endif
+
+#if vMacScreenDepth >= 4
+
+#define ScrnTrns_DoTrans UpdateTransColorCopy
+#define ScrnTrns_Src GetCurDrawBuff()
+#define ScrnTrns_Dst ScalingBuff
+#define ScrnTrns_SrcDepth vMacScreenDepth
+#define ScrnTrns_DstDepth 5
+#define ScrnTrns_DstZLo 1
+
+#include "SCRNTRNS.h"
+
+#endif
+
+LOCALPROC UpdateLuminanceCopy(si4b top, si4b left,
+ si4b bottom, si4b right)
+{
+ int i;
+
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+
+#if vMacScreenDepth < 4
+
+ if (! ColorTransValid) {
+ int j;
+ int k;
+ ui5p p4;
+
+ p4 = (ui5p)CLUT_final;
+ for (i = 0; i < 256; ++i) {
+ for (k = 1 << (3 - vMacScreenDepth); --k >= 0; ) {
+ j = (i >> (k << vMacScreenDepth)) & (CLUT_size - 1);
+ *p4++ = (((long)CLUT_reds[j] & 0xFF00) << 16)
+ | (((long)CLUT_greens[j] & 0xFF00) << 8)
+ | ((long)CLUT_blues[j] & 0xFF00);
+ }
+ }
+ ColorTransValid = trueblnr;
+ }
+
+ UpdateMappedColorCopy(top, left, bottom, right);
+
+#else
+ UpdateTransColorCopy(top, left, bottom, right);
+#endif
+
+ } else
+#endif
+ {
+ if (! ColorTransValid) {
+ int k;
+ ui3p p4 = (ui3p)CLUT_final;
+
+ for (i = 0; i < 256; ++i) {
+ for (k = 8; --k >= 0; ) {
+ *p4++ = ((i >> k) & 0x01) - 1;
+ }
+ }
+ ColorTransValid = trueblnr;
+ }
+
+ UpdateBWLuminanceCopy(top, left, bottom, right);
+ }
+}
+
+LOCALPROC MyDrawWithOpenGL(ui4r top, ui4r left, ui4r bottom, ui4r right)
+{
+ if (nil == MyNSOpnGLCntxt) {
+ /* oops */
+ } else {
+ si4b top2;
+ si4b left2;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ if (top < ViewVStart) {
+ top = ViewVStart;
+ }
+ if (left < ViewHStart) {
+ left = ViewHStart;
+ }
+ if (bottom > ViewVStart + ViewVSize) {
+ bottom = ViewVStart + ViewVSize;
+ }
+ if (right > ViewHStart + ViewHSize) {
+ right = ViewHStart + ViewHSize;
+ }
+
+ if ((top >= bottom) || (left >= right)) {
+ goto label_exit;
+ }
+ }
+#endif
+
+ top2 = top;
+ left2 = left;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ left2 -= ViewHStart;
+ top2 -= ViewVStart;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ top2 *= MyWindowScale;
+ left2 *= MyWindowScale;
+ }
+#endif
+
+ [MyNSOpnGLCntxt makeCurrentContext];
+
+ UpdateLuminanceCopy(top, left, bottom, right);
+ glRasterPos2i(GLhOffset + left2, GLvOffset - top2);
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+ glDrawPixels(right - left,
+ bottom - top,
+ GL_RGBA,
+ GL_UNSIGNED_INT_8_8_8_8,
+ ScalingBuff + (left + top * vMacScreenWidth) * 4
+ );
+ } else
+#endif
+ {
+ glDrawPixels(right - left,
+ bottom - top,
+ GL_LUMINANCE,
+ GL_UNSIGNED_BYTE,
+ ScalingBuff + (left + top * vMacScreenWidth)
+ );
+ }
+
+#if 0 /* a very quick and dirty check of where drawing */
+ glDrawPixels(right - left,
+ 1,
+ GL_RED,
+ GL_UNSIGNED_BYTE,
+ ScalingBuff + (left + top * vMacScreenWidth)
+ );
+
+ glDrawPixels(1,
+ bottom - top,
+ GL_RED,
+ GL_UNSIGNED_BYTE,
+ ScalingBuff + (left + top * vMacScreenWidth)
+ );
+#endif
+
+ glFlush();
+ }
+
+#if MayFullScreen
+label_exit:
+ ;
+#endif
+}
+
+#if UseCGContextDrawImage
+LOCALPROC SDL_UpdateRect(si5b x, si5b y, ui5b w, ui5b h)
+{
+ if ([MyWindow isMiniaturized]) {
+
+ /* Do nothing if miniaturized */
+
+ } else {
+ NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
+ if (ctx != MyNSgfxContext) {
+ /* uhoh, you might be rendering from another thread... */
+ [NSGraphicsContext
+ setCurrentContext: MyNSgfxContext];
+ ctx = MyNSgfxContext;
+ }
+ CGContextRef cgc = (CGContextRef) [ctx graphicsPort];
+ CGContextFlush(MyCGcontext);
+ CGImageRef image = CGBitmapContextCreateImage(
+ MyCGcontext);
+ CGRect rectangle = CGRectMake(0, 0,
+ [MyNSview frame].size.width,
+ [MyNSview frame].size.height);
+
+ CGContextDrawImage(cgc, rectangle, image);
+ CGImageRelease(image);
+ CGContextFlush(cgc);
+ }
+}
+#endif
+
+/* --- time, date, location --- */
+
+#define dbglog_TimeStuff (0 && dbglog_HAVE)
+
+LOCALVAR ui5b TrueEmulatedTime = 0;
+
+LOCALVAR NSTimeInterval LatestTime;
+LOCALVAR NSTimeInterval NextTickChangeTime;
+
+#define MyTickDuration (1.0 / 60.14742)
+
+LOCALVAR ui5b NewMacDateInSeconds;
+
+LOCALVAR blnr EmulationWasInterrupted = falseblnr;
+
+LOCALPROC UpdateTrueEmulatedTime(void)
+{
+ NSTimeInterval TimeDiff;
+
+ LatestTime = [NSDate timeIntervalSinceReferenceDate];
+ TimeDiff = LatestTime - NextTickChangeTime;
+
+ if (TimeDiff >= 0.0) {
+ if (TimeDiff > 16 * MyTickDuration) {
+ /* emulation interrupted, forget it */
+ ++TrueEmulatedTime;
+ NextTickChangeTime = LatestTime + MyTickDuration;
+
+ EmulationWasInterrupted = trueblnr;
+#if dbglog_TimeStuff
+ dbglog_writelnNum("emulation interrupted",
+ TrueEmulatedTime);
+#endif
+ } else {
+ do {
+#if 0 && dbglog_TimeStuff
+ dbglog_writeln("got next tick");
+#endif
+ ++TrueEmulatedTime;
+ TimeDiff -= MyTickDuration;
+ NextTickChangeTime += MyTickDuration;
+ } while (TimeDiff >= 0.0);
+ }
+ } else if (TimeDiff < (-16 * MyTickDuration)) {
+ /* clock set back, reset */
+#if dbglog_TimeStuff
+ dbglog_writeln("clock set back");
+#endif
+
+ NextTickChangeTime = LatestTime + MyTickDuration;
+ }
+}
+
+
+LOCALVAR ui5b MyDateDelta;
+
+LOCALFUNC blnr CheckDateTime(void)
+{
+ NewMacDateInSeconds = ((ui5b)LatestTime) + MyDateDelta;
+ if (CurMacDateInSeconds != NewMacDateInSeconds) {
+ CurMacDateInSeconds = NewMacDateInSeconds;
+ return trueblnr;
+ } else {
+ return falseblnr;
+ }
+}
+
+LOCALPROC StartUpTimeAdjust(void)
+{
+ LatestTime = [NSDate timeIntervalSinceReferenceDate];
+ NextTickChangeTime = LatestTime;
+}
+
+LOCALFUNC blnr InitLocationDat(void)
+{
+ NSTimeZone *MyZone = [NSTimeZone localTimeZone];
+ ui5b TzOffSet = (ui5b)[MyZone secondsFromGMT];
+#if AutoTimeZone
+ BOOL isdst = [MyZone isDaylightSavingTime];
+#endif
+
+ MyDateDelta = TzOffSet - 1233815296;
+ LatestTime = [NSDate timeIntervalSinceReferenceDate];
+ NewMacDateInSeconds = ((ui5b)LatestTime) + MyDateDelta;
+ CurMacDateInSeconds = NewMacDateInSeconds;
+#if AutoTimeZone
+ CurMacDelta = (TzOffSet & 0x00FFFFFF)
+ | ((isdst ? 0x80 : 0) << 24);
+#endif
+
+ return trueblnr;
+}
+
+/* --- sound --- */
+
+#if MySoundEnabled
+
+#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */
+#define kSoundBuffers (1 << kLn2SoundBuffers)
+#define kSoundBuffMask (kSoundBuffers - 1)
+
+#define DesiredMinFilledSoundBuffs 3
+ /*
+ if too big then sound lags behind emulation.
+ if too small then sound will have pauses.
+ */
+
+#define kLnOneBuffLen 9
+#define kLnAllBuffLen (kLn2SoundBuffers + kLnOneBuffLen)
+#define kOneBuffLen (1UL << kLnOneBuffLen)
+#define kAllBuffLen (1UL << kLnAllBuffLen)
+#define kLnOneBuffSz (kLnOneBuffLen + kLn2SoundSampSz - 3)
+#define kLnAllBuffSz (kLnAllBuffLen + kLn2SoundSampSz - 3)
+#define kOneBuffSz (1UL << kLnOneBuffSz)
+#define kAllBuffSz (1UL << kLnAllBuffSz)
+#define kOneBuffMask (kOneBuffLen - 1)
+#define kAllBuffMask (kAllBuffLen - 1)
+#define dbhBufferSize (kAllBuffSz + kOneBuffSz)
+
+#define dbglog_SoundStuff (0 && dbglog_HAVE)
+#define dbglog_SoundBuffStats (0 && dbglog_HAVE)
+
+LOCALVAR tpSoundSamp TheSoundBuffer = nullpr;
+static volatile ui4b ThePlayOffset;
+static volatile ui4b TheFillOffset;
+static volatile ui4b MinFilledSoundBuffs;
+#if dbglog_SoundBuffStats
+LOCALVAR ui4b MaxFilledSoundBuffs;
+#endif
+LOCALVAR ui4b TheWriteOffset;
+
+LOCALPROC MySound_Start0(void)
+{
+ /* Reset variables */
+ ThePlayOffset = 0;
+ TheFillOffset = 0;
+ TheWriteOffset = 0;
+ MinFilledSoundBuffs = kSoundBuffers + 1;
+#if dbglog_SoundBuffStats
+ MaxFilledSoundBuffs = 0;
+#endif
+}
+
+GLOBALOSGLUFUNC tpSoundSamp MySound_BeginWrite(ui4r n, ui4r *actL)
+{
+ ui4b ToFillLen = kAllBuffLen - (TheWriteOffset - ThePlayOffset);
+ ui4b WriteBuffContig =
+ kOneBuffLen - (TheWriteOffset & kOneBuffMask);
+
+ if (WriteBuffContig < n) {
+ n = WriteBuffContig;
+ }
+ if (ToFillLen < n) {
+ /* overwrite previous buffer */
+#if dbglog_SoundStuff
+ dbglog_writeln("sound buffer over flow");
+#endif
+ TheWriteOffset -= kOneBuffLen;
+ }
+
+ *actL = n;
+ return TheSoundBuffer + (TheWriteOffset & kAllBuffMask);
+}
+
+#if 4 == kLn2SoundSampSz
+LOCALPROC ConvertSoundBlockToNative(tpSoundSamp p)
+{
+ int i;
+
+ for (i = kOneBuffLen; --i >= 0; ) {
+ *p++ -= 0x8000;
+ }
+}
+#else
+#define ConvertSoundBlockToNative(p)
+#endif
+
+LOCALPROC MySound_WroteABlock(void)
+{
+#if (4 == kLn2SoundSampSz)
+ ui4b PrevWriteOffset = TheWriteOffset - kOneBuffLen;
+ tpSoundSamp p = TheSoundBuffer + (PrevWriteOffset & kAllBuffMask);
+#endif
+
+#if dbglog_SoundStuff
+ dbglog_writeln("enter MySound_WroteABlock");
+#endif
+
+ ConvertSoundBlockToNative(p);
+
+ TheFillOffset = TheWriteOffset;
+
+#if dbglog_SoundBuffStats
+ {
+ ui4b ToPlayLen = TheFillOffset
+ - ThePlayOffset;
+ ui4b ToPlayBuffs = ToPlayLen >> kLnOneBuffLen;
+
+ if (ToPlayBuffs > MaxFilledSoundBuffs) {
+ MaxFilledSoundBuffs = ToPlayBuffs;
+ }
+ }
+#endif
+}
+
+LOCALFUNC blnr MySound_EndWrite0(ui4r actL)
+{
+ blnr v;
+
+ TheWriteOffset += actL;
+
+ if (0 != (TheWriteOffset & kOneBuffMask)) {
+ v = falseblnr;
+ } else {
+ /* just finished a block */
+
+ MySound_WroteABlock();
+
+ v = trueblnr;
+ }
+
+ return v;
+}
+
+LOCALPROC MySound_SecondNotify0(void)
+{
+ if (MinFilledSoundBuffs <= kSoundBuffers) {
+ if (MinFilledSoundBuffs > DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too high");
+#endif
+ NextTickChangeTime += MyTickDuration;
+ } else if (MinFilledSoundBuffs < DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too low");
+#endif
+ ++TrueEmulatedTime;
+ }
+#if dbglog_SoundBuffStats
+ dbglog_writelnNum("MinFilledSoundBuffs",
+ MinFilledSoundBuffs);
+ dbglog_writelnNum("MaxFilledSoundBuffs",
+ MaxFilledSoundBuffs);
+ MaxFilledSoundBuffs = 0;
+#endif
+ MinFilledSoundBuffs = kSoundBuffers + 1;
+ }
+}
+
+typedef ui4r trSoundTemp;
+
+#define kCenterTempSound 0x8000
+
+#define AudioStepVal 0x0040
+
+#if 3 == kLn2SoundSampSz
+#define ConvertTempSoundSampleFromNative(v) ((v) << 8)
+#elif 4 == kLn2SoundSampSz
+#define ConvertTempSoundSampleFromNative(v) ((v) + kCenterSound)
+#else
+#error "unsupported kLn2SoundSampSz"
+#endif
+
+#if 3 == kLn2SoundSampSz
+#define ConvertTempSoundSampleToNative(v) ((v) >> 8)
+#elif 4 == kLn2SoundSampSz
+#define ConvertTempSoundSampleToNative(v) ((v) - kCenterSound)
+#else
+#error "unsupported kLn2SoundSampSz"
+#endif
+
+LOCALPROC SoundRampTo(trSoundTemp *last_val, trSoundTemp dst_val,
+ tpSoundSamp *stream, int *len)
+{
+ trSoundTemp diff;
+ tpSoundSamp p = *stream;
+ int n = *len;
+ trSoundTemp v1 = *last_val;
+
+ while ((v1 != dst_val) && (0 != n)) {
+ if (v1 > dst_val) {
+ diff = v1 - dst_val;
+ if (diff > AudioStepVal) {
+ v1 -= AudioStepVal;
+ } else {
+ v1 = dst_val;
+ }
+ } else {
+ diff = dst_val - v1;
+ if (diff > AudioStepVal) {
+ v1 += AudioStepVal;
+ } else {
+ v1 = dst_val;
+ }
+ }
+
+ --n;
+ *p++ = ConvertTempSoundSampleToNative(v1);
+ }
+
+ *stream = p;
+ *len = n;
+ *last_val = v1;
+}
+
+struct MySoundR {
+ tpSoundSamp fTheSoundBuffer;
+ volatile ui4b (*fPlayOffset);
+ volatile ui4b (*fFillOffset);
+ volatile ui4b (*fMinFilledSoundBuffs);
+
+ volatile trSoundTemp lastv;
+
+ blnr enabled;
+ blnr wantplaying;
+ blnr HaveStartedPlaying;
+
+ AudioUnit outputAudioUnit;
+};
+typedef struct MySoundR MySoundR;
+
+LOCALPROC my_audio_callback(void *udata, void *stream, int len)
+{
+ ui4b ToPlayLen;
+ ui4b FilledSoundBuffs;
+ int i;
+ MySoundR *datp = (MySoundR *)udata;
+ tpSoundSamp CurSoundBuffer = datp->fTheSoundBuffer;
+ ui4b CurPlayOffset = *datp->fPlayOffset;
+ trSoundTemp v0 = datp->lastv;
+ trSoundTemp v1 = v0;
+ tpSoundSamp dst = (tpSoundSamp)stream;
+
+#if kLn2SoundSampSz > 3
+ len >>= (kLn2SoundSampSz - 3);
+#endif
+
+#if dbglog_SoundStuff
+ dbglog_writeln("Enter my_audio_callback");
+ dbglog_writelnNum("len", len);
+#endif
+
+label_retry:
+ ToPlayLen = *datp->fFillOffset - CurPlayOffset;
+ FilledSoundBuffs = ToPlayLen >> kLnOneBuffLen;
+
+ if (! datp->wantplaying) {
+#if dbglog_SoundStuff
+ dbglog_writeln("playing end transistion");
+#endif
+
+ SoundRampTo(&v1, kCenterTempSound, &dst, &len);
+
+ ToPlayLen = 0;
+ } else if (! datp->HaveStartedPlaying) {
+#if dbglog_SoundStuff
+ dbglog_writeln("playing start block");
+#endif
+
+ if ((ToPlayLen >> kLnOneBuffLen) < 8) {
+ ToPlayLen = 0;
+ } else {
+ tpSoundSamp p = datp->fTheSoundBuffer
+ + (CurPlayOffset & kAllBuffMask);
+ trSoundTemp v2 = ConvertTempSoundSampleFromNative(*p);
+
+#if dbglog_SoundStuff
+ dbglog_writeln("have enough samples to start");
+#endif
+
+ SoundRampTo(&v1, v2, &dst, &len);
+
+ if (v1 == v2) {
+#if dbglog_SoundStuff
+ dbglog_writeln("finished start transition");
+#endif
+
+ datp->HaveStartedPlaying = trueblnr;
+ }
+ }
+ }
+
+ if (0 == len) {
+ /* done */
+
+ if (FilledSoundBuffs < *datp->fMinFilledSoundBuffs) {
+ *datp->fMinFilledSoundBuffs = FilledSoundBuffs;
+ }
+ } else if (0 == ToPlayLen) {
+
+#if dbglog_SoundStuff
+ dbglog_writeln("under run");
+#endif
+
+ for (i = 0; i < len; ++i) {
+ *dst++ = ConvertTempSoundSampleToNative(v1);
+ }
+ *datp->fMinFilledSoundBuffs = 0;
+ } else {
+ ui4b PlayBuffContig = kAllBuffLen
+ - (CurPlayOffset & kAllBuffMask);
+ tpSoundSamp p = CurSoundBuffer
+ + (CurPlayOffset & kAllBuffMask);
+
+ if (ToPlayLen > PlayBuffContig) {
+ ToPlayLen = PlayBuffContig;
+ }
+ if (ToPlayLen > len) {
+ ToPlayLen = len;
+ }
+
+ for (i = 0; i < ToPlayLen; ++i) {
+ *dst++ = *p++;
+ }
+ v1 = ConvertTempSoundSampleFromNative(p[-1]);
+
+ CurPlayOffset += ToPlayLen;
+ len -= ToPlayLen;
+
+ *datp->fPlayOffset = CurPlayOffset;
+
+ goto label_retry;
+ }
+
+ datp->lastv = v1;
+}
+
+LOCALFUNC OSStatus audioCallback(
+ void *inRefCon,
+ AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp *inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList *ioData)
+{
+ AudioBuffer *abuf;
+ UInt32 i;
+ UInt32 n = ioData->mNumberBuffers;
+
+#if dbglog_SoundStuff
+ dbglog_writeln("Enter audioCallback");
+ dbglog_writelnNum("mNumberBuffers", n);
+#endif
+
+ for (i = 0; i < n; i++) {
+ abuf = &ioData->mBuffers[i];
+ my_audio_callback(inRefCon,
+ abuf->mData, abuf->mDataByteSize);
+ }
+
+ return 0;
+}
+
+LOCALVAR MySoundR cur_audio;
+
+LOCALPROC ZapAudioVars(void)
+{
+ memset(&cur_audio, 0, sizeof(MySoundR));
+}
+
+LOCALPROC MySound_Stop(void)
+{
+#if dbglog_SoundStuff
+ dbglog_writeln("enter MySound_Stop");
+#endif
+
+ if (cur_audio.wantplaying) {
+ OSStatus result;
+ ui4r retry_limit = 50; /* half of a second */
+
+ cur_audio.wantplaying = falseblnr;
+
+label_retry:
+ if (kCenterTempSound == cur_audio.lastv) {
+#if dbglog_SoundStuff
+ dbglog_writeln("reached kCenterTempSound");
+#endif
+
+ /* done */
+ } else if (0 == --retry_limit) {
+#if dbglog_SoundStuff
+ dbglog_writeln("retry limit reached");
+#endif
+ /* done */
+ } else
+ {
+ /*
+ give time back, particularly important
+ if got here on a suspend event.
+ */
+ struct timespec rqt;
+ struct timespec rmt;
+
+#if dbglog_SoundStuff
+ dbglog_writeln("busy, so sleep");
+#endif
+
+ rqt.tv_sec = 0;
+ rqt.tv_nsec = 10000000;
+ (void) nanosleep(&rqt, &rmt);
+
+ goto label_retry;
+ }
+
+ if (noErr != (result = AudioOutputUnitStop(
+ cur_audio.outputAudioUnit)))
+ {
+#if dbglog_HAVE
+ dbglog_writeln("AudioOutputUnitStop fails");
+#endif
+ }
+ }
+
+#if dbglog_SoundStuff
+ dbglog_writeln("leave MySound_Stop");
+#endif
+}
+
+LOCALPROC MySound_Start(void)
+{
+ OSStatus result;
+
+ if ((! cur_audio.wantplaying) && cur_audio.enabled) {
+#if dbglog_SoundStuff
+ dbglog_writeln("enter MySound_Start");
+#endif
+
+ MySound_Start0();
+ cur_audio.lastv = kCenterTempSound;
+ cur_audio.HaveStartedPlaying = falseblnr;
+ cur_audio.wantplaying = trueblnr;
+
+ if (noErr != (result = AudioOutputUnitStart(
+ cur_audio.outputAudioUnit)))
+ {
+#if dbglog_HAVE
+ dbglog_writeln("AudioOutputUnitStart fails");
+#endif
+ cur_audio.wantplaying = falseblnr;
+ }
+
+#if dbglog_SoundStuff
+ dbglog_writeln("leave MySound_Start");
+#endif
+ }
+}
+
+LOCALPROC MySound_UnInit(void)
+{
+ if (cur_audio.enabled) {
+ OSStatus result;
+ struct AURenderCallbackStruct callback;
+
+ cur_audio.enabled = falseblnr;
+
+ /* Remove the input callback */
+ callback.inputProc = 0;
+ callback.inputProcRefCon = 0;
+
+ if (noErr != (result = AudioUnitSetProperty(
+ cur_audio.outputAudioUnit,
+ kAudioUnitProperty_SetRenderCallback,
+ kAudioUnitScope_Input,
+ 0,
+ &callback,
+ sizeof(callback))))
+ {
+#if dbglog_HAVE
+ dbglog_writeln("AudioUnitSetProperty fails"
+ "(kAudioUnitProperty_SetRenderCallback)");
+#endif
+ }
+
+ if (noErr != (result = CloseComponent(
+ cur_audio.outputAudioUnit)))
+ {
+#if dbglog_HAVE
+ dbglog_writeln("CloseComponent fails in MySound_UnInit");
+#endif
+ }
+ }
+}
+
+#define SOUND_SAMPLERATE 22255 /* = round(7833600 * 2 / 704) */
+
+LOCALFUNC blnr MySound_Init(void)
+{
+ OSStatus result = noErr;
+ Component comp;
+ ComponentDescription desc;
+ struct AURenderCallbackStruct callback;
+ AudioStreamBasicDescription requestedDesc;
+
+ cur_audio.fTheSoundBuffer = TheSoundBuffer;
+ cur_audio.fPlayOffset = &ThePlayOffset;
+ cur_audio.fFillOffset = &TheFillOffset;
+ cur_audio.fMinFilledSoundBuffs = &MinFilledSoundBuffs;
+ cur_audio.wantplaying = falseblnr;
+
+ desc.componentType = kAudioUnitType_Output;
+ desc.componentSubType = kAudioUnitSubType_DefaultOutput;
+ desc.componentManufacturer = kAudioUnitManufacturer_Apple;
+ desc.componentFlags = 0;
+ desc.componentFlagsMask = 0;
+
+
+ requestedDesc.mFormatID = kAudioFormatLinearPCM;
+ requestedDesc.mFormatFlags = kLinearPCMFormatFlagIsPacked
+#if 3 != kLn2SoundSampSz
+ | kLinearPCMFormatFlagIsSignedInteger
+#endif
+ ;
+ requestedDesc.mChannelsPerFrame = 1;
+ requestedDesc.mSampleRate = SOUND_SAMPLERATE;
+
+ requestedDesc.mBitsPerChannel = (1 << kLn2SoundSampSz);
+#if 0
+ requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
+#endif
+#if 0
+ requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
+#endif
+
+ requestedDesc.mFramesPerPacket = 1;
+ requestedDesc.mBytesPerFrame = (requestedDesc.mBitsPerChannel
+ * requestedDesc.mChannelsPerFrame) >> 3;
+ requestedDesc.mBytesPerPacket = requestedDesc.mBytesPerFrame
+ * requestedDesc.mFramesPerPacket;
+
+
+ callback.inputProc = audioCallback;
+ callback.inputProcRefCon = &cur_audio;
+
+ if (NULL == (comp = FindNextComponent(NULL, &desc)))
+ {
+#if dbglog_HAVE
+ dbglog_writeln("Failed to start CoreAudio: "
+ "FindNextComponent returned NULL");
+#endif
+ } else
+
+ if (noErr != (result = OpenAComponent(
+ comp, &cur_audio.outputAudioUnit)))
+ {
+#if dbglog_HAVE
+ dbglog_writeln("Failed to start CoreAudio: OpenAComponent");
+#endif
+ } else
+
+ if (noErr != (result = AudioUnitInitialize(
+ cur_audio.outputAudioUnit)))
+ {
+#if dbglog_HAVE
+ dbglog_writeln(
+ "Failed to start CoreAudio: AudioUnitInitialize");
+#endif
+ } else
+
+ if (noErr != (result = AudioUnitSetProperty(
+ cur_audio.outputAudioUnit,
+ kAudioUnitProperty_StreamFormat,
+ kAudioUnitScope_Input,
+ 0,
+ &requestedDesc,
+ sizeof(requestedDesc))))
+ {
+#if dbglog_HAVE
+ dbglog_writeln("Failed to start CoreAudio: "
+ "AudioUnitSetProperty(kAudioUnitProperty_StreamFormat)");
+#endif
+ } else
+
+ if (noErr != (result = AudioUnitSetProperty(
+ cur_audio.outputAudioUnit,
+ kAudioUnitProperty_SetRenderCallback,
+ kAudioUnitScope_Input,
+ 0,
+ &callback,
+ sizeof(callback))))
+ {
+#if dbglog_HAVE
+ dbglog_writeln("Failed to start CoreAudio: "
+ "AudioUnitSetProperty(kAudioUnitProperty_SetInputCallback)"
+ );
+#endif
+ } else
+
+ {
+ cur_audio.enabled = trueblnr;
+
+ MySound_Start();
+ /*
+ This should be taken care of by LeaveSpeedStopped,
+ but since takes a while to get going properly,
+ start early.
+ */
+ }
+
+ return trueblnr; /* keep going, even if no sound */
+}
+
+GLOBALOSGLUPROC MySound_EndWrite(ui4r actL)
+{
+ if (MySound_EndWrite0(actL)) {
+ }
+}
+
+LOCALPROC MySound_SecondNotify(void)
+{
+ if (cur_audio.enabled) {
+ MySound_SecondNotify0();
+ }
+}
+
+#endif
+
+LOCALPROC FinishSubMenu(NSMenu *theMenu, NSMenu *parentMenu,
+ NSString *sTitle)
+{
+ NSMenuItem *menuItem = [[NSMenuItem alloc]
+ initWithTitle: sTitle
+ action: nil
+ keyEquivalent: @""];
+
+ [menuItem setSubmenu: theMenu];
+ [parentMenu addItem: menuItem];
+ [menuItem release];
+}
+
+LOCALFUNC NSMenu *setApplicationMenu(NSMenu *mainMenu)
+{
+ NSMenuItem *menuItem;
+ NSString *sAppName = NSStringCreateFromSubstCStr("^p");
+ /* doesn't matter though, OS X replaces this */
+ NSString *sAbout =
+ NSStringCreateFromSubstCStr(kStrMenuItemAbout);
+ NSString *sHide =
+ NSStringCreateFromSubstCStr(kStrAppMenuItemHide);
+ NSString *sHideOthers =
+ NSStringCreateFromSubstCStr(kStrAppMenuItemHideOthers);
+ NSString *sShowAll =
+ NSStringCreateFromSubstCStr(kStrAppMenuItemShowAll);
+ NSString *sQuit =
+ NSStringCreateFromSubstCStr(kStrAppMenuItemQuit);
+
+ NSMenu *appleMenu = [[NSMenu alloc] initWithTitle: sAppName];
+
+ /* Add menu items */
+ menuItem = [appleMenu addItemWithTitle: sAbout
+ action: @selector(performApplicationAbout:)
+ keyEquivalent: @"a"];
+ [menuItem setKeyEquivalentModifierMask: NSControlKeyMask];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ [appleMenu addItemWithTitle: sHide
+ action: @selector(hide:) keyEquivalent: @""];
+
+ [appleMenu
+ addItemWithTitle: sHideOthers
+ action: @selector(hideOtherApplications:)
+ keyEquivalent: @""];
+
+ [appleMenu addItemWithTitle: sShowAll
+ action: @selector(unhideAllApplications:)
+ keyEquivalent: @""];
+
+ [appleMenu addItem: [NSMenuItem separatorItem]];
+
+ menuItem = [appleMenu addItemWithTitle: sQuit
+ action: @selector(terminate:) keyEquivalent: @"q"];
+ [menuItem setKeyEquivalentModifierMask: NSControlKeyMask];
+
+ FinishSubMenu(appleMenu, mainMenu, sAppName);
+
+ [appleMenu release];
+
+ return appleMenu;
+}
+
+/* Create File menu */
+LOCALPROC setupFileMenu(NSMenu *mainMenu)
+{
+ NSMenu *fileMenu;
+ NSMenuItem *menuItem;
+ NSString *sFile =
+ NSStringCreateFromSubstCStr(kStrMenuFile);
+ NSString *sOpen =
+ NSStringCreateFromSubstCStr(kStrMenuItemOpen ";ll");
+
+ fileMenu = [[NSMenu alloc] initWithTitle: sFile];
+
+ menuItem = [fileMenu
+ addItemWithTitle: sOpen
+ action: @selector(performFileOpen:)
+ keyEquivalent: @"o"];
+ [menuItem setKeyEquivalentModifierMask: NSControlKeyMask];
+
+ FinishSubMenu(fileMenu, mainMenu, sFile);
+
+ [fileMenu release];
+}
+
+/* Create Special menu */
+LOCALPROC setupSpecialMenu(NSMenu *mainMenu)
+{
+ NSMenu *specialMenu;
+ NSString *sSpecial =
+ NSStringCreateFromSubstCStr(kStrMenuSpecial);
+ NSString *sMore =
+ NSStringCreateFromSubstCStr(kStrMenuItemMore ";ll");
+
+ specialMenu = [[NSMenu alloc] initWithTitle: sSpecial];
+
+ [specialMenu
+ addItemWithTitle: sMore
+ action: @selector(performSpecialMoreCommands:)
+ keyEquivalent: @""];
+
+ FinishSubMenu(specialMenu, mainMenu, sSpecial);
+
+ [specialMenu release];
+}
+
+LOCALPROC MyMenuSetup(void)
+{
+ NSMenu *mainMenu = [[NSMenu alloc] init];
+ NSMenu *appleMenu = setApplicationMenu(mainMenu);
+
+ setupFileMenu(mainMenu);
+ setupSpecialMenu(mainMenu);
+
+ [NSApp setMainMenu: mainMenu];
+
+ /*
+ Tell the application object that this is now
+ the application menu, if this unsupported
+ call actually exists. Doesn't seem to
+ be needed anyway, at least in OS X 10.7
+ */
+ if([NSApp respondsToSelector:@selector(setAppleMenu:)]) {
+ /* [NSApp setAppleMenu: appleMenu]; */
+ [NSApp performSelector: @selector(setAppleMenu:)
+ withObject:appleMenu];
+ }
+
+ [mainMenu release];
+}
+
+
+
+/* --- video out --- */
+
+
+#if ! UseCGContextDrawImage
+LOCALPROC HaveChangedScreenBuff(ui4r top, ui4r left,
+ ui4r bottom, ui4r right)
+{
+ if ([MyNSview lockFocusIfCanDraw]) {
+ MyDrawWithOpenGL(top, left, bottom, right);
+ [MyNSview unlockFocus];
+ }
+}
+#else
+LOCALPROC HaveChangedScreenBuff(ui4r top, ui4r left,
+ ui4r bottom, ui4r right)
+{
+ int i;
+ int j;
+ ui3b *the_data = (ui3b *)GetCurDrawBuff();
+ ui3b *p;
+ ui5b color;
+ ui5b black_color = 0;
+ /* SDL_MapRGB(cur_video.format, 0, 0, 0) */
+ ui5b white_color = 0;
+ /* SDL_MapRGB(cur_video.format, 255, 255, 255) */
+
+ switch (MyBytesPerPixel) {
+ case 2: /* (1)-5-5-5 RGB */
+#if 0
+ rmask = 0x7C00;
+ gmask = 0x03E0;
+ bmask = 0x001F;
+#endif
+ break;
+ case 4:
+#if LittleEndianUnaligned
+#if 0
+ rmask = 0x0000FF00;
+ gmask = 0x00FF0000;
+ bmask = 0xFF000000;
+#endif
+ black_color = 0x000000FF;
+ white_color = 0xFFFFFFFF;
+#else
+#if 0
+ rmask = 0x00FF0000;
+ gmask = 0x0000FF00;
+ bmask = 0x000000FF;
+#endif
+ black_color = 0xFF000000;
+ white_color = 0xFFFFFFFF;
+#endif
+ break;
+ }
+
+#if EnableMagnify
+ if (UseMagnify) {
+ for (i = top * MyWindowScale; i < bottom * MyWindowScale; ++i) {
+ for (j = left * MyWindowScale;
+ j < right * MyWindowScale; ++j)
+ {
+ p = the_data + (((i / MyWindowScale) * vMacScreenWidth
+ + (j / MyWindowScale)) / 8);
+ if (0 != (*p & (1 << ((~ (j / MyWindowScale)) & 0x7))))
+ {
+ color = black_color;
+ } else {
+ color = white_color;
+ }
+ switch (MyBytesPerPixel) {
+ case 2: { /* Probably 15-bpp or 16-bpp */
+ ui4b *bufp;
+
+ bufp = (ui4b *)MyPixels
+ + i * MyPitch / 2 + j;
+ *bufp = color;
+ }
+ break;
+
+ case 4: { /* Probably 32-bpp */
+ ui5b *bufp;
+
+ bufp = (ui5b *)MyPixels
+ + i * MyPitch / 4 + j;
+ *bufp = color;
+ }
+ break;
+ }
+ }
+ }
+ } else
+#endif
+ {
+ for (i = top; i < bottom; ++i) {
+ for (j = left; j < right; ++j) {
+ p = the_data + ((i * vMacScreenWidth + j) / 8);
+ if (0 != (*p & (1 << ((~ j) & 0x7)))) {
+ color = black_color;
+ } else {
+ color = white_color;
+ }
+ switch (MyBytesPerPixel) {
+ case 2: { /* Probably 15-bpp or 16-bpp */
+ ui4b *bufp;
+
+ bufp = (ui4b *)MyPixels
+ + i * MyPitch / 2 + j;
+ *bufp = color;
+ }
+ break;
+ case 4: { /* Probably 32-bpp */
+ ui5b *bufp;
+
+ bufp = (ui5b *)MyPixels
+ + i * MyPitch / 4 + j;
+ *bufp = color;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+#if EnableMagnify
+ if (UseMagnify) {
+ SDL_UpdateRect(left * MyWindowScale,
+ top * MyWindowScale,
+ (right - left) * MyWindowScale,
+ (bottom - top) * MyWindowScale);
+ } else
+#endif
+ {
+ SDL_UpdateRect(left, top,
+ right - left, bottom - top);
+ }
+}
+#endif
+
+LOCALPROC MyDrawChangesAndClear(void)
+{
+ if (ScreenChangedBottom > ScreenChangedTop) {
+ HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft,
+ ScreenChangedBottom, ScreenChangedRight);
+ ScreenClearChanges();
+ }
+}
+
+GLOBALOSGLUPROC DoneWithDrawingForTick(void)
+{
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ AutoScrollScreen();
+ }
+#endif
+ MyDrawChangesAndClear();
+}
+
+/* --- keyboard input --- */
+
+LOCALPROC DisableKeyRepeat(void)
+{
+}
+
+LOCALPROC RestoreKeyRepeat(void)
+{
+}
+
+LOCALPROC ReconnectKeyCodes3(void)
+{
+}
+
+LOCALPROC DisconnectKeyCodes3(void)
+{
+ DisconnectKeyCodes2();
+ MyMouseButtonSet(falseblnr);
+}
+
+/* --- basic dialogs --- */
+
+LOCALPROC CheckSavedMacMsg(void)
+{
+ /* called only on quit, if error saved but not yet reported */
+
+ if (nullpr != SavedBriefMsg) {
+ NSString *briefMsg0 =
+ NSStringCreateFromSubstCStr(SavedBriefMsg);
+ NSString *longMsg0 =
+ NSStringCreateFromSubstCStr(SavedLongMsg);
+ NSString *quitMsg0 =
+ NSStringCreateFromSubstCStr(kStrCmdQuit);
+
+ (void) NSRunAlertPanel(briefMsg0, @"%@", quitMsg0, nil, nil,
+ longMsg0);
+
+ SavedBriefMsg = nullpr;
+ }
+}
+
+/* --- hide/show menubar --- */
+
+enum {
+ MyNSApplicationPresentationDefault = 0,
+ MyNSApplicationPresentationAutoHideDock = (1 << 0),
+ MyNSApplicationPresentationHideDock = (1 << 1),
+ MyNSApplicationPresentationAutoHideMenuBar = (1 << 2),
+ MyNSApplicationPresentationHideMenuBar = (1 << 3),
+ MyNSApplicationPresentationDisableAppleMenu = (1 << 4),
+ MyNSApplicationPresentationDisableProcessSwitching = (1 << 5),
+ MyNSApplicationPresentationDisableForceQuit = (1 << 6),
+ MyNSApplicationPresentationDisableSessionTermination = (1 << 7),
+ MyNSApplicationPresentationDisableHideApplication = (1 << 8),
+ MyNSApplicationPresentationDisableMenuBarTransparency = (1 << 9),
+ MyNSApplicationPresentationFullScreen = (1 << 10),
+ MyNSApplicationPresentationAutoHideToolbar = (1 << 11)
+};
+typedef NSUInteger MyNSApplicationPresentationOptions;
+
+@interface MyNSApplication : NSObject
+- (void)setPresentationOptions:
+ (MyNSApplicationPresentationOptions)newOptions;
+@end
+
+
+#if MayFullScreen
+LOCALPROC My_HideMenuBar(void)
+{
+ if ([NSApp respondsToSelector:@selector(setPresentationOptions:)]) {
+ [((MyNSApplication *)NSApp) setPresentationOptions:
+ MyNSApplicationPresentationHideDock
+ | MyNSApplicationPresentationHideMenuBar
+#if GrabKeysFullScreen
+ | MyNSApplicationPresentationDisableProcessSwitching
+#if GrabKeysMaxFullScreen /* dangerous !! */
+ | MyNSApplicationPresentationDisableForceQuit
+ | MyNSApplicationPresentationDisableSessionTermination
+#endif
+#endif
+ ];
+ } else
+ if (HaveMySetSystemUIMode()) {
+ (void) MySetSystemUIMode(MykUIModeAllHidden,
+ MykUIOptionDisableAppleMenu
+#if GrabKeysFullScreen
+ | MykUIOptionDisableProcessSwitch
+#if GrabKeysMaxFullScreen /* dangerous !! */
+ | MykUIOptionDisableForceQuit
+ | MykUIOptionDisableSessionTerminate
+#endif
+#endif
+ );
+ } else
+ {
+ }
+}
+#endif
+
+#if MayFullScreen
+LOCALPROC My_ShowMenuBar(void)
+{
+ if ([NSApp respondsToSelector:@selector(setPresentationOptions:)]) {
+ [((MyNSApplication *)NSApp) setPresentationOptions:
+ MyNSApplicationPresentationDefault];
+ } else
+ if (HaveMySetSystemUIMode()) {
+ (void) MySetSystemUIMode(MykUIModeNormal,
+ 0);
+ } else
+ {
+ }
+}
+#endif
+
+/* --- event handling for main window --- */
+
+LOCALPROC MyBeginDialog(void)
+{
+ DisconnectKeyCodes3();
+ ForceShowCursor();
+}
+
+LOCALPROC MyEndDialog(void)
+{
+ [MyWindow makeKeyWindow];
+ EmulationWasInterrupted = trueblnr;
+}
+
+LOCALPROC InsertADisk0(void)
+{
+ NSOpenPanel *panel = [NSOpenPanel openPanel];
+
+ [panel setAllowsMultipleSelection: YES];
+
+ MyBeginDialog();
+
+ if (NSOKButton == [panel runModal]) {
+ int i;
+ NSArray *a = [panel URLs];
+ int n = [a count];
+
+ for (i = 0; i < n; ++i) {
+ NSURL *fileURL = [a objectAtIndex: i];
+ NSString* filePath = [fileURL path];
+ (void) Sony_Insert1a(filePath);
+ }
+ }
+
+ MyEndDialog();
+}
+
+/* --- main window creation and disposal --- */
+
+LOCALFUNC blnr Screen_Init(void)
+{
+#if 0
+ if (noErr != Gestalt(gestaltSystemVersion,
+ &cur_video.system_version))
+ {
+ cur_video.system_version = 0;
+ }
+#endif
+
+#if 0
+#define MyCGMainDisplayID CGMainDisplayID
+ CGDirectDisplayID CurMainDisplayID = MyCGMainDisplayID();
+
+ cur_video.width = (ui5b) CGDisplayPixelsWide(CurMainDisplayID);
+ cur_video.height = (ui5b) CGDisplayPixelsHigh(CurMainDisplayID);
+#endif
+
+ InitKeyCodes();
+
+ return trueblnr;
+}
+
+#if MayFullScreen
+LOCALPROC AdjustMachineGrab(void)
+{
+#if EnableFSMouseMotion
+ AdjustMouseMotionGrab();
+#endif
+}
+#endif
+
+#if MayFullScreen
+LOCALPROC UngrabMachine(void)
+{
+ GrabMachine = falseblnr;
+ AdjustMachineGrab();
+}
+#endif
+
+LOCALPROC MyAdjustGLforSize(int h, int v)
+{
+ [MyNSOpnGLCntxt makeCurrentContext];
+
+ glClearColor (0.0, 0.0, 0.0, 1.0);
+
+#if 1
+ glViewport(0, 0, h, v);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, h, 0, v, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+#endif
+
+ glColor3f(0.0, 0.0, 0.0);
+#if EnableMagnify
+ if (UseMagnify) {
+ glPixelZoom(MyWindowScale, - MyWindowScale);
+ } else
+#endif
+ {
+ glPixelZoom(1, -1);
+ }
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, vMacScreenWidth);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ [NSOpenGLContext clearCurrentContext];
+
+ ScreenChangedAll();
+}
+
+LOCALVAR blnr WantScreensChangedCheck = falseblnr;
+
+LOCALPROC MyUpdateOpenGLContext(void)
+{
+ if (nil != MyNSOpnGLCntxt) {
+ [MyNSOpnGLCntxt makeCurrentContext];
+ [MyNSOpnGLCntxt update];
+ }
+}
+
+LOCALPROC CloseMyOpenGLContext(void)
+{
+ if (nil != MyNSOpnGLCntxt) {
+
+ [NSOpenGLContext clearCurrentContext];
+ /*
+ Only because MyDrawWithOpenGL doesn't
+ bother to do this. No one
+ uses the current context
+ without settting it first.
+ */
+ }
+}
+
+LOCALFUNC blnr GetOpnGLCntxt(void)
+{
+ blnr v = falseblnr;
+
+ if (nil == MyNSOpnGLCntxt) {
+ NSRect NewWinRect = [MyNSview frame];
+ NSOpenGLPixelFormat *fmt;
+
+#if WantGraphicsSwitching
+ {
+ NSOpenGLPixelFormatAttribute attr0[] = {
+ NSOpenGLPFAAllowOfflineRenderers,
+ 0};
+
+ fmt =
+ [[NSOpenGLPixelFormat alloc] initWithAttributes:attr0];
+ }
+ if (nil != fmt) {
+ /* ok */
+ } else
+#endif
+ {
+ NSOpenGLPixelFormatAttribute attr[] = {
+ 0};
+
+ fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
+ if (nil == fmt) {
+#if dbglog_HAVE
+ dbglog_writeln("Could not create fmt");
+#endif
+ goto label_exit;
+ }
+ }
+
+ MyNSOpnGLCntxt = [[NSOpenGLContext alloc]
+ initWithFormat:fmt shareContext:nil];
+
+ [fmt release];
+
+ if (nil == MyNSOpnGLCntxt) {
+#if dbglog_HAVE
+ dbglog_writeln("Could not create MyNSOpnGLCntxt");
+#endif
+ goto label_exit;
+ }
+
+ /* fprintf(stderr, "%s\n", "Got OpenGL context"); */
+
+ [MyNSOpnGLCntxt setView: MyNSview];
+ [MyNSOpnGLCntxt update];
+
+ MyAdjustGLforSize(NewWinRect.size.width,
+ NewWinRect.size.height);
+
+#if 0 != vMacScreenDepth
+ ColorModeWorks = trueblnr;
+#endif
+ }
+ v = trueblnr;
+
+label_exit:
+ return v;
+}
+
+typedef NSUInteger (*modifierFlagsProcPtr)
+ (id self, SEL cmd);
+
+/* Subclass of NSWindow to fix genie effect and support resize events */
+@interface MyClassWindow : NSWindow
+@end
+
+@implementation MyClassWindow
+
+#if MayFullScreen
+- (BOOL)canBecomeKeyWindow
+{
+ return
+#if VarFullScreen
+ (! UseFullScreen) ? [super canBecomeKeyWindow] :
+#endif
+ YES;
+}
+#endif
+
+#if MayFullScreen
+- (BOOL)canBecomeMainWindow
+{
+ return
+#if VarFullScreen
+ (! UseFullScreen) ? [super canBecomeMainWindow] :
+#endif
+ YES;
+}
+#endif
+
+#if MayFullScreen
+- (NSRect)constrainFrameRect:(NSRect)frameRect
+ toScreen:(NSScreen *)screen
+{
+#if VarFullScreen
+ if (! UseFullScreen) {
+ return [super constrainFrameRect:frameRect toScreen:screen];
+ } else
+#endif
+ {
+ return frameRect;
+ }
+}
+#endif
+
+- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
+{
+ /* NSPasteboard *pboard = [sender draggingPasteboard]; */
+ NSDragOperation sourceDragMask =
+ [sender draggingSourceOperationMask];
+ NSDragOperation v = NSDragOperationNone;
+
+ if (0 != (sourceDragMask & NSDragOperationGeneric)) {
+ return NSDragOperationGeneric;
+ }
+
+ return v;
+}
+
+- (void)draggingExited:(id <NSDraggingInfo>)sender
+{
+ /* remove hilighting */
+}
+
+- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
+{
+ return YES;
+}
+
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
+{
+ BOOL v = NO;
+ NSPasteboard *pboard = [sender draggingPasteboard];
+ /*
+ NSDragOperation sourceDragMask =
+ [sender draggingSourceOperationMask];
+ */
+
+ if ([[pboard types] containsObject:NSFilenamesPboardType]) {
+ int i;
+ NSArray *file_names =
+ [pboard propertyListForType: NSFilenamesPboardType];
+ int n = [file_names count];
+
+ for (i = 0; i < n; ++i) {
+ NSString *filePath = [file_names objectAtIndex:i];
+ Sony_ResolveInsert(filePath);
+ }
+ v = YES;
+ } else if ([[pboard types] containsObject: NSURLPboardType]) {
+ NSURL *fileURL = [NSURL URLFromPasteboard: pboard];
+ NSString* filePath = [fileURL path];
+ Sony_ResolveInsert(filePath);
+ v = YES;
+ }
+
+ if (v && gTrueBackgroundFlag) {
+ {
+ SEL sel = @selector(modifierFlags);
+
+ if ([NSEvent respondsToSelector:sel]) {
+ modifierFlagsProcPtr imp = (modifierFlagsProcPtr)
+ [NSEvent methodForSelector:sel];
+
+ MyUpdateKeyboardModifiers(imp([NSEvent class], sel));
+ }
+ }
+
+ [NSApp activateIgnoringOtherApps: YES];
+ }
+
+ return v;
+}
+
+- (void) concludeDragOperation:(id <NSDraggingInfo>)the_sender
+{
+}
+
+@end
+
+@interface MyClassWindowDelegate : NSObject <NSWindowDelegate>
+@end
+
+@implementation MyClassWindowDelegate
+
+- (BOOL)windowShouldClose:(id)sender
+{
+ RequestMacOff = trueblnr;
+ return NO;
+}
+
+- (void)windowDidBecomeKey:(NSNotification *)aNotification
+{
+ gTrueBackgroundFlag = falseblnr;
+}
+
+- (void)windowDidResignKey:(NSNotification *)aNotification
+{
+ gTrueBackgroundFlag = trueblnr;
+}
+
+@end
+
+@interface MyClassView : NSView
+@end
+
+@implementation MyClassView
+
+- (void)resetCursorRects
+{
+ [self addCursorRect: [self visibleRect]
+ cursor: [NSCursor arrowCursor]];
+}
+
+- (BOOL)isOpaque
+{
+ return YES;
+}
+
+- (void)drawRect:(NSRect)dirtyRect
+{
+ /*
+ Called upon makeKeyAndOrderFront. Create our
+ OpenGL context here, because can't do so
+ before makeKeyAndOrderFront.
+ And if create after then our content won't
+ be drawn initially, resulting in flicker.
+ */
+ if (GetOpnGLCntxt()) {
+ MyDrawWithOpenGL(0, 0, vMacScreenHeight, vMacScreenWidth);
+ }
+}
+
+@end
+
+#if UseCGContextDrawImage
+/* absent in 10.3.9. */
+CG_EXTERN CGImageRef CGBitmapContextCreateImage(CGContextRef);
+#endif
+
+
+LOCALVAR MyClassWindowDelegate *MyWinDelegate = nil;
+
+LOCALPROC CloseMainWindow(void)
+{
+ if (nil != MyWinDelegate) {
+ [MyWinDelegate release];
+ MyWinDelegate = nil;
+ }
+
+ if (nil != MyWindow) {
+ [MyWindow close];
+ MyWindow = nil;
+ }
+
+ if (nil != MyNSview) {
+ [MyNSview release];
+ MyNSview = nil;
+ }
+
+#if UseCGContextDrawImage
+ if (nil != MyCGcontext) {
+ CGContextFlush(MyCGcontext);
+ CGContextRelease(MyCGcontext);
+ MyCGcontext = nil;
+ }
+
+ if (NULL != MyPixels) {
+ free(MyPixels);
+ MyPixels = NULL;
+ }
+#endif
+
+ if (nil != MyNSOpnGLCntxt) {
+ [MyNSOpnGLCntxt release];
+ MyNSOpnGLCntxt = nil;
+ }
+}
+
+LOCALPROC QZ_SetCaption(void)
+{
+#if 0
+ NSString *string =
+ [[NSString alloc] initWithUTF8String: kStrAppName];
+#endif
+ [MyWindow setTitle: myAppName /* string */];
+#if 0
+ [string release];
+#endif
+}
+
+enum {
+ kMagStateNormal,
+#if EnableMagnify
+ kMagStateMagnifgy,
+#endif
+ kNumMagStates
+};
+
+#define kMagStateAuto kNumMagStates
+
+#if MayNotFullScreen
+LOCALVAR int CurWinIndx;
+LOCALVAR blnr HavePositionWins[kNumMagStates];
+LOCALVAR NSPoint WinPositionWins[kNumMagStates];
+#endif
+
+LOCALVAR NSRect SavedScrnBounds;
+
+LOCALFUNC blnr CreateMainWindow(void)
+{
+#if UseCGContextDrawImage
+ CGColorSpaceRef cgColorspace;
+#endif
+ unsigned int style;
+ NSRect MainScrnBounds;
+ NSRect AllScrnBounds;
+ NSRect NewWinRect;
+ NSPoint botleftPos;
+ int NewWindowHeight = vMacScreenHeight;
+ int NewWindowWidth = vMacScreenWidth;
+ blnr v = falseblnr;
+
+#if VarFullScreen
+ if (UseFullScreen) {
+ My_HideMenuBar();
+ } else {
+ My_ShowMenuBar();
+ }
+#else
+#if MayFullScreen
+ My_HideMenuBar();
+#endif
+#endif
+
+ MainScrnBounds = [[NSScreen mainScreen] frame];
+ SavedScrnBounds = MainScrnBounds;
+ {
+ int i;
+ NSArray *screens = [NSScreen screens];
+ int n = [screens count];
+
+ AllScrnBounds = MainScrnBounds;
+ for (i = 0; i < n; ++i) {
+ AllScrnBounds = NSUnionRect(AllScrnBounds,
+ [[screens objectAtIndex:i] frame]);
+ }
+ }
+
+#if EnableMagnify
+ if (UseMagnify) {
+ NewWindowHeight *= MyWindowScale;
+ NewWindowWidth *= MyWindowScale;
+ }
+#endif
+
+ botleftPos.x = MainScrnBounds.origin.x
+ + floor((MainScrnBounds.size.width
+ - NewWindowWidth) / 2);
+ botleftPos.y = MainScrnBounds.origin.y
+ + floor((MainScrnBounds.size.height
+ - NewWindowHeight) / 2);
+ if (botleftPos.x < MainScrnBounds.origin.x) {
+ botleftPos.x = MainScrnBounds.origin.x;
+ }
+ if (botleftPos.y < MainScrnBounds.origin.y) {
+ botleftPos.y = MainScrnBounds.origin.y;
+ }
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ ViewHSize = MainScrnBounds.size.width;
+ ViewVSize = MainScrnBounds.size.height;
+#if EnableMagnify
+ if (UseMagnify) {
+ ViewHSize /= MyWindowScale;
+ ViewVSize /= MyWindowScale;
+ }
+#endif
+ if (ViewHSize >= vMacScreenWidth) {
+ ViewHStart = 0;
+ ViewHSize = vMacScreenWidth;
+ } else {
+ ViewHSize &= ~ 1;
+ }
+ if (ViewVSize >= vMacScreenHeight) {
+ ViewVStart = 0;
+ ViewVSize = vMacScreenHeight;
+ } else {
+ ViewVSize &= ~ 1;
+ }
+ }
+#endif
+
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewWinRect = AllScrnBounds;
+
+ GLhOffset = botleftPos.x - AllScrnBounds.origin.x;
+ GLvOffset = (botleftPos.y - AllScrnBounds.origin.y)
+ + ((NewWindowHeight < MainScrnBounds.size.height)
+ ? NewWindowHeight : MainScrnBounds.size.height);
+
+ hOffset = GLhOffset;
+ vOffset = AllScrnBounds.size.height - GLvOffset;
+
+ style = NSBorderlessWindowMask;
+ }
+#endif
+#if VarFullScreen
+ else
+#endif
+#if MayNotFullScreen
+ {
+ int WinIndx;
+
+#if EnableMagnify
+ if (UseMagnify) {
+ WinIndx = kMagStateMagnifgy;
+ } else
+#endif
+ {
+ WinIndx = kMagStateNormal;
+ }
+
+ if (! HavePositionWins[WinIndx]) {
+ WinPositionWins[WinIndx].x = botleftPos.x;
+ WinPositionWins[WinIndx].y = botleftPos.y;
+ HavePositionWins[WinIndx] = trueblnr;
+ NewWinRect = NSMakeRect(botleftPos.x, botleftPos.y,
+ NewWindowWidth, NewWindowHeight);
+ } else {
+ NewWinRect = NSMakeRect(WinPositionWins[WinIndx].x,
+ WinPositionWins[WinIndx].y,
+ NewWindowWidth, NewWindowHeight);
+ }
+
+ GLhOffset = 0;
+ GLvOffset = NewWindowHeight;
+
+ style = NSTitledWindowMask
+ | NSMiniaturizableWindowMask | NSClosableWindowMask;
+
+ CurWinIndx = WinIndx;
+ }
+#endif
+
+ /* Manually create a window, avoids having a nib file resource */
+ MyWindow = [[MyClassWindow alloc]
+ initWithContentRect: NewWinRect
+ styleMask: style
+ backing: NSBackingStoreBuffered
+ defer: YES];
+
+ if (nil == MyWindow) {
+#if dbglog_HAVE
+ dbglog_writeln("Could not create the Cocoa window");
+#endif
+ goto label_exit;
+ }
+
+ /* [MyWindow setReleasedWhenClosed: YES]; */
+ /*
+ no need to set current_video as it's the
+ default for NSWindows
+ */
+ QZ_SetCaption();
+ [MyWindow setAcceptsMouseMovedEvents: YES];
+ [MyWindow setViewsNeedDisplay: NO];
+
+ [MyWindow registerForDraggedTypes:
+ [NSArray arrayWithObjects:
+ NSURLPboardType, NSFilenamesPboardType, nil]];
+
+ MyWinDelegate = [[MyClassWindowDelegate alloc] init];
+ if (nil == MyWinDelegate) {
+#if dbglog_HAVE
+ dbglog_writeln("Could not create MyNSview");
+#endif
+ goto label_exit;
+ }
+ [MyWindow setDelegate: MyWinDelegate];
+
+ MyNSview = [[MyClassView alloc] init];
+ if (nil == MyNSview) {
+#if dbglog_HAVE
+ dbglog_writeln("Could not create MyNSview");
+#endif
+ goto label_exit;
+ }
+ [MyWindow setContentView: MyNSview];
+
+ [MyWindow makeKeyAndOrderFront: nil];
+
+ /* just in case drawRect didn't get called */
+ if (! GetOpnGLCntxt()) {
+#if dbglog_HAVE
+ dbglog_writeln("Could not GetOpnGLCntxt");
+#endif
+ goto label_exit;
+ }
+
+#if UseCGContextDrawImage
+ MyPitch = 4 * NewWindowWidth;
+ MyPixels = malloc(NewWindowHeight * MyPitch);
+
+ cgColorspace = CGColorSpaceCreateDeviceRGB();
+ MyCGcontext = CGBitmapContextCreate(MyPixels,
+ NewWindowWidth, NewWindowHeight,
+ 8, MyPitch, cgColorspace,
+ kCGImageAlphaNoneSkipFirst);
+ CGColorSpaceRelease(cgColorspace);
+
+ MyNSgfxContext = [NSGraphicsContext
+ graphicsContextWithWindow: MyWindow];
+ [NSGraphicsContext setCurrentContext: MyNSgfxContext];
+
+ MyBytesPerPixel = 4;
+#endif
+
+ v = trueblnr;
+
+label_exit:
+
+ return v;
+}
+
+#if EnableRecreateW
+LOCALPROC ZapMyWState(void)
+{
+ MyWindow = nil;
+ MyNSview = nil;
+ MyWinDelegate = nil;
+#if UseCGContextDrawImage
+ MyNSgfxContext = nil;
+ MyCGcontext = nil;
+ MyPixels = NULL;
+#endif
+ MyNSOpnGLCntxt = nil;
+}
+#endif
+
+#if EnableRecreateW
+struct MyWState {
+#if MayFullScreen
+ ui4r f_ViewHSize;
+ ui4r f_ViewVSize;
+ ui4r f_ViewHStart;
+ ui4r f_ViewVStart;
+ short f_hOffset;
+ short f_vOffset;
+#endif
+#if VarFullScreen
+ blnr f_UseFullScreen;
+#endif
+#if EnableMagnify
+ blnr f_UseMagnify;
+#endif
+#if MayNotFullScreen
+ int f_CurWinIndx;
+#endif
+ NSWindow *f_MyWindow;
+ NSView *f_MyNSview;
+ MyClassWindowDelegate *f_MyWinDelegate;
+#if UseCGContextDrawImage
+ NSGraphicsContext *f_MyNSgfxContext;
+ CGContextRef f_MyCGcontext;
+ void *f_MyPixels;
+ ui4b f_MyPitch;
+ ui3b f_MyBytesPerPixel;
+#endif
+ NSOpenGLContext *f_MyNSOpnGLCntxt;
+ short f_GLhOffset;
+ short f_GLvOffset;
+};
+typedef struct MyWState MyWState;
+#endif
+
+#if EnableRecreateW
+LOCALPROC GetMyWState(MyWState *r)
+{
+#if MayFullScreen
+ r->f_ViewHSize = ViewHSize;
+ r->f_ViewVSize = ViewVSize;
+ r->f_ViewHStart = ViewHStart;
+ r->f_ViewVStart = ViewVStart;
+ r->f_hOffset = hOffset;
+ r->f_vOffset = vOffset;
+#endif
+#if VarFullScreen
+ r->f_UseFullScreen = UseFullScreen;
+#endif
+#if EnableMagnify
+ r->f_UseMagnify = UseMagnify;
+#endif
+#if MayNotFullScreen
+ r->f_CurWinIndx = CurWinIndx;
+#endif
+ r->f_MyWindow = MyWindow;
+ r->f_MyNSview = MyNSview;
+ r->f_MyWinDelegate = MyWinDelegate;
+#if UseCGContextDrawImage
+ r->f_MyNSgfxContext = MyNSgfxContext;
+ r->f_MyCGcontext = MyCGcontext;
+ r->f_MyPixels = MyPixels;
+ r->f_MyPitch = MyPitch;
+ r->f_MyBytesPerPixel = MyBytesPerPixel;
+#endif
+ r->f_MyNSOpnGLCntxt = MyNSOpnGLCntxt;
+ r->f_GLhOffset = GLhOffset;
+ r->f_GLvOffset = GLvOffset;
+}
+#endif
+
+#if EnableRecreateW
+LOCALPROC SetMyWState(MyWState *r)
+{
+#if MayFullScreen
+ ViewHSize = r->f_ViewHSize;
+ ViewVSize = r->f_ViewVSize;
+ ViewHStart = r->f_ViewHStart;
+ ViewVStart = r->f_ViewVStart;
+ hOffset = r->f_hOffset;
+ vOffset = r->f_vOffset;
+#endif
+#if VarFullScreen
+ UseFullScreen = r->f_UseFullScreen;
+#endif
+#if EnableMagnify
+ UseMagnify = r->f_UseMagnify;
+#endif
+#if MayNotFullScreen
+ CurWinIndx = r->f_CurWinIndx;
+#endif
+ MyWindow = r->f_MyWindow;
+ MyNSview = r->f_MyNSview;
+ MyWinDelegate = r->f_MyWinDelegate;
+#if UseCGContextDrawImage
+ MyNSgfxContext = r->f_MyNSgfxContext;
+ MyCGcontext = r->f_MyCGcontext;
+ MyPixels = r->f_MyPixels;
+ MyPitch = r->f_MyPitch;
+ MyBytesPerPixel = r->f_MyBytesPerPixel;
+#endif
+ MyNSOpnGLCntxt = r->f_MyNSOpnGLCntxt;
+ GLhOffset = r->f_GLhOffset;
+ GLvOffset = r->f_GLvOffset;
+}
+#endif
+
+#if EnableRecreateW
+LOCALPROC ReCreateMainWindow(void)
+{
+ MyWState old_state;
+ MyWState new_state;
+ blnr HadCursorHidden = HaveCursorHidden;
+
+#if VarFullScreen
+ if (! UseFullScreen)
+#endif
+#if MayNotFullScreen
+ {
+ /* save old position */
+ NSRect r =
+ [NSWindow contentRectForFrameRect: [MyWindow frame]
+ styleMask: [MyWindow styleMask]];
+ WinPositionWins[CurWinIndx] = r.origin;
+ }
+#endif
+
+#if MayFullScreen
+ if (GrabMachine) {
+ GrabMachine = falseblnr;
+ UngrabMachine();
+ }
+#endif
+
+ CloseMyOpenGLContext();
+
+ GetMyWState(&old_state);
+
+ ZapMyWState();
+
+#if EnableMagnify
+ UseMagnify = WantMagnify;
+#endif
+#if VarFullScreen
+ UseFullScreen = WantFullScreen;
+#endif
+
+ if (! CreateMainWindow()) {
+ CloseMainWindow();
+ SetMyWState(&old_state);
+
+#if VarFullScreen
+ if (UseFullScreen) {
+ My_HideMenuBar();
+ } else {
+ My_ShowMenuBar();
+ }
+#endif
+
+ /* avoid retry */
+#if VarFullScreen
+ WantFullScreen = UseFullScreen;
+#endif
+#if EnableMagnify
+ WantMagnify = UseMagnify;
+#endif
+
+ } else {
+ GetMyWState(&new_state);
+ SetMyWState(&old_state);
+ CloseMainWindow();
+ SetMyWState(&new_state);
+
+ if (HadCursorHidden) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ }
+ }
+}
+#endif
+
+#if VarFullScreen && EnableMagnify
+enum {
+ kWinStateWindowed,
+#if EnableMagnify
+ kWinStateFullScreen,
+#endif
+ kNumWinStates
+};
+#endif
+
+#if VarFullScreen && EnableMagnify
+LOCALVAR int WinMagStates[kNumWinStates];
+#endif
+
+LOCALPROC ZapWinStateVars(void)
+{
+#if MayNotFullScreen
+ {
+ int i;
+
+ for (i = 0; i < kNumMagStates; ++i) {
+ HavePositionWins[i] = falseblnr;
+ }
+ }
+#endif
+#if VarFullScreen && EnableMagnify
+ {
+ int i;
+
+ for (i = 0; i < kNumWinStates; ++i) {
+ WinMagStates[i] = kMagStateAuto;
+ }
+ }
+#endif
+}
+
+#if VarFullScreen
+LOCALPROC ToggleWantFullScreen(void)
+{
+ WantFullScreen = ! WantFullScreen;
+
+#if EnableMagnify
+ {
+ int OldWinState =
+ UseFullScreen ? kWinStateFullScreen : kWinStateWindowed;
+ int OldMagState =
+ UseMagnify ? kMagStateMagnifgy : kMagStateNormal;
+ int NewWinState =
+ WantFullScreen ? kWinStateFullScreen : kWinStateWindowed;
+ int NewMagState = WinMagStates[NewWinState];
+
+ WinMagStates[OldWinState] = OldMagState;
+ if (kMagStateAuto != NewMagState) {
+ WantMagnify = (kMagStateMagnifgy == NewMagState);
+ } else {
+ WantMagnify = falseblnr;
+ if (WantFullScreen) {
+ NSRect MainScrnBounds = [[NSScreen mainScreen] frame];
+
+ if ((MainScrnBounds.size.width
+ >= vMacScreenWidth * MyWindowScale)
+ && (MainScrnBounds.size.height
+ >= vMacScreenHeight * MyWindowScale)
+ )
+ {
+ WantMagnify = trueblnr;
+ }
+ }
+ }
+ }
+#endif
+}
+#endif
+
+/* --- SavedTasks --- */
+
+LOCALPROC LeaveBackground(void)
+{
+ ReconnectKeyCodes3();
+ DisableKeyRepeat();
+ EmulationWasInterrupted = trueblnr;
+}
+
+LOCALPROC EnterBackground(void)
+{
+ RestoreKeyRepeat();
+ DisconnectKeyCodes3();
+
+ ForceShowCursor();
+}
+
+LOCALPROC LeaveSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Start();
+#endif
+
+ StartUpTimeAdjust();
+}
+
+LOCALPROC EnterSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+}
+
+#if IncludeSonyNew && ! SaveDialogEnable
+LOCALFUNC blnr FindOrMakeNamedChildDirPath(NSString *parentPath,
+ char *ChildName, NSString **childPath)
+{
+ NSString *r;
+ BOOL isDir;
+ Boolean isDirectory;
+ NSFileManager *fm = [NSFileManager defaultManager];
+ blnr v = falseblnr;
+
+ if (FindNamedChildPath(parentPath, ChildName, &r)) {
+ if ([fm fileExistsAtPath:r isDirectory: &isDir])
+ {
+ if (isDir) {
+ *childPath = r;
+ v = trueblnr;
+ } else {
+ NSString *RslvPath = MyResolveAlias(r, &isDirectory);
+ if (nil != RslvPath) {
+ if (isDirectory) {
+ *childPath = RslvPath;
+ v = trueblnr;
+ }
+ }
+ }
+ } else {
+ if ([fm respondsToSelector:@selector(
+createDirectoryAtPath:withIntermediateDirectories:attributes:error:
+ )])
+ {
+ if ([fm
+ createDirectoryAtPath:r
+ withIntermediateDirectories:NO
+ attributes:nil
+ error:nil])
+ {
+ *childPath = r;
+ v = trueblnr;
+ }
+ } else
+ if ([fm respondsToSelector:
+ @selector(createDirectoryAtPath:attributes:)])
+ {
+ if ([fm
+ createDirectoryAtPath:r
+ attributes:nil])
+ {
+ *childPath = r;
+ v = trueblnr;
+ }
+ } else
+ {
+ /* fail */
+ }
+ }
+ }
+
+ return v;
+}
+#endif
+
+@interface MyNSSavePanel : NSObject
+- (NSInteger)runModalForDirectory:(NSString *)path
+ file:(NSString *)filename;
+- (void)setNameFieldStringValue:(NSString *)value;
+@end
+
+#if IncludeSonyNew
+LOCALPROC MakeNewDisk(ui5b L, NSString *drivename)
+{
+#if SaveDialogEnable
+ NSInteger result = NSCancelButton;
+ NSSavePanel *panel = [NSSavePanel savePanel];
+
+ MyBeginDialog();
+
+ if ([panel respondsToSelector:@selector(setNameFieldStringValue:)])
+ {
+#if 0
+ [panel setNameFieldStringValue: drivename];
+ /* available as of OS X 10.6 */
+#endif
+#if 0
+ [panel performSelector:@selector(setNameFieldStringValue:)
+ withObject: drivename];
+#endif
+ [((MyNSSavePanel *)panel)
+ setNameFieldStringValue: drivename];
+
+ result = [panel runModal];
+ } else
+ if ([panel
+ respondsToSelector: @selector(runModalForDirectory:file:)])
+ {
+#if 0
+ result = [panel runModalForDirectory: nil file: drivename];
+ /*
+ compiler warns deprecated. To avoid warning, and
+ to still work if removed from SDK, use NSInvocation.
+ */
+#endif
+#if 0
+ NSString *sDirName = nil;
+ SEL sel = @selector(runModalForDirectory:file:);
+ NSInvocation* invoc =
+ [NSInvocation invocationWithMethodSignature:
+ [panel methodSignatureForSelector: sel]];
+ [invoc setTarget:panel];
+ [invoc setSelector:sel];
+ [invoc setArgument:&sDirName atIndex:2];
+ [invoc setArgument:&drivename atIndex:3];
+ [invoc invoke];
+ [invoc getReturnValue: &result];
+#endif
+ /* an easier way ? seems to work */
+ result = [((MyNSSavePanel *)panel)
+ runModalForDirectory: nil file: drivename];
+ } else
+ {
+ /* fail */
+ }
+
+ MyEndDialog();
+
+ if (NSOKButton == result) {
+ NSString* filePath = [[panel URL] path];
+ MakeNewDisk0(L, filePath);
+ }
+#else /* SaveDialogEnable */
+ NSString *sPath;
+
+ if (FindOrMakeNamedChildDirPath(MyDataPath, "out", &sPath)) {
+ NSString *filePath =
+ [sPath stringByAppendingPathComponent: drivename];
+ MakeNewDisk0(L, filePath);
+ }
+#endif /* SaveDialogEnable */
+}
+#endif
+
+#if IncludeSonyNew
+LOCALPROC MakeNewDiskAtDefault(ui5b L)
+{
+ MakeNewDisk(L, @"untitled.dsk");
+}
+#endif
+
+LOCALPROC CheckForSavedTasks(void)
+{
+ if (MyEvtQNeedRecover) {
+ MyEvtQNeedRecover = falseblnr;
+
+ /* attempt cleanup, MyEvtQNeedRecover may get set again */
+ MyEvtQTryRecoverFromFull();
+ }
+
+ if (RequestMacOff) {
+ RequestMacOff = falseblnr;
+ if (AnyDiskInserted()) {
+ MacMsgOverride(kStrQuitWarningTitle,
+ kStrQuitWarningMessage);
+ } else {
+ ForceMacOff = trueblnr;
+ }
+ }
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (gTrueBackgroundFlag != gBackgroundFlag) {
+ gBackgroundFlag = gTrueBackgroundFlag;
+ if (gTrueBackgroundFlag) {
+ EnterBackground();
+ } else {
+ LeaveBackground();
+ }
+ }
+
+ if (EmulationWasInterrupted) {
+ EmulationWasInterrupted = falseblnr;
+
+ if (! gTrueBackgroundFlag) {
+ CheckMouseState();
+ }
+ }
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMouseConstrain();
+ }
+#endif
+
+#if VarFullScreen
+ if (gTrueBackgroundFlag && WantFullScreen) {
+ ToggleWantFullScreen();
+ }
+#endif
+
+ if (WantScreensChangedCheck) {
+ WantScreensChangedCheck = falseblnr;
+
+ MyUpdateOpenGLContext();
+
+#if VarFullScreen
+ /*
+ triggered on enter full screen for some
+ reason in OS X 10.11. so check against
+ saved rect.
+ */
+ if ((WantFullScreen)
+ && (! NSEqualRects(SavedScrnBounds,
+ [[NSScreen mainScreen] frame])))
+ {
+ ToggleWantFullScreen();
+ }
+#endif
+ }
+
+ if (CurSpeedStopped != (SpeedStopped ||
+ (gBackgroundFlag && ! RunInBackground
+#if EnableAutoSlow && 0
+ && (QuietSubTicks >= 4092)
+#endif
+ )))
+ {
+ CurSpeedStopped = ! CurSpeedStopped;
+ if (CurSpeedStopped) {
+ EnterSpeedStopped();
+ } else {
+ LeaveSpeedStopped();
+ }
+ }
+
+ if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) {
+ MacMsgDisplayOn();
+ }
+
+#if EnableRecreateW
+ if (0
+#if EnableMagnify
+ || (UseMagnify != WantMagnify)
+#endif
+#if VarFullScreen
+ || (UseFullScreen != WantFullScreen)
+#endif
+ )
+ {
+ ReCreateMainWindow();
+ }
+#endif
+
+#if MayFullScreen
+ if (GrabMachine != (
+#if VarFullScreen
+ UseFullScreen &&
+#endif
+ ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ GrabMachine = ! GrabMachine;
+ AdjustMachineGrab();
+ }
+#endif
+
+#if IncludeSonyNew
+ if (vSonyNewDiskWanted) {
+#if IncludeSonyNameNew
+ if (vSonyNewDiskName != NotAPbuf) {
+ NSString *sNewDiskName;
+ if (MacRomanFileNameToNSString(vSonyNewDiskName,
+ &sNewDiskName))
+ {
+ MakeNewDisk(vSonyNewDiskSize, sNewDiskName);
+ }
+ PbufDispose(vSonyNewDiskName);
+ vSonyNewDiskName = NotAPbuf;
+ } else
+#endif
+ {
+ MakeNewDiskAtDefault(vSonyNewDiskSize);
+ }
+ vSonyNewDiskWanted = falseblnr;
+ /* must be done after may have gotten disk */
+ }
+#endif
+
+ if (NeedWholeScreenDraw) {
+ NeedWholeScreenDraw = falseblnr;
+ ScreenChangedAll();
+ }
+
+ if (! gTrueBackgroundFlag) {
+ if (RequestInsertDisk) {
+ RequestInsertDisk = falseblnr;
+ InsertADisk0();
+ }
+ }
+
+#if NeedRequestIthDisk
+ if (0 != RequestIthDisk) {
+ Sony_InsertIth(RequestIthDisk);
+ RequestIthDisk = 0;
+ }
+#endif
+
+ if (HaveCursorHidden != (
+#if MayNotFullScreen
+ (WantCursorHidden
+#if VarFullScreen
+ || UseFullScreen
+#endif
+ ) &&
+#endif
+ ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ HaveCursorHidden = ! HaveCursorHidden;
+ if (HaveCursorHidden) {
+ MyHideCursor();
+ } else {
+ MyShowCursor();
+ }
+ }
+
+#if 1
+ /*
+ Check if actual cursor visibility is what it should be.
+ If move mouse to dock then cursor is made visible, but then
+ if move directly to our window, cursor is not hidden again.
+ */
+ if (HaveMyCGCursorIsVisible()) {
+ /* but only in OS X 10.3 and later */
+ /* deprecated in cocoa, but no alternative (?) */
+ if (MyCGCursorIsVisible()) {
+ if (HaveCursorHidden) {
+ MyHideCursor();
+ if (MyCGCursorIsVisible()) {
+ /*
+ didn't work, attempt undo so that
+ hide cursor count won't get large
+ */
+ MyShowCursor();
+ }
+ }
+ } else {
+ if (! HaveCursorHidden) {
+ MyShowCursor();
+ /*
+ don't check if worked, assume can't decrement
+ hide cursor count below 0
+ */
+ }
+ }
+ }
+#endif
+}
+
+/* --- main program flow --- */
+
+GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void)
+{
+ UpdateTrueEmulatedTime();
+ return TrueEmulatedTime == OnTrueTime;
+}
+
+LOCALPROC ProcessEventModifiers(NSEvent *event)
+{
+ NSUInteger newMods = [event modifierFlags];
+
+ MyUpdateKeyboardModifiers(newMods);
+}
+
+LOCALPROC ProcessEventLocation(NSEvent *event)
+{
+ NSPoint p = [event locationInWindow];
+ NSWindow *w = [event window];
+
+ if (w != MyWindow) {
+ if (nil != w) {
+ p = [w convertBaseToScreen: p];
+ }
+ p = [MyWindow convertScreenToBase: p];
+ }
+ p = [MyNSview convertPoint: p fromView: nil];
+ p.y = [MyNSview frame].size.height - p.y;
+ MousePositionNotify((int) p.x, (int) p.y);
+}
+
+LOCALPROC ProcessKeyEvent(blnr down, NSEvent *event)
+{
+ ui3r scancode = [event keyCode];
+
+ ProcessEventModifiers(event);
+ Keyboard_UpdateKeyMap2(Keyboard_RemapMac(scancode), down);
+}
+
+LOCALPROC ProcessOneSystemEvent(NSEvent *event)
+{
+ switch ([event type]) {
+ case NSLeftMouseDown:
+ case NSRightMouseDown:
+ case NSOtherMouseDown:
+ /*
+ int button = QZ_OtherMouseButtonToSDL(
+ [event buttonNumber]);
+ */
+ ProcessEventLocation(event);
+ ProcessEventModifiers(event);
+ if (([event window] == MyWindow)
+ && (! gTrueBackgroundFlag)
+#if MayNotFullScreen
+ && (WantCursorHidden
+#if VarFullScreen
+ || UseFullScreen
+#endif
+ )
+#endif
+ )
+ {
+ MyMouseButtonSet(trueblnr);
+ } else {
+ /* doesn't belong to us */
+ [NSApp sendEvent: event];
+ }
+ break;
+
+ case NSLeftMouseUp:
+ case NSRightMouseUp:
+ case NSOtherMouseUp:
+ /*
+ int button = QZ_OtherMouseButtonToSDL(
+ [event buttonNumber]);
+ */
+ ProcessEventLocation(event);
+ ProcessEventModifiers(event);
+ if (! MyMouseButtonState) {
+ /* doesn't belong to us */
+ [NSApp sendEvent: event];
+ } else {
+ MyMouseButtonSet(falseblnr);
+ }
+ break;
+
+ case NSMouseMoved:
+ {
+ ProcessEventLocation(event);
+ ProcessEventModifiers(event);
+ }
+ break;
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSOtherMouseDragged:
+ if (! MyMouseButtonState) {
+ /* doesn't belong to us ? */
+ [NSApp sendEvent: event];
+ } else {
+ ProcessEventLocation(event);
+ ProcessEventModifiers(event);
+ }
+ break;
+ case NSKeyUp:
+ ProcessKeyEvent(falseblnr, event);
+ break;
+ case NSKeyDown:
+ ProcessKeyEvent(trueblnr, event);
+ break;
+ case NSFlagsChanged:
+ ProcessEventModifiers(event);
+ break;
+ /* case NSScrollWheel: */
+ /* case NSSystemDefined: */
+ /* case NSAppKitDefined: */
+ /* case NSApplicationDefined: */
+ /* case NSPeriodic: */
+ /* case NSCursorUpdate: */
+ default:
+ [NSApp sendEvent: event];
+ }
+}
+
+GLOBALOSGLUPROC WaitForNextTick(void)
+{
+ NSDate *TheUntil;
+ int i;
+ NSEvent *event;
+ NSAutoreleasePool *pool;
+
+ pool = [[NSAutoreleasePool alloc] init];
+
+ NSDate *TheDistantFuture = [NSDate distantFuture];
+ NSDate *TheDistantPast = [NSDate distantPast];
+#if 0
+ NSDate *TheNextTick = [NSDate
+ dateWithTimeIntervalSinceReferenceDate: NextTickChangeTime];
+#endif
+
+ TheUntil = TheDistantPast;
+
+label_retry:
+
+ i = 32;
+ while ((--i >= 0) && (nil != (event =
+ [NSApp nextEventMatchingMask: NSAnyEventMask
+ untilDate: TheUntil
+ inMode: NSDefaultRunLoopMode
+ dequeue: YES])))
+ {
+ ProcessOneSystemEvent(event);
+ TheUntil = TheDistantPast;
+ }
+
+ CheckForSavedTasks();
+
+ if (ForceMacOff) {
+ goto label_exit;
+ }
+
+ if (CurSpeedStopped) {
+ DoneWithDrawingForTick();
+ TheUntil = TheDistantFuture;
+ goto label_retry;
+ }
+
+ if (ExtraTimeNotOver()) {
+#if 1
+#if 0 && EnableAutoSlow
+ if ((QuietSubTicks >= 16384)
+ && (QuietTime >= 34)
+ && ! WantNotAutoSlow)
+ {
+ TheUntil = [NSDate
+ dateWithTimeIntervalSinceReferenceDate:
+ (NextTickChangeTime + 0.50)];
+ } else
+#endif
+ {
+ NSTimeInterval inTimeout =
+ NextTickChangeTime - LatestTime;
+ if (inTimeout > 0.0) {
+ struct timespec rqt;
+ struct timespec rmt;
+
+ rqt.tv_sec = 0;
+ rqt.tv_nsec = inTimeout * 1000000000.0;
+ (void) nanosleep(&rqt, &rmt);
+ }
+ TheUntil = TheDistantPast;
+ }
+#else
+ /*
+ This has higher overhead.
+ */
+ TheUntil = TheNextTick;
+#endif
+ goto label_retry;
+ }
+
+#if 0
+ if (! gTrueBackgroundFlag) {
+ CheckMouseState();
+ }
+#endif
+
+ if (CheckDateTime()) {
+#if MySoundEnabled
+ MySound_SecondNotify();
+#endif
+#if EnableDemoMsg
+ DemoModeSecondNotify();
+#endif
+ }
+
+ OnTrueTime = TrueEmulatedTime;
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("WaitForNextTick, OnTrueTime", OnTrueTime);
+#endif
+
+label_exit:
+ [pool release];
+}
+
+typedef Boolean (*SecTranslocateIsTranslocatedURL_t)(
+ CFURLRef path, bool *isTranslocated, CFErrorRef * error);
+typedef CFURLRef (*SecTranslocateCreateOriginalPathForURL_t)(
+ CFURLRef translocatedPath, CFErrorRef * error);
+
+LOCALFUNC blnr setupWorkingDirectory(void)
+{
+ NSString *myAppDir;
+ NSString *contentsPath;
+ NSString *dataPath;
+ NSBundle *myBundle = [NSBundle mainBundle];
+ NSString *myAppPath = [myBundle bundlePath];
+
+#if WantUnTranslocate
+ {
+ bool isTranslocated;
+ void *sec_handle = NULL;
+ SecTranslocateIsTranslocatedURL_t
+ mySecTranslocateIsTranslocatedURL = NULL;
+ CFURLRef url = NULL;
+ SecTranslocateCreateOriginalPathForURL_t
+ mySecTranslocateCreateOriginalPathForURL = NULL;
+ CFURLRef untranslocatedURL = NULL;
+ NSString *realAppPath = NULL;
+
+ if (NULL == (sec_handle = dlopen(
+ "/System/Library/Frameworks/Security.framework/Security",
+ RTLD_LAZY)))
+ {
+ /* fail */
+ } else
+ if (NULL == (mySecTranslocateIsTranslocatedURL =
+ dlsym(sec_handle, "SecTranslocateIsTranslocatedURL")))
+ {
+ /* fail */
+ } else
+ if (NULL == (url =
+ CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
+ (CFStringRef)myAppPath, kCFURLPOSIXPathStyle, NO)))
+ {
+ /* fail */
+ } else
+ if (! mySecTranslocateIsTranslocatedURL(url, &isTranslocated,
+ NULL))
+ {
+ /* fail */
+ } else
+ if (! isTranslocated) {
+ /* done */
+ } else
+ if (NULL == (mySecTranslocateCreateOriginalPathForURL =
+ dlsym(sec_handle,
+ "SecTranslocateCreateOriginalPathForURL")))
+ {
+ /* fail */
+ } else
+ if (NULL == (untranslocatedURL =
+ mySecTranslocateCreateOriginalPathForURL(url, NULL)))
+ {
+ /* fail */
+ } else
+ if (NULL == (realAppPath =
+ (NSString *)CFURLCopyFileSystemPath(
+ untranslocatedURL, kCFURLPOSIXPathStyle)))
+ {
+ /* fail */
+ } else
+ {
+ myAppPath = realAppPath;
+ }
+
+ if (NULL != realAppPath) {
+ [realAppPath autorelease];
+ }
+ if (NULL != untranslocatedURL) {
+ CFRelease(untranslocatedURL);
+ }
+ if (NULL != url) {
+ CFRelease(url);
+ }
+ if (NULL != sec_handle) {
+ if (0 != dlclose(sec_handle)) {
+ /* dbglog_writeln("dlclose failed"); */
+ }
+ }
+ }
+#endif /* WantUnTranslocate */
+
+ myAppDir = [myAppPath stringByDeletingLastPathComponent];
+ myAppName = [[[myAppPath lastPathComponent]
+ stringByDeletingPathExtension] retain];
+
+ MyDataPath = myAppDir;
+ if (FindNamedChildDirPath(myAppPath, "Contents", &contentsPath))
+ if (FindNamedChildDirPath(contentsPath, "mnvm_dat", &dataPath))
+ {
+ MyDataPath = dataPath;
+ }
+ [MyDataPath retain];
+
+ return trueblnr;
+}
+
+@interface MyClassApplicationDelegate : NSObject <NSApplicationDelegate>
+@end
+
+@implementation MyClassApplicationDelegate
+
+- (BOOL)application:(NSApplication *)theApplication
+ openFile:(NSString *)filename
+{
+ (void) Sony_Insert1a(filename);
+
+ return TRUE;
+}
+
+- (void) applicationDidFinishLaunching: (NSNotification *) note
+{
+ [NSApp stop: nil]; /* stop immediately */
+
+ {
+ /*
+ doesn't actually stop until an event, so make one.
+ (As suggested by Michiel de Hoon in
+ http://www.cocoabuilder.com/ post.)
+ */
+ NSEvent* event = [NSEvent
+ otherEventWithType: NSApplicationDefined
+ location: NSMakePoint(0, 0)
+ modifierFlags: 0
+ timestamp: 0.0
+ windowNumber: 0
+ context: nil
+ subtype: 0
+ data1: 0
+ data2: 0];
+ [NSApp postEvent: event atStart: true];
+ }
+}
+
+- (void)applicationDidChangeScreenParameters:
+ (NSNotification *)aNotification
+{
+ WantScreensChangedCheck = trueblnr;
+}
+
+- (IBAction)performSpecialMoreCommands:(id)sender
+{
+ DoMoreCommandsMsg();
+}
+
+- (IBAction)performFileOpen:(id)sender
+{
+ RequestInsertDisk = trueblnr;
+}
+
+- (IBAction)performApplicationAbout:(id)sender
+{
+ DoAboutMsg();
+}
+
+@end
+
+LOCALVAR MyClassApplicationDelegate *MyApplicationDelegate = nil;
+
+LOCALFUNC blnr InitCocoaStuff(void)
+{
+ NSApplication *MyNSApp = [NSApplication sharedApplication];
+ /*
+ in Xcode 6.2, MyNSApp isn't the same as NSApp,
+ breaks NSApp setDelegate
+ */
+
+ MyMenuSetup();
+
+ MyApplicationDelegate = [[MyClassApplicationDelegate alloc] init];
+ [MyNSApp setDelegate: MyApplicationDelegate];
+
+#if 0
+ [MyNSApp finishLaunching];
+#endif
+ /*
+ If use finishLaunching, after
+ Hide Mini vMac command, activating from
+ Dock doesn't bring our window forward.
+ Using "run" instead fixes this.
+ As suggested by Hugues De Keyzer in
+ http://forums.libsdl.org/ post.
+ SDL 2.0 doesn't use this
+ technique. Was another solution found?
+ */
+
+ [MyNSApp run];
+ /*
+ our applicationDidFinishLaunching forces
+ immediate halt.
+ */
+
+ return trueblnr;
+}
+
+LOCALPROC UnInitCocoaStuff(void)
+{
+ if (nil != MyApplicationDelegate) {
+ [MyApplicationDelegate release];
+ }
+ if (nil != myAppName) {
+ [myAppName release];
+ }
+ if (nil != MyDataPath) {
+ [MyDataPath release];
+ }
+}
+
+/* --- platform independent code can be thought of as going here --- */
+
+#include "PROGMAIN.h"
+
+LOCALPROC ZapOSGLUVars(void)
+{
+ InitDrives();
+ ZapWinStateVars();
+#if MySoundEnabled
+ ZapAudioVars();
+#endif
+}
+
+LOCALPROC ReserveAllocAll(void)
+{
+#if dbglog_HAVE
+ dbglog_ReserveAlloc();
+#endif
+ ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr);
+
+ ReserveAllocOneBlock(&screencomparebuff,
+ vMacScreenNumBytes, 5, trueblnr);
+#if UseControlKeys
+ ReserveAllocOneBlock(&CntrlDisplayBuff,
+ vMacScreenNumBytes, 5, falseblnr);
+#endif
+
+ ReserveAllocOneBlock(&ScalingBuff, vMacScreenNumPixels
+#if 0 != vMacScreenDepth
+ * 4
+#endif
+ , 5, falseblnr);
+ ReserveAllocOneBlock(&CLUT_final, CLUT_finalsz, 5, falseblnr);
+
+#if MySoundEnabled
+ ReserveAllocOneBlock((ui3p *)&TheSoundBuffer,
+ dbhBufferSize, 5, falseblnr);
+#endif
+
+ EmulationReserveAlloc();
+}
+
+LOCALFUNC blnr AllocMyMemory(void)
+{
+#if 0 /* for testing start up error reporting */
+ MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr);
+ return falseblnr;
+#else
+ uimr n;
+ blnr IsOk = falseblnr;
+
+ ReserveAllocOffset = 0;
+ ReserveAllocBigBlock = nullpr;
+ ReserveAllocAll();
+ n = ReserveAllocOffset;
+ ReserveAllocBigBlock = (ui3p)calloc(1, n);
+ if (NULL == ReserveAllocBigBlock) {
+ MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr);
+ } else {
+ ReserveAllocOffset = 0;
+ ReserveAllocAll();
+ if (n != ReserveAllocOffset) {
+ /* oops, program error */
+ } else {
+ IsOk = trueblnr;
+ }
+ }
+
+ return IsOk;
+#endif
+}
+
+LOCALPROC UnallocMyMemory(void)
+{
+ if (nullpr != ReserveAllocBigBlock) {
+ free((char *) ReserveAllocBigBlock);
+ }
+}
+
+LOCALFUNC blnr InitOSGLU(void)
+{
+ blnr IsOk = falseblnr;
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ if (AllocMyMemory())
+ if (setupWorkingDirectory())
+#if dbglog_HAVE
+ if (dbglog_open())
+#endif
+#if MySoundEnabled
+ if (MySound_Init())
+ /* takes a while to stabilize, do as soon as possible */
+#endif
+ if (LoadMacRom())
+ if (LoadInitialImages())
+ if (InitCocoaStuff())
+ /*
+ Can get openFile call backs here
+ for initial files.
+ So must load ROM, disk1.dsk, etc first.
+ */
+#if UseActvCode
+ if (ActvCodeInit())
+#endif
+#if EmLocalTalk
+ if (InitLocalTalk())
+#endif
+ if (InitLocationDat())
+ if (Screen_Init())
+ if (CreateMainWindow())
+ if (WaitForRom())
+ {
+ IsOk = trueblnr;
+ }
+
+ [pool release];
+
+ return IsOk;
+}
+
+#if dbglog_HAVE && 0
+IMPORTPROC DumpRTC(void);
+#endif
+
+LOCALPROC UnInitOSGLU(void)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+#if dbglog_HAVE && 0
+ DumpRTC();
+#endif
+
+ if (MacMsgDisplayed) {
+ MacMsgDisplayOff();
+ }
+
+ RestoreKeyRepeat();
+#if MayFullScreen
+ UngrabMachine();
+#endif
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+#if MySoundEnabled
+ MySound_UnInit();
+#endif
+#if IncludePbufs
+ UnInitPbufs();
+#endif
+ UnInitDrives();
+
+ ForceShowCursor();
+
+#if dbglog_HAVE
+ dbglog_close();
+#endif
+
+ CheckSavedMacMsg();
+
+ CloseMyOpenGLContext();
+ CloseMainWindow();
+
+#if MayFullScreen
+ My_ShowMenuBar();
+#endif
+
+ UnInitCocoaStuff();
+
+ UnallocMyMemory();
+
+ [pool release];
+}
+
+int main(int argc, char **argv)
+{
+ ZapOSGLUVars();
+
+ if (InitOSGLU()) {
+ ProgramMain();
+ }
+ UnInitOSGLU();
+
+ return 0;
+}
--- /dev/null
+++ b/src/OSGLUGTK.c
@@ -1,0 +1,1764 @@
+/*
+ OSGLUGTK.c
+
+ Copyright (C) 2009 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Operating System GLUe for GTK
+
+ All operating system dependent code for the
+ GIMP Toolkit should go here.
+*/
+
+#include "CNFGRAPI.h"
+#include "SYSDEPNS.h"
+#include "ENDIANAC.h"
+
+#include "MYOSGLUE.h"
+
+#include "STRCONST.h"
+
+#include "COMOSGLU.h"
+
+/* --- some simple utilities --- */
+
+GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount)
+{
+ (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount);
+}
+
+/* --- control mode and internationalization --- */
+
+#define NeedCell2PlainAsciiMap 1
+
+#include "INTLCHAR.h"
+
+#include "CONTROLM.h"
+
+/* --- sending debugging info to file --- */
+
+#if dbglog_HAVE
+
+#define dbglog_ToStdErr 0
+
+#if ! dbglog_ToStdErr
+LOCALVAR FILE *dbglog_File = NULL;
+#endif
+
+LOCALFUNC blnr dbglog_open0(void)
+{
+#if dbglog_ToStdErr
+ return trueblnr;
+#else
+ dbglog_File = fopen("dbglog.txt", "w");
+ return (NULL != dbglog_File);
+#endif
+}
+
+LOCALPROC dbglog_write0(char *s, uimr L)
+{
+#if dbglog_ToStdErr
+ (void) fwrite(s, 1, L, stderr);
+#else
+ if (dbglog_File != NULL) {
+ (void) fwrite(s, 1, L, dbglog_File);
+ }
+#endif
+}
+
+LOCALPROC dbglog_close0(void)
+{
+#if ! dbglog_ToStdErr
+ if (dbglog_File != NULL) {
+ fclose(dbglog_File);
+ dbglog_File = NULL;
+ }
+#endif
+}
+
+#endif
+
+/* --- debug settings and utilities --- */
+
+#define MyDbgEvents (dbglog_HAVE && 1)
+
+#if ! dbglog_HAVE
+#define WriteExtraErr(s)
+#else
+LOCALPROC WriteExtraErr(char *s)
+{
+ dbglog_writeCStr("*** error: ");
+ dbglog_writeCStr(s);
+ dbglog_writeReturn();
+}
+#endif
+
+/* --- text translation --- */
+
+LOCALPROC NativeStrFromCStr(char *r, char *s, blnr AddEllipsis)
+{
+ ui3b ps[ClStrMaxLength];
+ int i;
+ int L;
+
+ ClStrFromSubstCStr(&L, ps, s);
+
+ for (i = 0; i < L; ++i) {
+ r[i] = Cell2PlainAsciiMap[ps[i]];
+ }
+
+ if (AddEllipsis) {
+ r[L] = '.';
+ ++L;
+ r[L] = '.';
+ ++L;
+ r[L] = '.';
+ ++L;
+ }
+
+ r[L] = 0;
+}
+
+/* --- drives --- */
+
+#define NotAfileRef NULL
+
+LOCALVAR FILE *Drives[NumDrives]; /* open disk image files */
+
+LOCALPROC InitDrives(void)
+{
+ /*
+ This isn't really needed, Drives[i] and DriveNames[i]
+ need not have valid values when not vSonyIsInserted[i].
+ */
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ Drives[i] = NotAfileRef;
+ }
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer,
+ tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
+ ui5r *Sony_ActCount)
+{
+ ui5r NewSony_Count = Sony_Count;
+
+ fseek(Drives[Drive_No], Sony_Start, SEEK_SET);
+
+ if (IsWrite) {
+ fwrite(Buffer, 1, NewSony_Count, Drives[Drive_No]);
+ } else {
+ fread(Buffer, 1, NewSony_Count, Drives[Drive_No]);
+ }
+
+ if (nullpr != Sony_ActCount) {
+ *Sony_ActCount = NewSony_Count;
+ }
+
+ return mnvm_noErr; /*& figure out what really to return &*/
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count)
+{
+ fseek(Drives[Drive_No], 0, SEEK_END);
+ *Sony_Count = ftell(Drives[Drive_No]);
+ return mnvm_noErr; /*& figure out what really to return &*/
+}
+
+LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit)
+{
+ DiskEjectedNotify(Drive_No);
+
+ fclose(Drives[Drive_No]);
+ Drives[Drive_No] = NotAfileRef; /* not really needed */
+
+
+ return mnvm_noErr;
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No)
+{
+ return vSonyEject0(Drive_No, falseblnr);
+}
+
+LOCALPROC UnInitDrives(void)
+{
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ if (vSonyIsInserted(i)) {
+ (void) vSonyEject(i);
+ }
+ }
+}
+
+LOCALFUNC blnr Sony_Insert0(FILE *refnum, blnr locked,
+ char *drivepath)
+{
+ tDrive Drive_No;
+
+ if (! FirstFreeDisk(&Drive_No)) {
+ fclose(refnum);
+ MacMsg(kStrTooManyImagesTitle,
+ kStrTooManyImagesMessage, falseblnr);
+ return falseblnr;
+ } else {
+ /* printf("Sony_Insert0 %d\n", (int)Drive_No); */
+ Drives[Drive_No] = refnum;
+ DiskInsertNotify(Drive_No, locked);
+
+ return trueblnr;
+ }
+}
+
+LOCALFUNC blnr Sony_Insert1(char *drivepath, blnr silentfail)
+{
+ blnr locked = falseblnr;
+ /* printf("Sony_Insert1 %s\n", drivepath); */
+ FILE *refnum = fopen(drivepath, "rb+");
+ if (NULL == refnum) {
+ locked = trueblnr;
+ refnum = fopen(drivepath, "rb");
+ }
+ if (NULL == refnum) {
+ if (! silentfail) {
+ MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
+ }
+ } else {
+ return Sony_Insert0(refnum, locked, drivepath);
+ }
+ return falseblnr;
+}
+
+LOCALFUNC tMacErr LoadMacRomFrom(char *path)
+{
+ tMacErr err;
+ FILE *ROM_File;
+ int File_Size;
+
+ ROM_File = fopen(path, "rb");
+ if (NULL == ROM_File) {
+ err = mnvm_fnfErr;
+ } else {
+ File_Size = fread(ROM, 1, kROM_Size, ROM_File);
+ if (kROM_Size != File_Size) {
+ if (feof(ROM_File)) {
+ MacMsgOverride(kStrShortROMTitle,
+ kStrShortROMMessage);
+ err = mnvm_eofErr;
+ } else {
+ MacMsgOverride(kStrNoReadROMTitle,
+ kStrNoReadROMMessage);
+ err = mnvm_miscErr;
+ }
+ } else {
+ err = ROM_IsValid();
+ }
+ fclose(ROM_File);
+ }
+
+ return err;
+}
+
+LOCALFUNC blnr Sony_Insert1a(char *drivepath, blnr silentfail)
+{
+ blnr v;
+
+ if (! ROM_loaded) {
+ v = (mnvm_noErr == LoadMacRomFrom(drivepath));
+ } else {
+ v = Sony_Insert1(drivepath, silentfail);
+ }
+
+ return v;
+}
+
+LOCALFUNC blnr Sony_InsertIth(int i)
+{
+ blnr v;
+
+ if ((i > 9) || ! FirstFreeDisk(nullpr)) {
+ v = falseblnr;
+ } else {
+ char s[] = "disk?.dsk";
+
+ s[4] = '0' + i;
+
+ v = Sony_Insert1(s, trueblnr);
+ }
+
+ return v;
+}
+
+LOCALFUNC blnr LoadInitialImages(void)
+{
+ int i;
+
+ for (i = 1; Sony_InsertIth(i); ++i) {
+ /* stop on first error (including file not found) */
+ }
+
+ return trueblnr;
+}
+
+/* --- ROM --- */
+
+LOCALVAR char *rom_path = NULL;
+
+LOCALFUNC blnr LoadMacRom(void)
+{
+ tMacErr err;
+
+ if ((NULL == rom_path)
+ || (mnvm_fnfErr == (err = LoadMacRomFrom(rom_path))))
+ if (mnvm_fnfErr == (err = LoadMacRomFrom(RomFileName)))
+ {
+ }
+
+ return trueblnr;
+}
+
+/* --- video out --- */
+
+static GtkWidget *drawing_area;
+
+LOCALVAR blnr gBackgroundFlag = falseblnr;
+LOCALVAR blnr gTrueBackgroundFlag = falseblnr;
+LOCALVAR blnr CurSpeedStopped = trueblnr;
+
+LOCALPROC HaveChangedScreenBuff(si4b top, si4b left,
+ si4b bottom, si4b right)
+{
+ guchar graybuf[vMacScreenWidth * vMacScreenHeight];
+
+ {
+ int i;
+ int j;
+ int k;
+ ui3b *p1 = GetCurDrawBuff()
+ + (ui5r)vMacScreenWidth / 8 * top;
+ ui3b *p2 = (ui3b *)graybuf + (ui5r)vMacScreenWidth * top;
+ ui5b t0;
+
+ UnusedParam(left);
+ UnusedParam(right);
+ for (i = bottom - top; --i >= 0; ) {
+ for (j = vMacScreenWidth / 8; --j >= 0; ) {
+ t0 = *p1++;
+ for (k = 8; --k >= 0; ) {
+ *p2++ = ((t0 >> k) & 0x01) - 1;
+ }
+ }
+ }
+ }
+
+ gdk_draw_gray_image(drawing_area->window,
+ drawing_area->style->fg_gc[GTK_WIDGET_STATE(drawing_area)],
+ left /* x */,
+ top /* y */,
+ right - left /* width */,
+ bottom - top /* height */,
+ GDK_RGB_DITHER_NONE,
+ graybuf + left + (ui5r)vMacScreenWidth * top,
+ vMacScreenWidth);
+}
+
+LOCALPROC MyDrawChangesAndClear(void)
+{
+ if (ScreenChangedBottom > ScreenChangedTop) {
+ HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft,
+ ScreenChangedBottom, ScreenChangedRight);
+ ScreenClearChanges();
+ }
+}
+
+GLOBALOSGLUPROC DoneWithDrawingForTick(void)
+{
+ MyDrawChangesAndClear();
+}
+
+/* --- mouse --- */
+
+LOCALVAR blnr HaveCursorHidden = falseblnr;
+LOCALVAR blnr WantCursorHidden = falseblnr;
+
+static GdkCursor *blank_cursor;
+static GtkWidget *window = NULL;
+
+LOCALPROC ForceShowCursor(void)
+{
+ if (HaveCursorHidden) {
+ HaveCursorHidden = falseblnr;
+
+ if (window) {
+ gdk_window_set_cursor(window->window, NULL);
+ }
+ }
+}
+
+/* cursor state */
+
+LOCALPROC MousePositionNotify(int NewMousePosh, int NewMousePosv)
+{
+ blnr ShouldHaveCursorHidden = trueblnr;
+
+ {
+ if (NewMousePosh < 0) {
+ NewMousePosh = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosh >= vMacScreenWidth) {
+ NewMousePosh = vMacScreenWidth - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+ if (NewMousePosv < 0) {
+ NewMousePosv = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosv >= vMacScreenHeight) {
+ NewMousePosv = vMacScreenHeight - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+
+
+ /* if (ShouldHaveCursorHidden || CurMouseButton) */
+ /*
+ for a game like arkanoid, would like mouse to still
+ move even when outside window in one direction
+ */
+ MyMousePositionSet(NewMousePosh, NewMousePosv);
+ }
+
+ WantCursorHidden = ShouldHaveCursorHidden;
+}
+
+LOCALPROC CheckMouseState(void)
+{
+#if 0
+ gint x;
+ gint y;
+ gint x0;
+ gint y0;
+
+ gdk_display_get_pointer(gdk_drawable_get_display(window),
+ NULL, &x, &y, NULL);
+ (void) gdk_window_get_origin(window, &x0, &y0);
+ MousePositionNotify(x - x0, y - y0);
+#endif
+ gint x;
+ gint y;
+
+ gtk_widget_get_pointer(drawing_area, &x, &y);
+ /* (void) gdk_window_get_pointer(window, &x, &y, NULL); */
+ MousePositionNotify(x, y);
+}
+
+/* --- keyboard input --- */
+
+#define MaxNumKeycode 256
+#define KeyCodeMask (MaxNumKeycode - 1)
+ /*
+ assume keycodes >= 0 and < MaxNumKeycode, which
+ isn't promised by gtk documentation.
+ */
+
+
+LOCALVAR ui3b KC2MKC[MaxNumKeycode];
+
+LOCALPROC KC2MKCAssignOne(guint keyval, ui3r key)
+{
+ GdkKeymapKey *keys;
+ gint n_keys;
+ int i;
+
+ if (gdk_keymap_get_entries_for_keyval(NULL,
+ keyval, &keys, &n_keys))
+ {
+ for (i = 0; i < n_keys; i++) {
+ KC2MKC[keys[i].keycode & KeyCodeMask] = key;
+ }
+ g_free(keys);
+ }
+#if 0
+ fprintf(stderr, "%d %d %d\n", (int)ks, key, (int)code);
+#endif
+}
+
+LOCALFUNC blnr KC2MKCInit(void)
+{
+ int i;
+
+ for (i = 0; i < 256; ++i) {
+ KC2MKC[i] = MKC_None;
+ }
+
+#ifdef GDK_KP_Insert
+ KC2MKCAssignOne(GDK_KP_Insert, MKC_KP0);
+#endif
+#ifdef GDK_KP_End
+ KC2MKCAssignOne(GDK_KP_End, MKC_KP1);
+#endif
+#ifdef GDK_KP_Down
+ KC2MKCAssignOne(GDK_KP_Down, MKC_KP2);
+#endif
+#ifdef GDK_KP_Next
+ KC2MKCAssignOne(GDK_KP_Next, MKC_KP3);
+#endif
+#ifdef GDK_KP_Left
+ KC2MKCAssignOne(GDK_KP_Left, MKC_KP4);
+#endif
+#ifdef GDK_KP_Begin
+ KC2MKCAssignOne(GDK_KP_Begin, MKC_KP5);
+#endif
+#ifdef GDK_KP_Right
+ KC2MKCAssignOne(GDK_KP_Right, MKC_KP6);
+#endif
+#ifdef GDK_KP_Home
+ KC2MKCAssignOne(GDK_KP_Home, MKC_KP7);
+#endif
+#ifdef GDK_KP_Up
+ KC2MKCAssignOne(GDK_KP_Up, MKC_KP8);
+#endif
+#ifdef GDK_KP_Prior
+ KC2MKCAssignOne(GDK_KP_Prior, MKC_KP9);
+#endif
+#ifdef GDK_KP_Delete
+ KC2MKCAssignOne(GDK_KP_Delete, MKC_Decimal);
+#endif
+
+ KC2MKCAssignOne(GDK_asciitilde, MKC_formac_Grave);
+ KC2MKCAssignOne(GDK_underscore, MKC_Minus);
+ KC2MKCAssignOne(GDK_plus, MKC_Equal);
+ KC2MKCAssignOne(GDK_braceleft, MKC_LeftBracket);
+ KC2MKCAssignOne(GDK_braceright, MKC_RightBracket);
+ KC2MKCAssignOne(GDK_bar, MKC_formac_BackSlash);
+ KC2MKCAssignOne(GDK_colon, MKC_SemiColon);
+ KC2MKCAssignOne(GDK_quotedbl, MKC_SingleQuote);
+ KC2MKCAssignOne(GDK_less, MKC_Comma);
+ KC2MKCAssignOne(GDK_greater, MKC_Period);
+ KC2MKCAssignOne(GDK_question, MKC_formac_Slash);
+
+ KC2MKCAssignOne(GDK_a, MKC_A);
+ KC2MKCAssignOne(GDK_b, MKC_B);
+ KC2MKCAssignOne(GDK_c, MKC_C);
+ KC2MKCAssignOne(GDK_d, MKC_D);
+ KC2MKCAssignOne(GDK_e, MKC_E);
+ KC2MKCAssignOne(GDK_f, MKC_F);
+ KC2MKCAssignOne(GDK_g, MKC_G);
+ KC2MKCAssignOne(GDK_h, MKC_H);
+ KC2MKCAssignOne(GDK_i, MKC_I);
+ KC2MKCAssignOne(GDK_j, MKC_J);
+ KC2MKCAssignOne(GDK_k, MKC_K);
+ KC2MKCAssignOne(GDK_l, MKC_L);
+ KC2MKCAssignOne(GDK_m, MKC_M);
+ KC2MKCAssignOne(GDK_n, MKC_N);
+ KC2MKCAssignOne(GDK_o, MKC_O);
+ KC2MKCAssignOne(GDK_p, MKC_P);
+ KC2MKCAssignOne(GDK_q, MKC_Q);
+ KC2MKCAssignOne(GDK_r, MKC_R);
+ KC2MKCAssignOne(GDK_s, MKC_S);
+ KC2MKCAssignOne(GDK_t, MKC_T);
+ KC2MKCAssignOne(GDK_u, MKC_U);
+ KC2MKCAssignOne(GDK_v, MKC_V);
+ KC2MKCAssignOne(GDK_w, MKC_W);
+ KC2MKCAssignOne(GDK_x, MKC_X);
+ KC2MKCAssignOne(GDK_y, MKC_Y);
+ KC2MKCAssignOne(GDK_z, MKC_Z);
+
+ /*
+ main mappings
+ */
+
+ KC2MKCAssignOne(GDK_F1, MKC_formac_F1);
+ KC2MKCAssignOne(GDK_F2, MKC_formac_F2);
+ KC2MKCAssignOne(GDK_F3, MKC_formac_F3);
+ KC2MKCAssignOne(GDK_F4, MKC_formac_F4);
+ KC2MKCAssignOne(GDK_F5, MKC_formac_F5);
+ KC2MKCAssignOne(GDK_F6, MKC_F6);
+ KC2MKCAssignOne(GDK_F7, MKC_F7);
+ KC2MKCAssignOne(GDK_F8, MKC_F8);
+ KC2MKCAssignOne(GDK_F9, MKC_F9);
+ KC2MKCAssignOne(GDK_F10, MKC_F10);
+ KC2MKCAssignOne(GDK_F11, MKC_F11);
+ KC2MKCAssignOne(GDK_F12, MKC_F12);
+
+#ifdef GDK_Delete
+ KC2MKCAssignOne(GDK_Delete, MKC_formac_ForwardDel);
+#endif
+#ifdef GDK_Insert
+ KC2MKCAssignOne(GDK_Insert, MKC_formac_Help);
+#endif
+#ifdef GDK_Help
+ KC2MKCAssignOne(GDK_Help, MKC_formac_Help);
+#endif
+#ifdef GDK_Home
+ KC2MKCAssignOne(GDK_Home, MKC_formac_Home);
+#endif
+#ifdef GDK_End
+ KC2MKCAssignOne(GDK_End, MKC_formac_End);
+#endif
+
+#ifdef GDK_Page_Up
+ KC2MKCAssignOne(GDK_Page_Up, MKC_formac_PageUp);
+#else
+#ifdef GDK_Prior
+ KC2MKCAssignOne(GDK_Prior, MKC_formac_PageUp);
+#endif
+#endif
+
+#ifdef GDK_Page_Down
+ KC2MKCAssignOne(GDK_Page_Down, MKC_formac_PageDown);
+#else
+#ifdef GDK_Next
+ KC2MKCAssignOne(GDK_Next, MKC_formac_PageDown);
+#endif
+#endif
+
+#ifdef GDK_Print
+ KC2MKCAssignOne(GDK_Print, MKC_Print);
+#endif
+#ifdef GDK_Scroll_Lock
+ KC2MKCAssignOne(GDK_Scroll_Lock, MKC_ScrollLock);
+#endif
+#ifdef GDK_Pause
+ KC2MKCAssignOne(GDK_Pause, MKC_Pause);
+#endif
+
+ KC2MKCAssignOne(GDK_KP_Add, MKC_KPAdd);
+ KC2MKCAssignOne(GDK_KP_Subtract, MKC_KPSubtract);
+ KC2MKCAssignOne(GDK_KP_Multiply, MKC_KPMultiply);
+ KC2MKCAssignOne(GDK_KP_Divide, MKC_KPDevide);
+ KC2MKCAssignOne(GDK_KP_Enter, MKC_formac_Enter);
+ KC2MKCAssignOne(GDK_KP_Equal, MKC_KPEqual);
+
+ KC2MKCAssignOne(GDK_KP_0, MKC_KP0);
+ KC2MKCAssignOne(GDK_KP_1, MKC_KP1);
+ KC2MKCAssignOne(GDK_KP_2, MKC_KP2);
+ KC2MKCAssignOne(GDK_KP_3, MKC_KP3);
+ KC2MKCAssignOne(GDK_KP_4, MKC_KP4);
+ KC2MKCAssignOne(GDK_KP_5, MKC_KP5);
+ KC2MKCAssignOne(GDK_KP_6, MKC_KP6);
+ KC2MKCAssignOne(GDK_KP_7, MKC_KP7);
+ KC2MKCAssignOne(GDK_KP_8, MKC_KP8);
+ KC2MKCAssignOne(GDK_KP_9, MKC_KP9);
+ KC2MKCAssignOne(GDK_KP_Decimal, MKC_Decimal);
+
+ KC2MKCAssignOne(GDK_Left, MKC_Left);
+ KC2MKCAssignOne(GDK_Right, MKC_Right);
+ KC2MKCAssignOne(GDK_Up, MKC_Up);
+ KC2MKCAssignOne(GDK_Down, MKC_Down);
+
+ KC2MKCAssignOne(GDK_grave, MKC_formac_Grave);
+ KC2MKCAssignOne(GDK_minus, MKC_Minus);
+ KC2MKCAssignOne(GDK_equal, MKC_Equal);
+ KC2MKCAssignOne(GDK_bracketleft, MKC_LeftBracket);
+ KC2MKCAssignOne(GDK_bracketright, MKC_RightBracket);
+ KC2MKCAssignOne(GDK_backslash, MKC_formac_BackSlash);
+ KC2MKCAssignOne(GDK_semicolon, MKC_SemiColon);
+ KC2MKCAssignOne(GDK_apostrophe, MKC_SingleQuote);
+ KC2MKCAssignOne(GDK_comma, MKC_Comma);
+ KC2MKCAssignOne(GDK_period, MKC_Period);
+ KC2MKCAssignOne(GDK_slash, MKC_formac_Slash);
+
+ KC2MKCAssignOne(GDK_Escape, MKC_formac_Escape);
+
+ KC2MKCAssignOne(GDK_Tab, MKC_Tab);
+ KC2MKCAssignOne(GDK_Return, MKC_Return);
+ KC2MKCAssignOne(GDK_space, MKC_Space);
+ KC2MKCAssignOne(GDK_BackSpace, MKC_BackSpace);
+
+ KC2MKCAssignOne(GDK_Caps_Lock, MKC_formac_CapsLock);
+ KC2MKCAssignOne(GDK_Num_Lock, MKC_Clear);
+
+ KC2MKCAssignOne(GDK_Meta_L, MKC_formac_Command);
+
+ KC2MKCAssignOne(GDK_Meta_R, MKC_formac_RCommand);
+
+ KC2MKCAssignOne(GDK_Mode_switch, MKC_formac_Option);
+ KC2MKCAssignOne(GDK_Menu, MKC_formac_Option);
+ KC2MKCAssignOne(GDK_Super_L, MKC_formac_Option);
+ KC2MKCAssignOne(GDK_Super_R, MKC_formac_ROption);
+ KC2MKCAssignOne(GDK_Hyper_L, MKC_formac_Option);
+ KC2MKCAssignOne(GDK_Hyper_R, MKC_formac_ROption);
+
+ KC2MKCAssignOne(GDK_F13, MKC_formac_Option);
+ /*
+ seen being used in Mandrake Linux 9.2
+ for windows key
+ */
+
+ KC2MKCAssignOne(GDK_Shift_L, MKC_formac_Shift);
+ KC2MKCAssignOne(GDK_Shift_R, MKC_formac_RShift);
+
+ KC2MKCAssignOne(GDK_Alt_L, MKC_formac_Command);
+
+ KC2MKCAssignOne(GDK_Alt_R, MKC_formac_RCommand);
+
+ KC2MKCAssignOne(GDK_Control_L, MKC_formac_Control);
+
+ KC2MKCAssignOne(GDK_Control_R, MKC_formac_RControl);
+
+ KC2MKCAssignOne(GDK_1, MKC_1);
+ KC2MKCAssignOne(GDK_2, MKC_2);
+ KC2MKCAssignOne(GDK_3, MKC_3);
+ KC2MKCAssignOne(GDK_4, MKC_4);
+ KC2MKCAssignOne(GDK_5, MKC_5);
+ KC2MKCAssignOne(GDK_6, MKC_6);
+ KC2MKCAssignOne(GDK_7, MKC_7);
+ KC2MKCAssignOne(GDK_8, MKC_8);
+ KC2MKCAssignOne(GDK_9, MKC_9);
+ KC2MKCAssignOne(GDK_0, MKC_0);
+
+ KC2MKCAssignOne(GDK_A, MKC_A);
+ KC2MKCAssignOne(GDK_B, MKC_B);
+ KC2MKCAssignOne(GDK_C, MKC_C);
+ KC2MKCAssignOne(GDK_D, MKC_D);
+ KC2MKCAssignOne(GDK_E, MKC_E);
+ KC2MKCAssignOne(GDK_F, MKC_F);
+ KC2MKCAssignOne(GDK_G, MKC_G);
+ KC2MKCAssignOne(GDK_H, MKC_H);
+ KC2MKCAssignOne(GDK_I, MKC_I);
+ KC2MKCAssignOne(GDK_J, MKC_J);
+ KC2MKCAssignOne(GDK_K, MKC_K);
+ KC2MKCAssignOne(GDK_L, MKC_L);
+ KC2MKCAssignOne(GDK_M, MKC_M);
+ KC2MKCAssignOne(GDK_N, MKC_N);
+ KC2MKCAssignOne(GDK_O, MKC_O);
+ KC2MKCAssignOne(GDK_P, MKC_P);
+ KC2MKCAssignOne(GDK_Q, MKC_Q);
+ KC2MKCAssignOne(GDK_R, MKC_R);
+ KC2MKCAssignOne(GDK_S, MKC_S);
+ KC2MKCAssignOne(GDK_T, MKC_T);
+ KC2MKCAssignOne(GDK_U, MKC_U);
+ KC2MKCAssignOne(GDK_V, MKC_V);
+ KC2MKCAssignOne(GDK_W, MKC_W);
+ KC2MKCAssignOne(GDK_X, MKC_X);
+ KC2MKCAssignOne(GDK_Y, MKC_Y);
+ KC2MKCAssignOne(GDK_Z, MKC_Z);
+
+ InitKeyCodes();
+
+ return trueblnr;
+}
+
+LOCALPROC CheckTheCapsLock(void)
+{
+ GdkModifierType mask;
+
+ (void) gdk_window_get_pointer(window->window, NULL, NULL, &mask);
+
+ Keyboard_UpdateKeyMap2(MKC_formac_CapsLock,
+ (mask & GDK_LOCK_MASK) != 0);
+}
+
+LOCALPROC DoKeyCode(guint keycode, blnr down)
+{
+ if (GDK_Caps_Lock == keycode) {
+ CheckTheCapsLock();
+ } else {
+ ui3r key = KC2MKC[keycode & KeyCodeMask];
+
+ if (MKC_None != key) {
+ Keyboard_UpdateKeyMap2(key, down);
+ }
+ }
+}
+
+/* --- time, date, location --- */
+
+LOCALVAR ui5b TrueEmulatedTime = 0;
+
+#include "DATE2SEC.h"
+
+#define TicksPerSecond 1000000
+
+LOCALVAR blnr HaveTimeDelta = falseblnr;
+LOCALVAR ui5b TimeDelta;
+
+LOCALVAR ui5b NewMacDateInSeconds;
+
+LOCALVAR ui5b LastTimeSec;
+LOCALVAR ui5b LastTimeUsec;
+
+LOCALPROC GetCurrentTicks(void)
+{
+ GTimeVal t;
+
+ g_get_current_time(&t);
+ if (! HaveTimeDelta) {
+ time_t Current_Time;
+ struct tm *s;
+
+#if 0
+ GDate *date;
+ date = g_date_new();
+ g_date_set_time_val(date, &t);
+ g_date_free(date);
+#endif
+ (void) time(&Current_Time);
+ s = localtime(&Current_Time);
+ TimeDelta = Date2MacSeconds(s->tm_sec, s->tm_min, s->tm_hour,
+ s->tm_mday, 1 + s->tm_mon, 1900 + s->tm_year) - t.tv_sec;
+#if 0 && AutoTimeZone /* how portable is this ? */
+ CurMacDelta = ((ui5b)(s->tm_gmtoff) & 0x00FFFFFF)
+ | ((s->tm_isdst ? 0x80 : 0) << 24);
+#endif
+ HaveTimeDelta = trueblnr;
+ }
+
+ NewMacDateInSeconds = t.tv_sec + TimeDelta;
+ LastTimeSec = (ui5b)t.tv_sec;
+ LastTimeUsec = (ui5b)t.tv_usec;
+}
+
+#define MyInvTimeStep 16626 /* TicksPerSecond / 60.14742 */
+
+LOCALVAR ui5b NextTimeSec;
+LOCALVAR ui5b NextTimeUsec;
+
+LOCALPROC IncrNextTime(void)
+{
+ NextTimeUsec += MyInvTimeStep;
+ if (NextTimeUsec >= TicksPerSecond) {
+ NextTimeUsec -= TicksPerSecond;
+ NextTimeSec += 1;
+ }
+}
+
+LOCALPROC InitNextTime(void)
+{
+ NextTimeSec = LastTimeSec;
+ NextTimeUsec = LastTimeUsec;
+ IncrNextTime();
+}
+
+LOCALPROC StartUpTimeAdjust(void)
+{
+ GetCurrentTicks();
+ InitNextTime();
+}
+
+LOCALFUNC si5b GetTimeDiff(void)
+{
+ return ((si5b)(LastTimeSec - NextTimeSec)) * TicksPerSecond
+ + ((si5b)(LastTimeUsec - NextTimeUsec));
+}
+
+LOCALPROC UpdateTrueEmulatedTime(void)
+{
+ si5b TimeDiff;
+
+ GetCurrentTicks();
+
+ TimeDiff = GetTimeDiff();
+ if (TimeDiff >= 0) {
+ if (TimeDiff > 4 * MyInvTimeStep) {
+ /* emulation interrupted, forget it */
+ ++TrueEmulatedTime;
+ InitNextTime();
+ } else {
+ do {
+ ++TrueEmulatedTime;
+ IncrNextTime();
+ TimeDiff -= TicksPerSecond;
+ } while (TimeDiff >= 0);
+ }
+ } else if (TimeDiff < - 2 * MyInvTimeStep) {
+ /* clock goofed if ever get here, reset */
+ InitNextTime();
+ }
+}
+
+LOCALFUNC blnr CheckDateTime(void)
+{
+ if (CurMacDateInSeconds != NewMacDateInSeconds) {
+ CurMacDateInSeconds = NewMacDateInSeconds;
+ return trueblnr;
+ } else {
+ return falseblnr;
+ }
+}
+
+LOCALFUNC blnr InitLocationDat(void)
+{
+ GetCurrentTicks();
+ CurMacDateInSeconds = NewMacDateInSeconds;
+
+ return trueblnr;
+}
+
+/* --- basic dialogs --- */
+
+LOCALPROC CheckSavedMacMsg(void)
+{
+ if (nullpr != SavedBriefMsg) {
+ char briefMsg0[ClStrMaxLength + 1];
+ char longMsg0[ClStrMaxLength + 1];
+
+ NativeStrFromCStr(briefMsg0, SavedBriefMsg, falseblnr);
+ NativeStrFromCStr(longMsg0, SavedLongMsg, falseblnr);
+
+ fprintf(stderr, "%s\n", briefMsg0);
+ fprintf(stderr, "%s\n", longMsg0);
+
+ SavedBriefMsg = nullpr;
+ }
+}
+
+LOCALVAR blnr CaughtMouse = falseblnr;
+
+/* --- main window creation and disposal --- */
+
+LOCALVAR int my_argc;
+LOCALVAR char **my_argv;
+
+/* Create a new backing pixmap of the appropriate size */
+static gboolean configure_event(GtkWidget *widget,
+ GdkEventConfigure *event)
+{
+ return TRUE;
+}
+
+/* Redraw the screen from the backing pixmap */
+static gboolean expose_event(GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data)
+{
+ int x0 = event->area.x;
+ int y0 = event->area.y;
+ int x1 = x0 + event->area.width;
+ int y1 = y0 + event->area.height;
+
+#if 0 && MyDbgEvents
+ fprintf(stderr, "- event - Expose\n");
+#endif
+
+ if (x0 < 0) {
+ x0 = 0;
+ }
+ if (x1 > vMacScreenWidth) {
+ x1 = vMacScreenWidth;
+ }
+ if (y0 < 0) {
+ y0 = 0;
+ }
+ if (y1 > vMacScreenHeight) {
+ y1 = vMacScreenHeight;
+ }
+ if ((x0 < x1) && (y0 < y1)) {
+ HaveChangedScreenBuff(y0, x0, y1, x1);
+ }
+
+ return FALSE;
+}
+
+static gboolean button_press_event(GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ MousePositionNotify(event->x, event->y);
+ MyMouseButtonSet(trueblnr);
+
+ return TRUE;
+}
+
+static gboolean button_release_event(GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ MousePositionNotify(event->x, event->y);
+ MyMouseButtonSet(falseblnr);
+
+ return TRUE;
+}
+
+static gboolean motion_notify_event(GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data)
+{
+ int x;
+ int y;
+ GdkModifierType state;
+
+ if (event->is_hint) {
+ gdk_window_get_pointer(event->window, &x, &y, &state);
+ } else {
+ x = event->x;
+ y = event->y;
+ state = event->state;
+ }
+
+ MousePositionNotify(x, y);
+ MyMouseButtonSet((state & GDK_BUTTON1_MASK) != 0);
+
+ return TRUE;
+}
+
+static gboolean enter_notify_event(GtkWidget *widget,
+ GdkEventCrossing *event,
+ gpointer user_data)
+{
+ CaughtMouse = trueblnr;
+
+ MousePositionNotify(event->x, event->y);
+ MyMouseButtonSet((event->state & GDK_BUTTON1_MASK) != 0);
+
+ return TRUE;
+}
+
+static gboolean leave_notify_event(GtkWidget *widget,
+ GdkEventCrossing *event,
+ gpointer user_data)
+{
+ MousePositionNotify(event->x, event->y);
+ MyMouseButtonSet((event->state & GDK_BUTTON1_MASK) != 0);
+
+ CaughtMouse = falseblnr;
+
+ return TRUE;
+}
+
+static gboolean delete_event(GtkWidget *widget,
+ GdkEventMotion *event)
+{
+ RequestMacOff = trueblnr;
+
+ return TRUE;
+}
+
+LOCALPROC ReconnectKeyCodes3(void)
+{
+ CheckTheCapsLock();
+
+#if 0
+ if (WantCmdOptOnReconnect) {
+ WantCmdOptOnReconnect = falseblnr;
+
+ GetTheDownKeys();
+ }
+#endif
+}
+
+LOCALPROC DisconnectKeyCodes3(void)
+{
+ DisconnectKeyCodes2();
+ MyMouseButtonSet(falseblnr);
+}
+
+LOCALVAR blnr ADialogIsUp = falseblnr;
+
+LOCALPROC MyBeginDialog(void)
+{
+ DisconnectKeyCodes3();
+ ADialogIsUp = trueblnr;
+ ForceShowCursor();
+}
+
+LOCALPROC MyEndDialog(void)
+{
+ ADialogIsUp = falseblnr;
+ ReconnectKeyCodes3();
+}
+
+/* --- SavedTasks --- */
+
+LOCALPROC LeaveBackground(void)
+{
+ ReconnectKeyCodes3();
+#if 0
+ DisableKeyRepeat();
+#endif
+}
+
+LOCALPROC EnterBackground(void)
+{
+#if 0
+ RestoreKeyRepeat();
+#endif
+ DisconnectKeyCodes3();
+
+ ForceShowCursor();
+}
+
+LOCALPROC LeaveSpeedStopped(void)
+{
+ StartUpTimeAdjust();
+}
+
+LOCALPROC EnterSpeedStopped(void)
+{
+}
+
+static void InsertADisk0(void)
+{
+ char ts[ClStrMaxLength + 1];
+ GtkWidget *dialog;
+
+ NativeStrFromCStr(ts, kStrMenuItemOpen, falseblnr);
+
+ MyBeginDialog();
+ dialog = gtk_file_chooser_dialog_new(ts,
+ GTK_WINDOW(window),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+ MyEndDialog();
+
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+ char *filename;
+
+ filename =
+ gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ (void) Sony_Insert1a(filename, falseblnr);
+ g_free(filename);
+ }
+
+ gtk_widget_destroy(dialog);
+}
+
+LOCALPROC CheckForSavedTasks(void)
+{
+ if (MyEvtQNeedRecover) {
+ MyEvtQNeedRecover = falseblnr;
+
+ /* attempt cleanup, MyEvtQNeedRecover may get set again */
+ MyEvtQTryRecoverFromFull();
+ }
+
+ if (RequestMacOff) {
+ RequestMacOff = falseblnr;
+ if (AnyDiskInserted()) {
+ MacMsgOverride(kStrQuitWarningTitle,
+ kStrQuitWarningMessage);
+ } else {
+ ForceMacOff = trueblnr;
+ }
+ }
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (gTrueBackgroundFlag != gBackgroundFlag) {
+ gBackgroundFlag = gTrueBackgroundFlag;
+ if (gTrueBackgroundFlag) {
+ EnterBackground();
+ } else {
+ LeaveBackground();
+ }
+ }
+
+ if (CurSpeedStopped != (SpeedStopped ||
+ (gBackgroundFlag && ! RunInBackground
+#if EnableAutoSlow && 0
+ && (QuietSubTicks >= 4092)
+#endif
+ )))
+ {
+ CurSpeedStopped = ! CurSpeedStopped;
+ if (CurSpeedStopped) {
+ EnterSpeedStopped();
+ } else {
+ LeaveSpeedStopped();
+ }
+ }
+
+
+ if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) {
+ MacMsgDisplayOn();
+ }
+
+ if (NeedWholeScreenDraw) {
+ NeedWholeScreenDraw = falseblnr;
+ ScreenChangedAll();
+ }
+
+ if (HaveCursorHidden != (WantCursorHidden && CaughtMouse
+ && ! (gTrueBackgroundFlag || ADialogIsUp || CurSpeedStopped)))
+ {
+ HaveCursorHidden = ! HaveCursorHidden;
+ if (HaveCursorHidden) {
+ gdk_window_set_cursor(window->window, blank_cursor);
+ } else {
+ gdk_window_set_cursor(window->window, NULL);
+ }
+ }
+
+ if (gTrueBackgroundFlag || ADialogIsUp) {
+ } else {
+ if (RequestInsertDisk) {
+ RequestInsertDisk = falseblnr;
+ InsertADisk0();
+ }
+ }
+
+#if NeedRequestIthDisk
+ if (0 != RequestIthDisk) {
+ Sony_InsertIth(RequestIthDisk);
+ RequestIthDisk = 0;
+ }
+#endif
+}
+
+/* --- command line parsing --- */
+
+LOCALFUNC blnr ScanCommandLine(void)
+{
+ int i;
+
+ for (i = 1; i < my_argc; ++i) {
+ if ('-' == my_argv[i][0]) {
+#if 0
+ if ((0 == strcmp(my_argv[i], "--display")) ||
+ (0 == strcmp(my_argv[i], "-display")))
+ {
+ ++i;
+ if (i < my_argc) {
+ display_name = my_argv[i];
+ }
+ } else
+#endif
+ if ((0 == strcmp(my_argv[i], "--rom")) ||
+ (0 == strcmp(my_argv[i], "-r")))
+ {
+ ++i;
+ if (i < my_argc) {
+ rom_path = my_argv[i];
+ }
+ } else
+#if 0
+ if (0 == strcmp(my_argv[i], "-l")) {
+ SpeedValue = 0;
+ } else
+#endif
+ {
+ MacMsg(kStrBadArgTitle, kStrBadArgMessage, falseblnr);
+ }
+ } else {
+ (void) Sony_Insert1(my_argv[i], falseblnr);
+ }
+ }
+ return trueblnr;
+}
+
+/* --- main program flow --- */
+
+GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void)
+{
+ UpdateTrueEmulatedTime();
+ return TrueEmulatedTime == OnTrueTime;
+}
+
+LOCALPROC WaitForTheNextEvent(void)
+{
+ (void) gtk_main_iteration_do(TRUE);
+}
+
+LOCALPROC CheckForSystemEvents(void)
+{
+ int i = 10;
+
+ while (gtk_events_pending() && (--i >= 0)) {
+ (void) gtk_main_iteration_do(FALSE);
+ }
+#if 0
+ XFlush(x_display);
+#endif
+}
+
+GLOBALOSGLUPROC WaitForNextTick(void)
+{
+label_retry:
+ CheckForSystemEvents();
+ CheckForSavedTasks();
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (CurSpeedStopped) {
+ DoneWithDrawingForTick();
+ WaitForTheNextEvent();
+ goto label_retry;
+ }
+
+ if (ExtraTimeNotOver()) {
+ si5b TimeDiff = GetTimeDiff();
+ if (TimeDiff < 0) {
+ g_usleep(- TimeDiff);
+ }
+ goto label_retry;
+ }
+
+ if (CheckDateTime()) {
+#if EnableDemoMsg
+ DemoModeSecondNotify();
+#endif
+ }
+
+ if ((! gBackgroundFlag || ADialogIsUp)
+ && (! CaughtMouse)
+ )
+ {
+ CheckMouseState();
+ }
+
+ OnTrueTime = TrueEmulatedTime;
+}
+
+#include "PROGMAIN.h"
+
+static gboolean
+MainEventLoop0(gpointer data)
+{
+ (void) data;
+ fprintf(stderr, "hello from MainEventLoop0\n");
+ ProgramMain();
+ if (ForceMacOff) {
+ goto Label_01;
+ }
+#if 0
+ while (! gtk_main_iteration_do(FALSE)) {
+ if (! gtk_events_pending()) {
+ fprintf(stderr, "sleep\n");
+ g_usleep(1000000);
+ }
+ }
+#endif
+Label_01:
+ fprintf(stderr, "leaving MainEventLoop0\n");
+
+ gtk_main_quit();
+
+ return FALSE;
+}
+
+static gboolean
+focus_in_event(GtkWidget *widget, GdkEvent *event,
+ gpointer data)
+{
+ gTrueBackgroundFlag = falseblnr;
+
+ CheckMouseState();
+
+ return FALSE;
+}
+
+static gboolean
+focus_out_event(GtkWidget *widget, GdkEvent *event,
+ gpointer data)
+{
+ gTrueBackgroundFlag = trueblnr;
+ return FALSE;
+}
+
+static gboolean key_press_event(GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+#if 0
+ fprintf(stderr, "hello from key_press_event\n");
+ fprintf(stderr, "keyval %d\n", event->keyval);
+ fprintf(stderr, "hardware_keycode %d\n", event->hardware_keycode);
+#endif
+#if 0
+ {
+ GdkKeymapKey *keys;
+ gint n_keys;
+ int i;
+
+ if (gdk_keymap_get_entries_for_keyval(NULL,
+ event->keyval, &keys, &n_keys))
+ {
+ for (i = 0; i < n_keys; i++) {
+ fprintf(stderr, "keycode %d\n", keys[i].keycode);
+ }
+ g_free(keys);
+ }
+ }
+#endif
+ DoKeyCode(event->hardware_keycode, trueblnr);
+
+ return TRUE;
+}
+
+static gboolean key_release_event(GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+#if 0
+ fprintf(stderr, "hello from key_release_event\n");
+ fprintf(stderr, "keyval %d\n", event->keyval);
+ fprintf(stderr, "hardware_keycode %d\n", event->hardware_keycode);
+#endif
+ DoKeyCode(event->hardware_keycode, falseblnr);
+
+ return TRUE;
+}
+
+static void drag_data_received(GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint info,
+ guint time,
+ gpointer user_data)
+{
+ char **uris;
+ char *file;
+ int i;
+ gboolean handled = FALSE;
+
+ uris = g_strsplit((char *)data->data, "\r\n", -1);
+ if (uris != NULL) {
+ for (i = 0; uris[i] != NULL; i++) {
+ file = g_filename_from_uri(uris[i], NULL, NULL);
+ /* file = gnome_vfs_get_local_path_from_uri(uris[i]); */
+ if (file != NULL) {
+ (void) Sony_Insert1a(file, falseblnr);
+ handled = TRUE;
+ g_free(file);
+ }
+ }
+ g_strfreev(uris);
+ }
+ gtk_drag_finish(drag_context, handled, FALSE, time);
+ if (handled) {
+ gtk_window_present_with_time(GTK_WINDOW(window), time);
+ }
+}
+
+static void do_more_commands_item(GtkAction *action, gpointer user_data)
+{
+ DoMoreCommandsMsg();
+}
+
+static void do_about_item(GtkAction *action, gpointer user_data)
+{
+ DoAboutMsg();
+}
+
+static void do_quit_item(GtkAction *action, gpointer user_data)
+{
+ RequestMacOff = trueblnr;
+}
+
+static void do_open_item(GtkAction *action, gpointer user_data)
+{
+ RequestInsertDisk = trueblnr;
+}
+
+LOCALPROC MyAppendConvertMenuItem(GtkWidget *the_menu,
+ GCallback c_handler, gpointer gobject, char *s, blnr AddEllipsis)
+{
+ char ts[ClStrMaxLength + 1];
+ GtkWidget *the_item;
+
+ NativeStrFromCStr(ts, s, AddEllipsis);
+ the_item = gtk_menu_item_new_with_label(ts);
+ g_signal_connect(G_OBJECT(the_item), "activate",
+ c_handler, gobject);
+ gtk_menu_shell_append(GTK_MENU_SHELL(the_menu), the_item);
+}
+
+LOCALPROC MyAppendSubmenuConvertName(GtkWidget *menubar,
+ GtkWidget *the_menu, char *s)
+{
+ char ts[ClStrMaxLength + 1];
+ GtkWidget *the_item;
+
+ NativeStrFromCStr(ts, s, falseblnr);
+ the_item = gtk_menu_item_new_with_label(ts);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(the_item), the_menu);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menubar), the_item);
+}
+
+static GdkPixmap *blank_pixmap;
+static GdkColor blank_color = {
+ 0, 0, 0, 0
+};
+
+static gchar blank_cursor_bits[] = {
+ 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
+};
+
+static GtkTargetEntry dnd_target =
+{
+ "text/uri-list", 0, 0
+};
+
+LOCALPROC ZapOSGLUVars(void)
+{
+ InitDrives();
+#if 0
+ {
+ int i;
+
+ for (i = 0; i < kNumMagStates; ++i) {
+ HavePositionWins[i] = falseblnr;
+ }
+ }
+#endif
+}
+
+LOCALPROC ReserveAllocAll(void)
+{
+#if dbglog_HAVE
+ dbglog_ReserveAlloc();
+#endif
+ ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr);
+ ReserveAllocOneBlock(&screencomparebuff,
+ vMacScreenNumBytes, 5, trueblnr);
+#if UseControlKeys
+ ReserveAllocOneBlock(&CntrlDisplayBuff,
+ vMacScreenNumBytes, 5, falseblnr);
+#endif
+
+ EmulationReserveAlloc();
+}
+
+LOCALFUNC blnr AllocMyMemory(void)
+{
+ uimr n;
+ blnr IsOk = falseblnr;
+
+ ReserveAllocOffset = 0;
+ ReserveAllocBigBlock = nullpr;
+ ReserveAllocAll();
+ n = ReserveAllocOffset;
+ ReserveAllocBigBlock = (ui3p)calloc(1, n);
+ if (NULL == ReserveAllocBigBlock) {
+ MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr);
+ } else {
+ ReserveAllocOffset = 0;
+ ReserveAllocAll();
+ if (n != ReserveAllocOffset) {
+ /* oops, program error */
+ } else {
+ IsOk = trueblnr;
+ }
+ }
+
+ return IsOk;
+}
+
+LOCALPROC UnallocMyMemory(void)
+{
+ if (nullpr != ReserveAllocBigBlock) {
+ free((char *)ReserveAllocBigBlock);
+ }
+}
+
+LOCALFUNC blnr InitOSGLU(void)
+{
+ if (AllocMyMemory())
+#if dbglog_HAVE
+ if (dbglog_open())
+#endif
+ if (ScanCommandLine())
+ if (LoadMacRom())
+ if (LoadInitialImages())
+ if (InitLocationDat())
+ /* if (ReCreateMainWindow()) */
+ if (KC2MKCInit())
+ if (WaitForRom())
+ {
+ return trueblnr;
+ }
+ return falseblnr;
+}
+
+LOCALPROC UnInitOSGLU(void)
+{
+ if (MacMsgDisplayed) {
+ MacMsgDisplayOff();
+ }
+
+ UnInitDrives();
+
+ ForceShowCursor();
+
+#if dbglog_HAVE
+ dbglog_close();
+#endif
+
+ UnallocMyMemory();
+
+ CheckSavedMacMsg();
+}
+
+int main(int argc, char *argv[])
+{
+ GtkWidget *vbox;
+
+#if 0
+ GtkWidget *button;
+#endif
+
+ GtkWidget *menubar;
+ GtkWidget *the_menu;
+ GtkWidget *the_item;
+
+ gtk_init(&argc, &argv);
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_widget_set_name(window, "Test Input");
+ gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(window), vbox);
+ gtk_widget_show(vbox);
+
+ g_signal_connect(G_OBJECT(window), "delete-event",
+ G_CALLBACK(delete_event), NULL);
+ g_signal_connect(G_OBJECT(window), "focus-out-event",
+ (GCallback)focus_out_event,
+ NULL);
+ g_signal_connect(G_OBJECT(window), "focus-in-event",
+ (GCallback)focus_in_event, NULL);
+
+ g_signal_connect(G_OBJECT(window), "key-press-event",
+ G_CALLBACK(key_press_event), NULL);
+ g_signal_connect(G_OBJECT(window), "key-release-event",
+ G_CALLBACK(key_release_event), NULL);
+
+ menubar = gtk_menu_bar_new();
+
+ the_menu = gtk_menu_new();
+
+ MyAppendConvertMenuItem(the_menu,
+ G_CALLBACK(do_open_item), NULL, kStrMenuItemOpen, trueblnr);
+
+ the_item = gtk_separator_menu_item_new();
+ gtk_menu_shell_append(GTK_MENU_SHELL(the_menu), the_item);
+
+ MyAppendConvertMenuItem(the_menu,
+ G_CALLBACK(do_quit_item), NULL, kStrMenuItemQuit, falseblnr);
+
+ MyAppendSubmenuConvertName(menubar, the_menu, kStrMenuFile);
+
+ the_menu = gtk_menu_new();
+
+ MyAppendConvertMenuItem(the_menu, G_CALLBACK(do_more_commands_item),
+ NULL, kStrMenuItemMore, trueblnr);
+
+ MyAppendSubmenuConvertName(menubar, the_menu, kStrMenuSpecial);
+
+ the_menu = gtk_menu_new();
+
+ MyAppendConvertMenuItem(the_menu,
+ G_CALLBACK(do_about_item), NULL, kStrMenuItemAbout, trueblnr);
+
+ MyAppendSubmenuConvertName(menubar, the_menu, kStrMenuHelp);
+
+ gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
+
+ gtk_widget_show_all(menubar);
+
+
+ /* Create the drawing area */
+
+ drawing_area = gtk_drawing_area_new();
+ gtk_widget_set_size_request(GTK_WIDGET(drawing_area),
+ vMacScreenWidth, vMacScreenHeight);
+ gtk_box_pack_start(GTK_BOX(vbox), drawing_area, TRUE, TRUE, 0);
+
+ gtk_widget_show(drawing_area);
+
+ /* Signals used to handle backing pixmap */
+
+ g_signal_connect(G_OBJECT(drawing_area), "expose-event",
+ G_CALLBACK(expose_event), NULL);
+ g_signal_connect(G_OBJECT(drawing_area), "configure-event",
+ G_CALLBACK(configure_event), NULL);
+
+ /* Event signals */
+
+ g_signal_connect(G_OBJECT(drawing_area), "motion-notify-event",
+ G_CALLBACK(motion_notify_event), NULL);
+ g_signal_connect(G_OBJECT(drawing_area), "enter-notify-event",
+ G_CALLBACK(enter_notify_event), NULL);
+ g_signal_connect(G_OBJECT(drawing_area), "leave-notify-event",
+ G_CALLBACK(leave_notify_event), NULL);
+
+ g_signal_connect(G_OBJECT(drawing_area), "button-press-event",
+ G_CALLBACK(button_press_event), NULL);
+ g_signal_connect(G_OBJECT(drawing_area), "button-release-event",
+ G_CALLBACK(button_release_event), NULL);
+
+ gtk_widget_add_events(window,
+ GDK_KEY_PRESS_MASK
+ | GDK_KEY_RELEASE_MASK
+ );
+
+ gtk_widget_set_events(drawing_area, GDK_EXPOSURE_MASK
+ | GDK_LEAVE_NOTIFY_MASK
+ | GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_POINTER_MOTION_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_LEAVE_NOTIFY_MASK
+ | GDK_FOCUS_CHANGE_MASK
+ | GDK_KEY_PRESS_MASK
+ | GDK_KEY_RELEASE_MASK
+ /* | GDK_POINTER_MOTION_HINT_MASK */
+ );
+
+#if 0
+ /* .. And a quit button */
+ button = gtk_button_new_with_label("Quit");
+ gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+
+ g_signal_connect_swapped(G_OBJECT(button), "clicked",
+ G_CALLBACK(delete_event), NULL
+ /*
+ G_CALLBACK(gtk_widget_destroy),
+ G_OBJECT(window)
+ */
+ );
+ gtk_widget_show(button);
+#endif
+
+ gtk_drag_dest_set(drawing_area, GTK_DEST_DEFAULT_ALL,
+ &dnd_target, 1,
+ GDK_ACTION_COPY);
+ g_signal_connect(GTK_OBJECT(drawing_area), "drag-data-received",
+ G_CALLBACK(drag_data_received), NULL);
+
+ gtk_widget_show(window);
+
+ blank_pixmap = gdk_bitmap_create_from_data(NULL,
+ blank_cursor_bits, 16, 16);
+ blank_cursor = gdk_cursor_new_from_pixmap(blank_pixmap,
+ blank_pixmap, &blank_color, &blank_color, 8, 8);
+ gdk_pixmap_unref(blank_pixmap);
+
+ gdk_window_set_cursor(window->window, blank_cursor);
+
+ g_idle_add(MainEventLoop0, NULL);
+
+ my_argc = argc;
+ my_argv = argv;
+
+ ZapOSGLUVars();
+ if (InitOSGLU()) {
+ gtk_main ();
+ }
+ UnInitOSGLU();
+
+ return 0;
+}
--- /dev/null
+++ b/src/OSGLUMAC.c
@@ -1,0 +1,5775 @@
+/*
+ OSGLUMAC.c
+
+ Copyright (C) 2009 Philip Cummins, Richard F. Bannister,
+ Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Operating System GLUe for MACintosh
+
+ All operating system dependent code for the
+ Macintosh (pre OS X) platform should go here.
+
+ This is also the "reference" implementation. General
+ comments about what the platform dependent code
+ does should go here, and not be repeated for each
+ platform.
+
+ This code is descended from Richard F. Bannister's Macintosh
+ port of vMac, by Philip Cummins.
+
+ The main entry point 'main' is at the end of this file.
+*/
+
+#include "CNFGRAPI.h"
+#include "SYSDEPNS.h"
+#include "ENDIANAC.h"
+
+#include "MYOSGLUE.h"
+
+#include "STRCONST.h"
+
+#ifndef NavigationAvail
+#define NavigationAvail 1
+#endif
+
+#ifndef AppearanceAvail
+#define AppearanceAvail 1
+#endif
+
+#ifndef NewNamesAvail
+#define NewNamesAvail 1
+#endif
+
+#ifndef CALL_NOT_IN_CARBON
+#define CALL_NOT_IN_CARBON 1
+#endif /* !defined(CALL_NOT_IN_CARBON) */
+
+
+/* --- information about the environment --- */
+
+/*
+ code to determine characteristics
+ of the current run time environment.
+*/
+
+#define TestBit(i, p) (((uimr)(i) & ((uimr)1 << (p))) != 0)
+
+#ifndef HaveCPUfamM68K
+#define HaveCPUfamM68K 0
+#endif
+
+#if HaveCPUfamM68K
+
+/* MACENVRN.i */
+
+#ifndef Support64kROM
+#define Support64kROM 1
+#endif
+
+#define Have64kROM() (LMGetROM85() < 0)
+
+/* -- basic environment checking -- */
+
+#ifndef DebugTrapAvailableChecks
+#define DebugTrapAvailableChecks 0
+#endif
+
+LOCALFUNC blnr LowToolTrapAvailable(short trap_num)
+{
+#if DebugTrapAvailableChecks
+ if ((trap_num & 0x0800) == 0) {
+ DebugStr("\pOSTrap in LowToolTrapAvailable");
+ return falseblnr;
+ }
+ if ((trap_num & 0x07ff) >= 0x200) {
+ DebugStr("\pHiToolTrap in LowToolTrapAvailable");
+ return falseblnr;
+ }
+#endif
+ return GetToolTrapAddress(trap_num) !=
+ GetToolTrapAddress(_Unimplemented);
+}
+
+LOCALFUNC blnr HiToolTrapAvailable(short trap_num)
+{
+#if DebugTrapAvailableChecks
+ if ((trap_num & 0x0800) == 0) {
+ DebugStr("\pOSTrap in HiToolTrapAvailable");
+ return falseblnr;
+ }
+ if (((trap_num & 0x07ff) < 0x200)
+ || ((trap_num & 0x07ff) >= 0x400))
+ {
+ DebugStr("\pLowToolTrap in HiToolTrapAvailable");
+ return falseblnr;
+ }
+#endif
+ if (GetToolTrapAddress(_InitGraf)
+ == GetToolTrapAddress(0xAA6E))
+ {
+ return falseblnr;
+ } else {
+ return GetToolTrapAddress(trap_num) !=
+ GetToolTrapAddress(_Unimplemented);
+ }
+}
+
+LOCALFUNC blnr OSTrapAvailable(short trap_num)
+{
+#if DebugTrapAvailableChecks
+ if ((trap_num & 0x0800) != 0) {
+ DebugStr("\pToolTrap in ToolTrapAvailable");
+ return falseblnr;
+ }
+#endif
+ return GetOSTrapAddress(trap_num) !=
+ GetToolTrapAddress(_Unimplemented);
+}
+
+LOCALVAR blnr MyEnvrAttrWaitNextEventAvail;
+LOCALVAR blnr HaveEnvrAttrWaitNextEventAvail = falseblnr;
+
+LOCALFUNC blnr HaveWaitNextEventAvail(void)
+{
+ if (! HaveEnvrAttrWaitNextEventAvail) {
+ MyEnvrAttrWaitNextEventAvail =
+ LowToolTrapAvailable(_WaitNextEvent);
+ HaveEnvrAttrWaitNextEventAvail = trueblnr;
+ }
+ return MyEnvrAttrWaitNextEventAvail;
+}
+
+LOCALVAR blnr MyEnvrAttrGestaltAvail;
+LOCALVAR blnr HaveEnvrAttrGestaltAvail = falseblnr;
+
+LOCALFUNC blnr HaveGestaltAvail(void)
+{
+ if (! HaveEnvrAttrGestaltAvail) {
+ MyEnvrAttrGestaltAvail =
+ (! Have64kROM()) &&
+ OSTrapAvailable(_Gestalt);
+ /*
+ contrary to all the documentation,
+ TrapAvailable check by itself doesn't
+ work on 64k ROM, because a tool box trap
+ has the same trap number, and both
+ GetOSTrapAddress and GetToolTrapAddress
+ are the same as GetTrapAddress on a 64k ROM.
+ */
+ HaveEnvrAttrGestaltAvail = trueblnr;
+ }
+ return MyEnvrAttrGestaltAvail;
+}
+
+#else
+
+/* for PowerPC, assume always have these routines */
+
+#define HaveWaitNextEventAvail() trueblnr
+#define HaveGestaltAvail() trueblnr
+
+#endif
+
+LOCALVAR blnr MyEnvrAttrAliasMgrAvail;
+LOCALVAR blnr HaveEnvrAttrAliasMgrAvail = falseblnr;
+
+LOCALFUNC blnr HaveAliasMgrAvail(void)
+{
+ if (! HaveEnvrAttrAliasMgrAvail) {
+ long reply;
+
+ MyEnvrAttrAliasMgrAvail =
+ HaveGestaltAvail()
+ && (noErr == Gestalt(gestaltAliasMgrAttr, &reply))
+ && TestBit(reply, gestaltAliasMgrPresent);
+ HaveEnvrAttrAliasMgrAvail = trueblnr;
+ }
+ return MyEnvrAttrAliasMgrAvail;
+}
+
+LOCALVAR blnr MyEnvrAttrAppleEvtMgrAvail;
+LOCALVAR blnr HaveEnvrAttrAppleEvtMgrAvail = falseblnr;
+
+LOCALFUNC blnr HaveAppleEvtMgrAvail(void)
+{
+ if (! HaveEnvrAttrAppleEvtMgrAvail) {
+ long reply;
+
+ MyEnvrAttrAppleEvtMgrAvail =
+ HaveGestaltAvail()
+ && (noErr == Gestalt(gestaltAppleEventsAttr, &reply))
+ && TestBit(reply, gestaltAppleEventsPresent);
+ HaveEnvrAttrAppleEvtMgrAvail = trueblnr;
+ }
+ return MyEnvrAttrAppleEvtMgrAvail;
+}
+
+#if EnableDragDrop
+
+LOCALVAR blnr MyEnvrAttrDragMgrAvail;
+LOCALVAR blnr HaveEnvrAttrDragMgrAvail = falseblnr;
+
+LOCALFUNC blnr HaveDragMgrAvail(void)
+{
+ if (! HaveEnvrAttrDragMgrAvail) {
+ long reply;
+
+ MyEnvrAttrDragMgrAvail =
+ HaveGestaltAvail()
+ && (noErr == Gestalt(gestaltDragMgrAttr, &reply))
+ && TestBit(reply, gestaltDragMgrPresent);
+ HaveEnvrAttrDragMgrAvail = trueblnr;
+ }
+ return MyEnvrAttrDragMgrAvail;
+}
+
+#endif
+
+#ifndef Windows85APIAvail
+#define Windows85APIAvail 1
+#endif
+
+#if Windows85APIAvail
+LOCALVAR blnr MyEnvrAttrHideShowMenuAvail;
+LOCALVAR blnr HaveEnvrAttrHideShowMenuAvail = falseblnr;
+
+LOCALFUNC blnr HaveHideShowMenuAvail(void)
+{
+ if (! HaveEnvrAttrHideShowMenuAvail) {
+ long reply;
+
+ MyEnvrAttrHideShowMenuAvail =
+ HaveGestaltAvail()
+ && (noErr == Gestalt(gestaltMenuMgrAttr, &reply));
+ HaveEnvrAttrHideShowMenuAvail = trueblnr;
+ }
+ return MyEnvrAttrHideShowMenuAvail;
+}
+#endif
+
+#if AppearanceAvail
+LOCALVAR blnr MyEnvrAttrAppearanceAvail;
+LOCALVAR blnr HaveEnvrAttrAppearanceAvail = falseblnr;
+
+LOCALFUNC blnr HaveAppearanceAvail(void)
+{
+ if (! HaveEnvrAttrAppearanceAvail) {
+ long reply;
+
+ MyEnvrAttrAppearanceAvail =
+ HaveGestaltAvail()
+ && (noErr == Gestalt(gestaltAppearanceAttr, &reply));
+ HaveEnvrAttrAppearanceAvail = trueblnr;
+ }
+ return MyEnvrAttrAppearanceAvail;
+}
+#endif
+
+#if HaveCPUfamM68K
+LOCALVAR blnr MyEnvrAttrSndMngrAvail;
+LOCALVAR blnr HaveEnvrAttrSndMngrAvail = falseblnr;
+
+LOCALFUNC blnr HaveSndMngrAvail(void)
+{
+ if (! HaveEnvrAttrSndMngrAvail) {
+ MyEnvrAttrSndMngrAvail = LowToolTrapAvailable(_SndNewChannel);
+ HaveEnvrAttrSndMngrAvail = trueblnr;
+ }
+ return MyEnvrAttrSndMngrAvail;
+}
+#endif
+
+#if NavigationAvail
+LOCALVAR blnr MyEnvrAttrNavServicesAvail;
+LOCALVAR blnr HaveEnvrAttrNavServicesAvail = falseblnr;
+
+LOCALFUNC blnr HaveNavServicesAvail(void)
+{
+ if (! HaveEnvrAttrNavServicesAvail) {
+ MyEnvrAttrNavServicesAvail = NavServicesAvailable();
+ HaveEnvrAttrNavServicesAvail = trueblnr;
+ }
+ return MyEnvrAttrNavServicesAvail;
+}
+#endif
+
+#if HaveCPUfamM68K
+LOCALVAR blnr MyEnvrAttrFSSpecCallsAvail;
+LOCALVAR blnr HaveEnvrAttrFSSpecCallsAvail = falseblnr;
+
+LOCALFUNC blnr HaveFSSpecCallsAvail(void)
+{
+ if (! HaveEnvrAttrFSSpecCallsAvail) {
+ long reply;
+
+ MyEnvrAttrFSSpecCallsAvail =
+ HaveGestaltAvail()
+ && (noErr == Gestalt(gestaltFSAttr, &reply))
+ && TestBit(reply, gestaltHasFSSpecCalls);
+ HaveEnvrAttrFSSpecCallsAvail = trueblnr;
+ }
+ return MyEnvrAttrFSSpecCallsAvail;
+}
+#endif
+
+#if Windows85APIAvail
+LOCALVAR blnr MyEnvrAttrNewWndMgrAvail;
+LOCALVAR blnr HaveEnvrAttrNewWndMgrAvail = falseblnr;
+
+LOCALFUNC blnr HaveNewWndMgrAvail(void)
+{
+ if (! HaveEnvrAttrNewWndMgrAvail) {
+ long reply;
+
+ MyEnvrAttrNewWndMgrAvail =
+ HaveGestaltAvail()
+ && (noErr == Gestalt(gestaltWindowMgrAttr, &reply))
+ && TestBit(reply, gestaltWindowMgrPresentBit);
+ HaveEnvrAttrNewWndMgrAvail = trueblnr;
+ }
+ return MyEnvrAttrNewWndMgrAvail;
+}
+#endif
+
+/* --- initial initialization --- */
+
+#if defined(__SC__) || ((defined(powerc) || defined(__powerc)) \
+ && ! defined(__MWERKS__))
+
+/* GLOBALVAR */ QDGlobals qd;
+#endif
+
+LOCALFUNC blnr InitMacManagers(void)
+{
+ MaxApplZone();
+
+ {
+ int i;
+
+ for (i = 7; --i >= 0; ) {
+ MoreMasters();
+ }
+ }
+
+ InitGraf(&qd.thePort);
+ InitFonts();
+ InitWindows();
+ InitMenus();
+ TEInit();
+ InitDialogs(NULL);
+ InitCursor();
+ return trueblnr;
+}
+
+
+/* --- mac style errors --- */
+
+#define CheckSavetMacErr(result) (mnvm_noErr == (err = (result)))
+ /*
+ where 'err' is a variable of type tMacErr in the function
+ this is used in
+ */
+
+#define To_tMacErr(result) ((tMacErr)(ui4b)(result))
+
+#define CheckSaveMacErr(result) (CheckSavetMacErr(To_tMacErr(result)))
+
+
+/*
+ define NotAfileRef to some value that is different
+ from any valid open file reference.
+*/
+#define NotAfileRef (-1)
+
+struct MyDir_R {
+ long DirId;
+ short VRefNum;
+};
+typedef struct MyDir_R MyDir_R;
+
+LOCALFUNC tMacErr OpenNamedFileInFolder(MyDir_R *d,
+ ps3p fileName, short *refnum)
+{
+ tMacErr err;
+
+#if HaveCPUfamM68K
+ if (! HaveFSSpecCallsAvail()) {
+ err = To_tMacErr(FSOpen(fileName, d->VRefNum, refnum));
+ } else
+#endif
+ {
+ Boolean isFolder;
+ Boolean isAlias;
+ FSSpec spec;
+
+ if (CheckSaveMacErr(
+ FSMakeFSSpec(d->VRefNum, d->DirId, fileName, &spec)))
+ if (CheckSaveMacErr(
+ ResolveAliasFile(&spec, trueblnr, &isFolder, &isAlias)))
+ if (CheckSaveMacErr(
+ FSpOpenDF(&spec, fsRdPerm, refnum)))
+ {
+ }
+ }
+
+ return err;
+}
+
+/* --- sending debugging info to file --- */
+
+#if dbglog_HAVE
+
+#define Support64kROM 0
+#define tMyErr tMacErr
+
+typedef unsigned char * MyPtr;
+
+LOCALFUNC tMyErr MyHGetDir_v2(MyDir_R *d)
+{
+ tMyErr err;
+ WDPBRec r;
+
+ r.ioCompletion = NULL;
+ r.ioNamePtr = NULL;
+
+#if Support64kROM
+ if (Have64kROM()) {
+ err = PBGetVolSync((ParamBlockRec *)&r);
+ d->VRefNum = r.ioVRefNum;
+ d->DirId = 0;
+ } else
+#endif
+ {
+ err = PBHGetVolSync(&r);
+ d->VRefNum = r.ioWDVRefNum;
+ d->DirId = r.ioWDDirID;
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr MyWriteBytes_v2(short refNum, MyPtr p, uimr L)
+{
+ ParamBlockRec r;
+
+ r.ioParam.ioCompletion = NULL;
+ r.ioParam.ioRefNum = refNum;
+ r.ioParam.ioBuffer = (Ptr)p;
+ r.ioParam.ioReqCount = L;
+ r.ioParam.ioPosMode = (short) fsFromMark;
+ r.ioParam.ioPosOffset = 0;
+
+ return PBWriteSync(&r);
+}
+
+LOCALFUNC tMyErr MyCloseFile_v2(short refNum)
+{
+ ParamBlockRec r;
+
+ r.ioParam.ioCompletion = NULL;
+ r.ioParam.ioRefNum = refNum;
+
+ return PBCloseSync(&r);
+#if 0
+ return (tMyErr)FSClose(refNum);
+#endif
+}
+
+#define NotAfileRef (-1)
+
+/*
+ Probably should use PBHOpenDF instead
+ of PBHOpen when it is available.
+ (System 7 according to Technical Note FL515)
+*/
+
+LOCALFUNC tMyErr MyFileOpen_v2(MyDir_R *d, StringPtr s,
+ char Permssn, short *refnum)
+{
+ tMyErr err;
+ HParamBlockRec r;
+
+ r.ioParam.ioCompletion = NULL;
+ r.ioParam.ioNamePtr = s;
+ r.ioParam.ioVRefNum = d->VRefNum;
+ r.ioParam.ioPermssn = Permssn;
+ r.ioParam.ioMisc = 0; /* use volume buffer */
+ r.ioParam.ioVersNum = 0; /* needed if MFS volume */
+
+#if Support64kROM
+ if (Have64kROM()) {
+ err = PBOpenSync((ParamBlockRec *)&r);
+ } else
+#endif
+ {
+ r.fileParam.ioDirID = d->DirId;
+ err = PBHOpenSync(&r);
+ }
+
+ if (noErr == err) {
+ *refnum = r.ioParam.ioRefNum;
+ /*
+ Don't change *refnum unless file opened,
+ so can initialize to NotAfileRef, and
+ compare later before closing in uninit.
+ */
+ }
+ return err;
+}
+
+LOCALFUNC tMyErr MyFileOpenWrite_v2(MyDir_R *d, StringPtr s,
+ short *refnum)
+{
+ return MyFileOpen_v2(d, s, (char)fsWrPerm, refnum);
+}
+
+LOCALFUNC tMyErr MyDeleteFile_v2(MyDir_R *d, StringPtr s)
+{
+ tMyErr err;
+ HParamBlockRec r;
+
+ r.fileParam.ioCompletion = NULL;
+ r.fileParam.ioVRefNum = d->VRefNum;
+ r.fileParam.ioNamePtr = s;
+ r.fileParam.ioFVersNum = 0; /* needed if MFS volume */
+
+#if Support64kROM
+ if (Have64kROM()) {
+ err = PBDeleteSync((ParamBlockRec *)&r);
+ } else
+#endif
+ {
+ r.fileParam.ioDirID = d->DirId;
+ err = PBHDeleteSync(&r);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr MyCreateFile_v2(MyDir_R *d, StringPtr s)
+{
+ tMyErr err;
+ HParamBlockRec r;
+
+ r.fileParam.ioFlVersNum = 0;
+ /*
+ Think reference says to do this,
+ but not Inside Mac IV
+ */
+
+ r.fileParam.ioCompletion = NULL;
+ r.fileParam.ioNamePtr = s;
+ r.fileParam.ioVRefNum = d->VRefNum;
+ r.fileParam.ioFVersNum = 0; /* needed if MFS volume */
+
+#if Support64kROM
+ if (Have64kROM()) {
+ err = PBCreateSync((ParamBlockRec *)&r);
+ } else
+#endif
+ {
+ r.fileParam.ioDirID = d->DirId;
+ err = PBHCreateSync(&r);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr MyFileGetInfo_v2(MyDir_R *d, StringPtr s,
+ HParamBlockRec *r)
+{
+ tMyErr err;
+
+ r->fileParam.ioCompletion = NULL;
+ r->fileParam.ioNamePtr = s;
+ r->fileParam.ioVRefNum = d->VRefNum;
+ r->fileParam.ioFVersNum = (char)0; /* needed if MFS volume */
+ r->fileParam.ioFDirIndex = (short)0;
+
+#if Support64kROM
+ if (Have64kROM()) {
+ err = PBGetFInfoSync((ParamBlockRec *)r);
+ } else
+#endif
+ {
+ r->fileParam.ioDirID = d->DirId;
+ err = PBHGetFInfoSync(r);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr MyFileSetInfo_v2(MyDir_R *d, StringPtr s,
+ HParamBlockRec *r)
+{
+ tMyErr err;
+
+ r->fileParam.ioCompletion = NULL;
+ r->fileParam.ioNamePtr = s;
+ r->fileParam.ioVRefNum = d->VRefNum;
+ r->fileParam.ioFVersNum = (char)0; /* needed if MFS volume */
+
+#if Support64kROM
+ if (Have64kROM()) {
+ err = PBSetFInfoSync((ParamBlockRec *)r);
+ } else
+#endif
+ {
+ r->fileParam.ioDirID = d->DirId;
+ err = PBHSetFInfoSync(r);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr MyFileSetTypeCreator_v2(MyDir_R *d, StringPtr s,
+ OSType creator, OSType fileType)
+{
+ tMyErr err;
+ HParamBlockRec r;
+
+ if (noErr == (err = MyFileGetInfo_v2(d, s, &r))) {
+ r.fileParam.ioFlFndrInfo.fdType = fileType;
+ r.fileParam.ioFlFndrInfo.fdCreator = creator;
+ err = MyFileSetInfo_v2(d, s, &r);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr MyCreateFileOverWrite_v2(MyDir_R *d, StringPtr s)
+{
+ tMyErr err;
+
+ err = MyCreateFile_v2(d, s);
+ if (dupFNErr == err) {
+ if (noErr == (err = MyDeleteFile_v2(d, s))) {
+ err = MyCreateFile_v2(d, s);
+ }
+ }
+
+ return err;
+}
+
+LOCALFUNC tMyErr MyOpenNewFile_v3(MyDir_R *d, StringPtr s,
+ OSType creator, OSType fileType,
+ short *refnum)
+/*
+ Deletes old file if already exists.
+*/
+{
+ tMyErr err;
+
+ err = MyCreateFileOverWrite_v2(d, s);
+ if (noErr == err) {
+ err = MyFileSetTypeCreator_v2(d, s,
+ creator, fileType);
+ if (noErr == err) {
+ err = MyFileOpenWrite_v2(d, s, refnum);
+ }
+
+ if (noErr != err) {
+ (void) MyDeleteFile_v2(d, s);
+ /* ignore any error, since already got one */
+ }
+ }
+
+ return err;
+}
+
+
+LOCALVAR short dbglog_File = NotAfileRef;
+LOCALVAR tMyErr dbglog_err = noErr;
+
+LOCALFUNC blnr dbglog_open0(void)
+{
+ tMacErr err;
+ MyDir_R d;
+
+ if (noErr == (err = MyHGetDir_v2(&d))) {
+ err = MyFileOpen_v2(&d, (StringPtr)"\pdbglog",
+ (char)fsWrPerm, &dbglog_File);
+ if (mnvm_noErr /* fnfErr */ == err) {
+ err = SetEOF(dbglog_File, 0);
+ } else {
+ err = MyOpenNewFile_v3(&d, (StringPtr)"\pdbglog",
+ 'MPS ', 'TEXT', &dbglog_File);
+ err = mnvm_noErr;
+ }
+
+ }
+
+ return (mnvm_noErr == err);
+}
+
+LOCALPROC dbglog_write0(char *s, uimr L)
+{
+ if (NotAfileRef != dbglog_File)
+ if (noErr == dbglog_err)
+ {
+ dbglog_err = MyWriteBytes_v2(dbglog_File, (MyPtr)s, L);
+ }
+}
+
+LOCALPROC dbglog_close0(void)
+{
+ if (NotAfileRef != dbglog_File) {
+ (void) MyCloseFile_v2(dbglog_File);
+ dbglog_File = NotAfileRef;
+ }
+}
+
+#endif /* dbglog_HAVE */
+
+
+/* --- control mode and internationalization --- */
+
+#define NeedCell2MacAsciiMap 1
+
+#define WantColorTransValid 1
+
+#include "INTLCHAR.h"
+
+#include "COMOSGLU.h"
+
+#define WantKeyboard_RemapMac 1
+
+#include "CONTROLM.h"
+
+/* --- some simple utilities --- */
+
+GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount)
+{
+ BlockMove((Ptr)srcPtr, (Ptr)destPtr, byteCount);
+}
+
+/* don't want to include c libraries, so: */
+LOCALFUNC si5b CStrLen(char *src)
+{
+ char *p = src;
+ while (*p++ != 0) {
+ }
+ return ((si5b)p) - ((si5b)src) - 1;
+}
+
+#define PStrMaxLength 255
+
+LOCALPROC PStrFromCStr(ps3p r, /* CONST */ char *s)
+{
+ unsigned short L;
+
+ L = CStrLen(s);
+ if (L > PStrMaxLength) {
+ L = PStrMaxLength;
+ }
+ *r++ = L;
+ MyMoveBytes((anyp)s, (anyp)r, L);
+}
+
+LOCALPROC PStrFromChar(ps3p r, char x)
+{
+ r[0] = 1;
+ r[1] = (char)x;
+}
+
+LOCALPROC PStrFromHandle(ps3p r, Handle h, ui5b MaxL)
+{
+ ui5b L = GetHandleSize(h);
+
+ if (L > MaxL) {
+ L = MaxL;
+ }
+
+ *r++ = L;
+ BlockMove(*h, (Ptr)r, L);
+}
+
+LOCALFUNC tMacErr PStrToHand(ps3p s, Handle *r)
+{
+ return To_tMacErr(PtrToHand((Ptr)(s + 1), r, s[0]));
+}
+
+/* --- utilities for adapting to the environment --- */
+
+#ifndef MightNotHaveAppearanceMgrAvail
+#define MightNotHaveAppearanceMgrAvail 1
+#endif
+
+#ifndef MightNotHaveWindows85Avail
+#define MightNotHaveWindows85Avail MightNotHaveAppearanceMgrAvail
+#endif
+
+#ifndef LowMemAPIAvail
+#define LowMemAPIAvail 1
+#endif
+
+#ifndef My_LMGetTime
+#if LowMemAPIAvail
+#define My_LMGetTime LMGetTime
+#else
+#define My_LMGetTime() (*(SInt32 *)(0x020C))
+#endif
+#endif
+
+#ifndef My_LMGetMBarHeight
+#if LowMemAPIAvail
+#define My_LMGetMBarHeight LMGetMBarHeight
+#else
+#define My_LMGetMBarHeight() (*(short *)(0x0BAA))
+#endif
+#endif
+
+#ifndef My_GetGrayRgn
+#if /* LowMemAPIAvail */ 0
+#define My_GetGrayRgn LMGetGrayRgn
+#else
+#define My_GetGrayRgn() (*(RgnHandle *)(0x9EE))
+#endif
+#endif
+
+#ifndef My_LMGetCurApName
+#if LowMemAPIAvail
+#define My_LMGetCurApName LMGetCurApName
+#else
+#define My_LMGetCurApName() ((StringPtr) 0x0910)
+#endif
+#endif
+
+#define MyGetScreenBitsBounds(r) (*r) = qd.screenBits.bounds
+
+#define My_GetRegionBounds(region, bounds) *(bounds) = \
+ (**(region)).rgnBBox
+
+#define My_GetPortPixMap(p) ((p)->portPixMap)
+
+#ifndef My_WindowRef
+#if NewNamesAvail
+#define My_WindowRef WindowRef
+#else
+#define My_WindowRef WindowPtr
+#endif
+#endif
+
+#define My_SetPortWindowPort(w) SetPort(w)
+
+LOCALPROC My_InvalWindowRect(My_WindowRef mw, Rect *r)
+{
+ GrafPtr SavePort;
+
+ GetPort(&SavePort);
+ My_SetPortWindowPort(mw);
+ InvalRect(r);
+ SetPort(SavePort);
+}
+
+#define My_GetWindowPortBounds(w, r) *(r) = ((w)->portRect)
+
+LOCALPROC InvalWholeWindow(My_WindowRef mw)
+{
+ Rect bounds;
+
+ My_GetWindowPortBounds(mw, &bounds);
+ My_InvalWindowRect(mw, &bounds);
+}
+
+LOCALPROC MySetMacWindContRect(My_WindowRef mw, Rect *r)
+{
+#if Windows85APIAvail
+ if (HaveNewWndMgrAvail()) {
+ (void) SetWindowBounds (mw, kWindowContentRgn, r);
+ } else
+#endif
+ {
+#if MightNotHaveWindows85Avail
+ MoveWindow(mw, r->left, r->top, falseblnr);
+ SizeWindow(mw, r->right - r->left, r->bottom - r->top,
+ trueblnr);
+#endif
+ }
+ InvalWholeWindow(mw);
+}
+
+LOCALFUNC blnr MyGetWindowTitleBounds(My_WindowRef mw, Rect *r)
+{
+#if Windows85APIAvail
+ if (HaveNewWndMgrAvail()) {
+ return (noErr == GetWindowBounds(mw,
+ kWindowTitleBarRgn, r));
+ } else
+#endif
+ {
+#if MightNotHaveWindows85Avail
+ My_GetRegionBounds(((WindowPeek)mw)->strucRgn, r);
+ r->bottom = r->top + 15;
+ r->left += 4;
+ r->right -= 4;
+#endif
+ return trueblnr;
+ }
+}
+
+#define topLeft(r) (((Point *) &(r))[0])
+#define botRight(r) (((Point *) &(r))[1])
+
+LOCALFUNC blnr MyGetWindowContBounds(My_WindowRef mw, Rect *r)
+{
+#if Windows85APIAvail
+ if (HaveNewWndMgrAvail()) {
+ return (noErr == GetWindowBounds(mw,
+ kWindowContentRgn, r));
+ } else
+#endif
+ {
+#if MightNotHaveWindows85Avail
+ GrafPtr oldPort;
+ GetPort(&oldPort);
+ My_SetPortWindowPort(mw);
+ My_GetWindowPortBounds(mw, r);
+ LocalToGlobal(&topLeft(*r));
+ LocalToGlobal(&botRight(*r));
+ SetPort(oldPort);
+#endif
+ return trueblnr;
+ }
+}
+
+LOCALPROC MyGetGrayRgnBounds(Rect *r)
+{
+ My_GetRegionBounds(My_GetGrayRgn(), (Rect *)r);
+}
+
+/* --- main window data --- */
+
+LOCALVAR WindowPtr gMyMainWindow = NULL;
+
+#if MayFullScreen
+LOCALVAR short hOffset;
+LOCALVAR short vOffset;
+#endif
+
+#if MayFullScreen
+LOCALVAR blnr GrabMachine = falseblnr;
+#endif
+
+#if VarFullScreen
+LOCALVAR blnr UseFullScreen = (WantInitFullScreen != 0);
+#endif
+
+#if EnableMagnify
+LOCALVAR blnr UseMagnify = (WantInitMagnify != 0);
+#endif
+
+#if EnableMagnify
+LOCALPROC MyScaleRect(Rect *r)
+{
+ r->left *= MyWindowScale;
+ r->right *= MyWindowScale;
+ r->top *= MyWindowScale;
+ r->bottom *= MyWindowScale;
+}
+#endif
+
+LOCALPROC SetScrnRectFromCoords(Rect *r,
+ si4b top, si4b left, si4b bottom, si4b right)
+{
+ r->left = left;
+ r->right = right;
+ r->top = top;
+ r->bottom = bottom;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ OffsetRect(r, - ViewHStart, - ViewVStart);
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ MyScaleRect(r);
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ OffsetRect(r, hOffset, vOffset);
+ }
+#endif
+
+}
+
+#if EnableMagnify
+#define MyScaledHeight (MyWindowScale * vMacScreenHeight)
+#define MyScaledWidth (MyWindowScale * vMacScreenWidth)
+#endif
+
+#if EnableMagnify
+LOCALVAR ui3p ScalingBuff = nullpr;
+#endif
+
+#if EnableMagnify
+
+LOCALVAR ui3p ScalingTabl = nullpr;
+#define ScalingTablsz (256 * MyWindowScale)
+
+#define ScrnMapr_DoMap UpdateScaledBWCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 0
+#define ScrnMapr_Map ScalingTabl
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#endif
+
+#if EnableMagnify
+LOCALPROC SetUpScalingTabl(void)
+{
+ ui3b *p4;
+ int i;
+ int j;
+ int k;
+ ui3r bitsRemaining;
+ ui3b t1;
+ ui3b t2;
+
+ p4 = ScalingTabl;
+ for (i = 0; i < 256; ++i) {
+ bitsRemaining = 8;
+ t2 = 0;
+ for (j = 8; --j >= 0; ) {
+ t1 = (i >> j) & 1;
+ for (k = MyWindowScale; --k >= 0; ) {
+ t2 = (t2 << 1) | t1;
+ if (--bitsRemaining == 0) {
+ *p4++ = t2;
+ bitsRemaining = 8;
+ t2 = 0;
+ }
+ }
+ }
+ }
+}
+#endif
+
+LOCALPROC DefaultDrawScreenBuff(si4b top, si4b left,
+ si4b bottom, si4b right)
+{
+ BitMap src;
+ Rect SrcRect;
+ Rect DstRect;
+
+ SrcRect.left = left;
+ SrcRect.right = right;
+ SrcRect.top = top;
+ SrcRect.bottom = bottom;
+
+ src.rowBytes = vMacScreenMonoByteWidth;
+ SetRect(&src.bounds, 0, 0, vMacScreenWidth, vMacScreenHeight);
+#if EnableMagnify
+ if (UseMagnify) {
+
+ if (! ColorTransValid) {
+ SetUpScalingTabl();
+ ColorTransValid = trueblnr;
+ }
+
+ UpdateScaledBWCopy(top, left, bottom, right);
+
+ MyScaleRect(&SrcRect);
+ MyScaleRect(&src.bounds);
+
+ src.baseAddr = (Ptr)ScalingBuff;
+ src.rowBytes *= MyWindowScale;
+ } else
+#endif
+ {
+ src.baseAddr = (Ptr)GetCurDrawBuff();
+ }
+ SetScrnRectFromCoords(&DstRect, top, left, bottom, right);
+ CopyBits(&src,
+ &gMyMainWindow->portBits,
+ &SrcRect, &DstRect, srcCopy, NULL);
+ /* FrameRect(&SrcRect); for testing */
+}
+
+LOCALPROC Update_Screen(void)
+{
+ GrafPtr savePort;
+
+ GetPort(&savePort);
+ My_SetPortWindowPort(gMyMainWindow);
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ PaintRect(&gMyMainWindow->portRect);
+ }
+#endif
+
+ DefaultDrawScreenBuff(0, 0, vMacScreenHeight, vMacScreenWidth);
+ SetPort(savePort);
+}
+
+LOCALPROC HaveChangedScreenBuff(si4b top, si4b left,
+ si4b bottom, si4b right)
+{
+#if 0 /* experimental code in progress */
+ if (UseFullScreen)
+ {
+ {
+ PixMapHandle pm= (**GetMainDevice()).gdPMap;
+
+ /* LockPixels(pm); */
+#if EnableMagnify
+ if (! UseMagnify) {
+#define PixelT ui5b
+ PixelT *p1 = (PixelT *)GetPixBaseAddr(pm);
+ int i;
+ int j;
+ int k;
+ ui5b *p0 = (ui5b *)GetCurDrawBuff();
+ ui5b SkipBytes = GetPixRowBytes(pm)
+ - sizeof(PixelT) * vMacScreenWidth;
+ ui5b t0;
+ PixelT a[2];
+
+ ((Ptr)p1) += (long)GetPixRowBytes(pm) * (top + vOffset);
+ p1 += hOffset;
+ p0 += (long)top * vMacScreenWidth / 32;
+
+ a[0] = (PixelT) -1;
+ a[1] = 0;
+
+#if 1
+ for (i = bottom - top; --i >= 0; ) {
+ for (j = vMacScreenWidth / 32; --j >= 0; ) {
+ t0 = *p0++;
+
+ for (k = 32; --k >= 0; ) {
+ PixelT v = a[(t0 >> k) & 1];
+ *p1++ = v;
+ }
+ }
+ ((Ptr)p1) += SkipBytes;
+ }
+#endif
+ } else {
+#define PixelT ui5b
+ PixelT *p1 = (PixelT *)GetPixBaseAddr(pm);
+ int i;
+ int j;
+ int k;
+ ui5b *p0 = (ui5b *)GetCurDrawBuff();
+ PixelT *p2;
+ ui5b t0;
+ PixelT a[2];
+
+ p1 += vOffset * MyScaledWidth;
+ p1 += (long)MyWindowScale * (long)MyScaledWidth * top;
+ p0 += (long)top * vMacScreenWidth / 32;
+
+ a[0] = (PixelT) -1;
+ a[1] = 0;
+
+#if 1
+ for (i = bottom - top; --i >= 0; ) {
+ p2 = p1;
+ for (j = vMacScreenWidth / 32; --j >= 0; ) {
+ t0 = *p0++;
+
+ for (k = 32; --k >= 0; ) {
+ PixelT v = a[(t0 >> k) & 1];
+ /* ((t0 >> k) & 1) - 1 */
+ *p1++ = v;
+ *p1++ = v;
+ }
+ }
+ for (j = MyScaledWidth; --j >= 0; ) {
+ *p1++ = *p2++;
+ }
+ }
+#endif
+ }
+#endif
+ /* UnlockPixels(pm); */
+ }
+ } else
+#endif
+ {
+ GrafPtr savePort;
+
+ GetPort(&savePort);
+ My_SetPortWindowPort(gMyMainWindow);
+ DefaultDrawScreenBuff(top, left, bottom, right);
+ SetPort(savePort);
+ }
+}
+
+LOCALPROC MyDrawChangesAndClear(void)
+{
+ if (ScreenChangedBottom > ScreenChangedTop) {
+ HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft,
+ ScreenChangedBottom, ScreenChangedRight);
+ ScreenClearChanges();
+ }
+}
+
+GLOBALOSGLUPROC DoneWithDrawingForTick(void)
+{
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ AutoScrollScreen();
+ }
+#endif
+ MyDrawChangesAndClear();
+}
+
+/* --- keyboard --- */
+
+LOCALVAR ui5b LastEmKeys[4];
+
+LOCALPROC ZapEmKeys(void)
+{
+ LastEmKeys[0] = 0;
+ LastEmKeys[1] = 0;
+ LastEmKeys[2] = 0;
+ LastEmKeys[3] = 0;
+}
+
+LOCALPROC CheckKeyBoardState(void)
+{
+ int i;
+ int j;
+ ui5b NewKeys[4];
+
+ GetKeys(*(KeyMap *)NewKeys);
+
+ for (j = 0; j < 16; ++j) {
+ ui3b k1 = ((ui3b *)NewKeys)[j];
+ ui3b k2 = ((ui3b *)LastEmKeys)[j];
+ ui3b k3 = k1 ^ k2;
+
+ if (k3 != 0) {
+ for (i = 0; i < 8; ++i) {
+ if ((k3 & (1 << i)) != 0) {
+ Keyboard_UpdateKeyMap2(Keyboard_RemapMac(j * 8 + i),
+ (k1 & (1 << i)) != 0);
+ }
+ }
+ }
+ }
+ for (i = 0; i < 4; ++i) {
+ LastEmKeys[i] = NewKeys[i];
+ }
+}
+
+LOCALVAR WantCmdOptOnReconnect = falseblnr;
+
+#define KeyMap_TestBit(m, key) \
+ ((((ui3b *)m)[(key) / 8] & (1 << ((key) & 7))) != 0)
+
+LOCALPROC ReconnectKeyCodes3(void)
+/* so keys already pressed will be ignored */
+{
+ int i;
+ int j;
+ blnr oldv;
+ blnr newv;
+ ui5b NewKeys[4];
+
+ GetKeys(*(KeyMap *)NewKeys);
+
+ /* except check CapsLock */
+ oldv = KeyMap_TestBit(LastEmKeys, MKC_CapsLock);
+ newv = KeyMap_TestBit(NewKeys, MKC_CapsLock);
+ if (oldv != newv) {
+ Keyboard_UpdateKeyMap2(MKC_formac_CapsLock, newv);
+ }
+
+ /* and except for command/option on receive drop */
+ if (WantCmdOptOnReconnect) {
+ WantCmdOptOnReconnect = falseblnr;
+
+ for (i = 0; i < 16; ++i) {
+ ui3b v = ((ui3b *)NewKeys)[i];
+ for (j = 0; j < 8; ++j) {
+ if (0 != ((1 << j) & v)) {
+ ui3r k = i * 8 + j;
+ if (MKC_CapsLock != k) {
+ Keyboard_UpdateKeyMap2(Keyboard_RemapMac(k),
+ trueblnr);
+ }
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < 4; ++i) {
+ LastEmKeys[i] = NewKeys[i];
+ }
+}
+
+/* --- cursor hiding --- */
+
+LOCALVAR blnr HaveCursorHidden = falseblnr;
+LOCALVAR blnr WantCursorHidden = falseblnr;
+
+LOCALPROC ForceShowCursor(void)
+{
+ if (HaveCursorHidden) {
+ HaveCursorHidden = falseblnr;
+ ShowCursor();
+ }
+}
+
+LOCALPROC SetCursorArrow(void)
+{
+ SetCursor(&qd.arrow);
+}
+
+/* --- cursor moving --- */
+
+/*
+ When "EnableFSMouseMotion" the platform
+ specific code can get relative mouse
+ motion, instead of absolute coordinates
+ on the emulated screen. It should
+ set HaveMouseMotion to true when
+ it is doing this (normally when in
+ full screen mode.)
+
+ This can usually be implemented by
+ hiding the platform specific cursor,
+ and then keeping it within a box,
+ moving the cursor back to the center whenever
+ it leaves the box. This requires the
+ ability to move the cursor (in MyMoveMouse).
+*/
+
+/*
+ mouse moving code (non OS X) adapted from
+ MoveMouse.c by Dan Sears, which says that
+ "Based on code from Jon Wtte, Denis Pelli,
+ Apple, and a timely suggestion from Bo Lindbergh."
+ Also says 'For documentation of the CDM, see Apple
+ Tech Note "HW 01 - ADB (The Untold Story: Space Aliens
+ ate my mouse)"'
+*/
+
+#ifndef TARGET_CPU_PPC
+#error "TARGET_CPU_PPC undefined"
+#endif
+
+#if TARGET_CPU_PPC
+enum {
+ glueUppCursorDeviceMoveToProcInfo =
+ kD0DispatchedPascalStackBased |
+ DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
+ RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
+ DISPATCHED_STACK_ROUTINE_PARAMETER(1,
+ SIZE_CODE(sizeof(CursorDevicePtr))) |
+ DISPATCHED_STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) |
+ DISPATCHED_STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))),
+ glueUppCursorDeviceNextDeviceProcInfo =
+ kD0DispatchedPascalStackBased |
+ DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
+ RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
+ DISPATCHED_STACK_ROUTINE_PARAMETER(1,
+ SIZE_CODE(sizeof(CursorDevicePtr *)))
+};
+#endif
+
+#if TARGET_CPU_PPC
+LOCALFUNC OSErr
+CallCursorDeviceMoveTo(
+ CursorDevicePtr ourDevice,
+ long absX,
+ long absY)
+{
+ return CallUniversalProc(
+ GetToolboxTrapAddress(_CursorDeviceDispatch),
+ glueUppCursorDeviceMoveToProcInfo,
+ 1, ourDevice, absX, absY);
+}
+#else
+#define CallCursorDeviceMoveTo CursorDeviceMoveTo
+#endif
+
+#if TARGET_CPU_PPC
+LOCALFUNC OSErr
+CallCursorDeviceNextDevice(
+ CursorDevicePtr *ourDevice)
+{
+ return CallUniversalProc(
+ GetToolboxTrapAddress(_CursorDeviceDispatch),
+ glueUppCursorDeviceNextDeviceProcInfo,
+ 0xB, ourDevice);
+}
+#else
+#define CallCursorDeviceNextDevice CursorDeviceNextDevice
+#endif
+
+#if ! TARGET_CPU_PPC
+pascal void CallCursorTask(void) =
+{
+ 0x2078, 0x08EE, /* MOVE.L jCrsrTask,A0 */
+ 0x4E90 /* JSR (A0) */
+};
+#endif
+
+/*
+ Low memory globals for the mouse
+*/
+
+#define MyRawMouse 0x082C
+ /* low memory global that has current mouse loc */
+#define MyMTemp 0x0828
+ /* low memory global that has current mouse loc */
+#define MyCrsrNew 0x08CE
+ /* set after you change mtemp and rawmouse */
+#define MyCrsrCouple 0x08CF
+ /* true if the cursor is tied to the mouse */
+
+LOCALFUNC blnr MyMoveMouse(si4b h, si4b v)
+{
+ /*
+ Move the cursor to the point h, v
+ on the emulated screen.
+ if detect that this fails return falseblnr,
+ otherwise return trueblnr.
+ (on some platforms it is possible to
+ move the curser, but there is no
+ way to detect failure.)
+ */
+ GrafPtr oldPort;
+ Point CurMousePos;
+ Point NewMousePos;
+ ui5b difftime;
+ blnr IsOk;
+ long int StartTime = TickCount();
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ h -= ViewHStart;
+ v -= ViewVStart;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ h *= MyWindowScale;
+ v *= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ h += hOffset;
+ v += vOffset;
+ }
+#endif
+
+ CurMousePos.h = h;
+ CurMousePos.v = v;
+
+ GetPort(&oldPort);
+ My_SetPortWindowPort(gMyMainWindow);
+ LocalToGlobal(&CurMousePos);
+
+ do {
+
+#if HaveCPUfamM68K
+ if (! HiToolTrapAvailable(_CursorDeviceDispatch)) {
+ *(Point *)MyRawMouse = CurMousePos;
+ *(Point *)MyMTemp = CurMousePos;
+ *(Ptr)MyCrsrNew = *(Ptr)MyCrsrCouple;
+#if ! TARGET_CPU_PPC
+ CallCursorTask();
+#endif
+ } else
+#endif
+ {
+ CursorDevice *firstMouse = NULL;
+ CallCursorDeviceNextDevice(&firstMouse);
+ if (firstMouse != NULL) {
+ CallCursorDeviceMoveTo(firstMouse,
+ (long) CurMousePos.h,
+ (long) CurMousePos.v);
+ }
+ }
+
+ GetMouse(&NewMousePos);
+ IsOk = (h == NewMousePos.h) && (v == NewMousePos.v);
+ difftime = (ui5b)(TickCount() - StartTime);
+ } while ((! IsOk) && (difftime < 5));
+
+ SetPort(oldPort);
+ return IsOk;
+}
+
+#if EnableFSMouseMotion
+LOCALPROC AdjustMouseMotionGrab(void)
+{
+ if (gMyMainWindow != NULL) {
+#if MayFullScreen
+ if (GrabMachine) {
+ /*
+ if magnification changes, need to reset,
+ even if HaveMouseMotion already true
+ */
+ if (MyMoveMouse(ViewHStart + (ViewHSize / 2),
+ ViewVStart + (ViewVSize / 2)))
+ {
+ SavedMouseH = ViewHStart + (ViewHSize / 2);
+ SavedMouseV = ViewVStart + (ViewVSize / 2);
+ HaveMouseMotion = trueblnr;
+ }
+ } else
+#endif
+ {
+ if (HaveMouseMotion) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ HaveMouseMotion = falseblnr;
+ }
+ }
+ }
+}
+#endif
+
+#if EnableFSMouseMotion
+LOCALPROC MyMouseConstrain(void)
+{
+ si4b shiftdh;
+ si4b shiftdv;
+
+ if (SavedMouseH < ViewHStart + (ViewHSize / 4)) {
+ shiftdh = ViewHSize / 2;
+ } else if (SavedMouseH > ViewHStart + ViewHSize - (ViewHSize / 4)) {
+ shiftdh = - ViewHSize / 2;
+ } else {
+ shiftdh = 0;
+ }
+ if (SavedMouseV < ViewVStart + (ViewVSize / 4)) {
+ shiftdv = ViewVSize / 2;
+ } else if (SavedMouseV > ViewVStart + ViewVSize - (ViewVSize / 4)) {
+ shiftdv = - ViewVSize / 2;
+ } else {
+ shiftdv = 0;
+ }
+ if ((shiftdh != 0) || (shiftdv != 0)) {
+ SavedMouseH += shiftdh;
+ SavedMouseV += shiftdv;
+ if (! MyMoveMouse(SavedMouseH, SavedMouseV)) {
+ HaveMouseMotion = falseblnr;
+ }
+ }
+}
+#endif
+
+LOCALPROC MousePositionNotify(Point NewMousePos)
+{
+ blnr ShouldHaveCursorHidden = trueblnr;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewMousePos.h -= hOffset;
+ NewMousePos.v -= vOffset;
+ }
+#endif
+#if VarFullScreen
+ else
+#endif
+#if MayNotFullScreen
+ {
+ if (! PtInRgn(NewMousePos, gMyMainWindow->visRgn)) {
+ ShouldHaveCursorHidden = falseblnr;
+ }
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ NewMousePos.h /= MyWindowScale;
+ NewMousePos.v /= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewMousePos.h += ViewHStart;
+ NewMousePos.v += ViewVStart;
+ }
+#endif
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMousePositionSetDelta(
+ NewMousePos.h - SavedMouseH, NewMousePos.v - SavedMouseV);
+ SavedMouseH = NewMousePos.h;
+ SavedMouseV = NewMousePos.v;
+ } else
+#endif
+ {
+ if (NewMousePos.h < 0) {
+ NewMousePos.h = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePos.h >= vMacScreenWidth) {
+ NewMousePos.h = vMacScreenWidth - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+ if (NewMousePos.v < 0) {
+ NewMousePos.v = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePos.v >= vMacScreenHeight) {
+ NewMousePos.v = vMacScreenHeight - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ ShouldHaveCursorHidden = trueblnr;
+ }
+#endif
+
+ /* if (ShouldHaveCursorHidden || CurMouseButton) */
+ /*
+ for a game like arkanoid, would like mouse to still
+ move even when outside window in one direction
+ */
+ MyMousePositionSet(NewMousePos.h, NewMousePos.v);
+ }
+
+ WantCursorHidden = ShouldHaveCursorHidden;
+}
+
+LOCALPROC MousePositionNotifyFromGlobal(Point NewMousePos)
+{
+ GrafPtr oldPort;
+
+ GetPort(&oldPort);
+ My_SetPortWindowPort(gMyMainWindow);
+ GlobalToLocal(&NewMousePos);
+ SetPort(oldPort);
+
+ MousePositionNotify(NewMousePos);
+}
+
+LOCALPROC CheckMouseState(void)
+{
+ Point NewMousePos;
+ GrafPtr oldPort;
+
+ GetPort(&oldPort);
+ My_SetPortWindowPort(gMyMainWindow);
+ GetMouse(&NewMousePos);
+ SetPort(oldPort);
+
+ MousePositionNotify(NewMousePos);
+}
+
+LOCALPROC DisconnectKeyCodes3(void)
+{
+ DisconnectKeyCodes2();
+
+ MyMouseButtonSet(falseblnr);
+
+ ForceShowCursor();
+}
+
+
+/* --- time, date, location --- */
+
+#define dbglog_TimeStuff (0 && dbglog_HAVE)
+
+/*
+ be sure to avoid getting confused if TickCount
+ overflows and wraps.
+*/
+
+LOCALVAR ui5b TrueEmulatedTime = 0;
+ /*
+ The amount of time the program has
+ been running, measured in Macintosh
+ "ticks". There are 60.14742 ticks per
+ second.
+
+ (time when the emulation is
+ stopped for more than a few ticks
+ should not be counted.)
+ */
+
+LOCALVAR long int LastTime;
+
+LOCALPROC StartUpTimeAdjust(void)
+{
+ /*
+ prepare to call UpdateTrueEmulatedTime.
+
+ will be called again when haven't been
+ regularly calling UpdateTrueEmulatedTime,
+ (such as the emulation has been stopped).
+ */
+ LastTime = TickCount();
+}
+
+LOCALPROC UpdateTrueEmulatedTime(void)
+{
+ /*
+ Update TrueEmulatedTime. usually
+ need to convert between how the
+ host operating system measures
+ time and Macintosh ticks. But
+ not for this port.
+ */
+ long int LatestTime = TickCount();
+ si5b TimeDiff = LatestTime - LastTime;
+
+ if (TimeDiff != 0) {
+ LastTime = LatestTime;
+
+ if (TimeDiff >= 0) {
+ if (TimeDiff > 16) {
+ /* emulation interrupted, forget it */
+ ++TrueEmulatedTime;
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("emulation interrupted",
+ TrueEmulatedTime);
+#endif
+ } else {
+ TrueEmulatedTime += TimeDiff;
+ }
+ }
+ }
+}
+
+LOCALFUNC blnr CheckDateTime(void)
+{
+ /*
+ Update CurMacDateInSeconds, the number
+ of seconds since midnight January 1, 1904.
+
+ return true if CurMacDateInSeconds is
+ different than it was on the last
+ call to CheckDateTime.
+ */
+ ui5b NewMacDateInSecond;
+
+ NewMacDateInSecond = My_LMGetTime();
+ if (CurMacDateInSeconds != NewMacDateInSecond) {
+ CurMacDateInSeconds = NewMacDateInSecond;
+ return trueblnr;
+ } else {
+ return falseblnr;
+ }
+}
+
+LOCALFUNC blnr InitLocationDat(void)
+{
+#if AutoLocation || AutoTimeZone
+ MachineLocation loc;
+
+ ReadLocation(&loc);
+#if AutoLocation
+ CurMacLatitude = (ui5b)loc.latitude;
+ CurMacLongitude = (ui5b)loc.longitude;
+#endif
+#if AutoTimeZone
+ CurMacDelta = (ui5b)loc.u.gmtDelta;
+#endif
+#endif
+
+ (void) CheckDateTime();
+
+ return trueblnr;
+}
+
+/* --- sound --- */
+
+#if MySoundEnabled
+
+#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */
+#define kSoundBuffers (1 << kLn2SoundBuffers)
+#define kSoundBuffMask (kSoundBuffers - 1)
+
+#define DesiredMinFilledSoundBuffs 3
+ /*
+ if too big then sound lags behind emulation.
+ if too small then sound will have pauses.
+ */
+
+#define kLnOneBuffLen 9
+#define kLnAllBuffLen (kLn2SoundBuffers + kLnOneBuffLen)
+#define kOneBuffLen (1UL << kLnOneBuffLen)
+#define kAllBuffLen (1UL << kLnAllBuffLen)
+#define kLnOneBuffSz (kLnOneBuffLen + kLn2SoundSampSz - 3)
+#define kLnAllBuffSz (kLnAllBuffLen + kLn2SoundSampSz - 3)
+#define kOneBuffSz (1UL << kLnOneBuffSz)
+#define kAllBuffSz (1UL << kLnAllBuffSz)
+#define kOneBuffMask (kOneBuffLen - 1)
+#define kAllBuffMask (kAllBuffLen - 1)
+#define dbhBufferSize (kAllBuffSz + kOneBuffSz)
+
+#define dbglog_SoundStuff (0 && dbglog_HAVE)
+#define dbglog_SoundBuffStats (0 && dbglog_HAVE)
+
+LOCALVAR tpSoundSamp TheSoundBuffer = nullpr;
+volatile static ui4b ThePlayOffset;
+volatile static ui4b TheFillOffset;
+volatile static ui4b MinFilledSoundBuffs;
+#if dbglog_SoundBuffStats
+LOCALVAR ui4b MaxFilledSoundBuffs;
+#endif
+LOCALVAR ui4b TheWriteOffset;
+
+LOCALPROC MySound_Start0(void)
+{
+ /* Reset variables */
+ ThePlayOffset = 0;
+ TheFillOffset = 0;
+ TheWriteOffset = 0;
+ MinFilledSoundBuffs = kSoundBuffers + 1;
+#if dbglog_SoundBuffStats
+ MaxFilledSoundBuffs = 0;
+#endif
+}
+
+GLOBALOSGLUFUNC tpSoundSamp MySound_BeginWrite(ui4r n, ui4r *actL)
+{
+ ui4b ToFillLen = kAllBuffLen - (TheWriteOffset - ThePlayOffset);
+ ui4b WriteBuffContig =
+ kOneBuffLen - (TheWriteOffset & kOneBuffMask);
+
+ if (WriteBuffContig < n) {
+ n = WriteBuffContig;
+ }
+ if (ToFillLen < n) {
+ /* overwrite previous buffer */
+#if dbglog_SoundStuff
+ dbglog_writeln("sound buffer over flow");
+#endif
+ TheWriteOffset -= kOneBuffLen;
+ }
+
+ *actL = n;
+ return TheSoundBuffer + (TheWriteOffset & kAllBuffMask);
+}
+
+#if 4 == kLn2SoundSampSz
+LOCALPROC ConvertSoundBlockToNative(tpSoundSamp p)
+{
+ int i;
+
+ for (i = kOneBuffLen; --i >= 0; ) {
+ *p++ -= 0x8000;
+ }
+}
+#else
+#define ConvertSoundBlockToNative(p)
+#endif
+
+LOCALPROC MySound_WroteABlock(void)
+{
+#if (4 == kLn2SoundSampSz)
+ ui4b PrevWriteOffset = TheWriteOffset - kOneBuffLen;
+ tpSoundSamp p = TheSoundBuffer + (PrevWriteOffset & kAllBuffMask);
+#endif
+
+#if dbglog_SoundStuff
+ dbglog_writeln("enter MySound_WroteABlock");
+#endif
+
+ ConvertSoundBlockToNative(p);
+
+ TheFillOffset = TheWriteOffset;
+
+#if dbglog_SoundBuffStats
+ {
+ ui4b ToPlayLen = TheFillOffset
+ - ThePlayOffset;
+ ui4b ToPlayBuffs = ToPlayLen >> kLnOneBuffLen;
+
+ if (ToPlayBuffs > MaxFilledSoundBuffs) {
+ MaxFilledSoundBuffs = ToPlayBuffs;
+ }
+ }
+#endif
+}
+
+LOCALFUNC blnr MySound_EndWrite0(ui4r actL)
+{
+ blnr v;
+
+ TheWriteOffset += actL;
+
+ if (0 != (TheWriteOffset & kOneBuffMask)) {
+ v = falseblnr;
+ } else {
+ /* just finished a block */
+
+ MySound_WroteABlock();
+
+ v = trueblnr;
+ }
+
+ return v;
+}
+
+LOCALPROC MySound_SecondNotify0(void)
+{
+ if (MinFilledSoundBuffs <= kSoundBuffers) {
+ if (MinFilledSoundBuffs > DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too high");
+#endif
+ ++LastTime;
+ } else if (MinFilledSoundBuffs < DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too low");
+#endif
+ ++TrueEmulatedTime;
+ }
+#if dbglog_SoundBuffStats
+ dbglog_writelnNum("MinFilledSoundBuffs",
+ MinFilledSoundBuffs);
+ dbglog_writelnNum("MaxFilledSoundBuffs",
+ MaxFilledSoundBuffs);
+ MaxFilledSoundBuffs = 0;
+#endif
+ MinFilledSoundBuffs = kSoundBuffers + 1;
+ }
+}
+
+LOCALPROC RampSound(tpSoundSamp p,
+ trSoundSamp BeginVal, trSoundSamp EndVal)
+{
+ int i;
+ ui5r v = (((ui5r)BeginVal) << kLnOneBuffLen) + (kLnOneBuffLen >> 1);
+
+ for (i = kOneBuffLen; --i >= 0; ) {
+ *p++ = v >> kLnOneBuffLen;
+ v = v + EndVal - BeginVal;
+ }
+}
+
+#if 4 == kLn2SoundSampSz
+#define ConvertSoundSampleFromNative(v) ((v) + 0x8000)
+#else
+#define ConvertSoundSampleFromNative(v) (v)
+#endif
+
+struct MySoundR {
+ tpSoundSamp fTheSoundBuffer;
+ volatile ui4b (*fPlayOffset);
+ volatile ui4b (*fFillOffset);
+ volatile ui4b (*fMinFilledSoundBuffs);
+
+ volatile blnr PlayingBuffBlock;
+ volatile trSoundSamp lastv;
+ volatile blnr wantplaying;
+ volatile blnr StartingBlocks;
+
+ CmpSoundHeader /* ExtSoundHeader */ soundHeader;
+};
+typedef struct MySoundR MySoundR;
+
+
+/*
+ Some of this code descended from CarbonSndPlayDB, an
+ example from Apple, as found being used in vMac for Mac OS.
+*/
+
+LOCALPROC InsertSndDoCommand(SndChannelPtr chan, SndCommand * newCmd)
+{
+ if (-1 == chan->qHead) {
+ chan->qHead = chan->qTail;
+ }
+
+ if (1 <= chan->qHead) {
+ chan->qHead--;
+ } else {
+ chan->qHead = chan->qTail;
+ }
+
+ chan->queue[chan->qHead] = *newCmd;
+}
+
+/* call back */ static pascal void
+MySound_CallBack(SndChannelPtr theChannel, SndCommand * theCallBackCmd)
+{
+ MySoundR *datp =
+ (MySoundR *)(theCallBackCmd->param2);
+ blnr wantplaying0 = datp->wantplaying;
+ trSoundSamp v0 = datp->lastv;
+
+#if dbglog_SoundStuff
+ dbglog_writeln("Enter MySound_CallBack");
+#endif
+
+ if (datp->PlayingBuffBlock) {
+ /* finish with last sample */
+#if dbglog_SoundStuff
+ dbglog_writeln("done with sample");
+#endif
+
+ *datp->fPlayOffset += kOneBuffLen;
+ datp->PlayingBuffBlock = falseblnr;
+ }
+
+ if ((! wantplaying0) && (kCenterSound == v0)) {
+#if dbglog_SoundStuff
+ dbglog_writeln("terminating");
+#endif
+ } else {
+ SndCommand playCmd;
+ tpSoundSamp p;
+ trSoundSamp v1 = v0;
+ blnr WantRamp = falseblnr;
+ ui4b CurPlayOffset = *datp->fPlayOffset;
+ ui4b ToPlayLen = *datp->fFillOffset - CurPlayOffset;
+ ui4b FilledSoundBuffs = ToPlayLen >> kLnOneBuffLen;
+
+ if (FilledSoundBuffs < *datp->fMinFilledSoundBuffs) {
+ *datp->fMinFilledSoundBuffs = FilledSoundBuffs;
+ }
+
+ if (! wantplaying0) {
+#if dbglog_SoundStuff
+ dbglog_writeln("playing end transistion");
+#endif
+ v1 = kCenterSound;
+
+ WantRamp = trueblnr;
+ } else
+ if (datp->StartingBlocks) {
+#if dbglog_SoundStuff
+ dbglog_writeln("playing start block");
+#endif
+
+ if ((ToPlayLen >> kLnOneBuffLen) < 12) {
+ datp->StartingBlocks = falseblnr;
+#if dbglog_SoundStuff
+ dbglog_writeln("have enough samples to start");
+#endif
+
+ p = datp->fTheSoundBuffer
+ + (CurPlayOffset & kAllBuffMask);
+ v1 = ConvertSoundSampleFromNative(*p);
+ }
+
+ WantRamp = trueblnr;
+ } else
+ if (0 == FilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("playing under run");
+#endif
+
+ WantRamp = trueblnr;
+ } else
+ {
+ /* play next sample */
+ p = datp->fTheSoundBuffer
+ + (CurPlayOffset & kAllBuffMask);
+ datp->PlayingBuffBlock = trueblnr;
+ v1 =
+ ConvertSoundSampleFromNative(*(p + kOneBuffLen - 1));
+#if dbglog_SoundStuff
+ dbglog_writeln("playing sample");
+#endif
+ }
+
+ if (WantRamp) {
+ p = datp->fTheSoundBuffer + kAllBuffLen;
+
+#if dbglog_SoundStuff
+ dbglog_writelnNum("v0", v0);
+ dbglog_writelnNum("v1", v1);
+#endif
+
+ RampSound(p, v0, v1);
+ ConvertSoundBlockToNative(p);
+ }
+
+ datp->soundHeader.samplePtr = (Ptr)p;
+ datp->soundHeader.numFrames =
+ (unsigned long)kOneBuffLen;
+
+ /* Insert our callback command */
+ InsertSndDoCommand (theChannel, theCallBackCmd);
+
+#if 0
+ {
+ int i;
+ tpSoundSamp pS =
+ (tpSoundSamp)datp->soundHeader.samplePtr;
+
+ for (i = datp->soundHeader.numFrames; --i >= 0; )
+ {
+ fprintf(stderr, "%d\n", *pS++);
+ }
+ }
+#endif
+
+ /* Play the next buffer */
+ playCmd.cmd = bufferCmd;
+ playCmd.param1 = 0;
+ playCmd.param2 = (long)&(datp->soundHeader);
+ InsertSndDoCommand (theChannel, &playCmd);
+
+ datp->lastv = v1;
+ }
+}
+
+LOCALVAR MySoundR cur_audio;
+
+LOCALVAR SndCallBackUPP gCarbonSndPlayDoubleBufferCallBackUPP = NULL;
+
+LOCALVAR SndChannelPtr sndChannel = NULL; /* our sound channel */
+
+LOCALPROC MySound_Start(void)
+{
+ if (NULL == sndChannel)
+#if HaveCPUfamM68K
+ if (HaveSndMngrAvail())
+#endif
+ {
+ SndCommand callBack;
+ SndChannelPtr chan = NULL;
+
+ cur_audio.wantplaying = falseblnr;
+ cur_audio.StartingBlocks = falseblnr;
+
+ MySound_Start0();
+
+ SndNewChannel(&chan, sampledSynth, initMono, nil);
+ if (NULL != chan) {
+ sndChannel = chan;
+
+ cur_audio.PlayingBuffBlock = falseblnr;
+ cur_audio.lastv = kCenterSound;
+ cur_audio.StartingBlocks = trueblnr;
+ cur_audio.wantplaying = trueblnr;
+
+ callBack.cmd = callBackCmd;
+ callBack.param1 = 0; /* unused */
+ callBack.param2 = (long)&cur_audio;
+
+ sndChannel->callBack =
+ gCarbonSndPlayDoubleBufferCallBackUPP;
+
+ (void) SndDoCommand (sndChannel, &callBack, true);
+ }
+ }
+}
+
+#define IgnorableEventMask \
+ (mUpMask | keyDownMask | keyUpMask | autoKeyMask)
+
+LOCALPROC MySound_Stop(void)
+{
+#if dbglog_SoundStuff
+ dbglog_writeln("enter MySound_Stop");
+#endif
+
+ if (NULL != sndChannel) {
+ ui4r retry_limit = 50; /* half of a second */
+ SCStatus r;
+
+ cur_audio.wantplaying = falseblnr;
+#if dbglog_SoundStuff
+ dbglog_writeln("cleared wantplaying");
+#endif
+
+label_retry:
+ r.scChannelBusy = falseblnr; /* what is this for? */
+ if (noErr != SndChannelStatus(sndChannel,
+ sizeof(SCStatus), &r))
+ {
+ /* fail */
+ } else
+ if ((! r.scChannelBusy) && (kCenterSound == cur_audio.lastv)) {
+ /* done */
+
+ /*
+ observed reporting not busy unexpectedly,
+ so also check lastv.
+ */
+ } else
+ if (0 == --retry_limit) {
+#if dbglog_SoundStuff
+ dbglog_writeln("retry limit reached");
+#endif
+ /*
+ don't trust SndChannelStatus, make
+ sure don't get in infinite loop.
+ */
+
+ /* done */
+ } else
+ {
+ /*
+ give time back, particularly important
+ if got here on a suspend event.
+ */
+ EventRecord theEvent;
+
+#if dbglog_SoundStuff
+ dbglog_writeln("busy, so sleep");
+#endif
+
+#if HaveCPUfamM68K
+ if (! HaveWaitNextEventAvail()) {
+ (void) GetNextEvent(IgnorableEventMask, &theEvent);
+ } else
+#endif
+ {
+ (void) WaitNextEvent(IgnorableEventMask,
+ &theEvent, 1, NULL);
+ }
+ goto label_retry;
+ }
+
+ SndDisposeChannel(sndChannel, true);
+ sndChannel = NULL;
+ }
+
+#if dbglog_SoundStuff
+ dbglog_writeln("leave MySound_Stop");
+#endif
+}
+
+#define SOUND_SAMPLERATE rate22khz
+ /* = 0x56EE8BA3 = (7833600 * 2 / 704) << 16 */
+
+LOCALFUNC blnr MySound_Init(void)
+{
+#if dbglog_SoundStuff
+ dbglog_writeln("enter MySound_Init");
+#endif
+
+ cur_audio.fTheSoundBuffer = TheSoundBuffer;
+
+ cur_audio.fPlayOffset = &ThePlayOffset;
+ cur_audio.fFillOffset = &TheFillOffset;
+ cur_audio.fMinFilledSoundBuffs = &MinFilledSoundBuffs;
+ cur_audio.wantplaying = falseblnr;
+
+ /* Init basic per channel information */
+ cur_audio.soundHeader.sampleRate = SOUND_SAMPLERATE;
+ /* sample rate */
+ cur_audio.soundHeader.numChannels = 1; /* one channel */
+ cur_audio.soundHeader.loopStart = 0;
+ cur_audio.soundHeader.loopEnd = 0;
+ cur_audio.soundHeader.encode = cmpSH /* extSH */;
+ cur_audio.soundHeader.baseFrequency = kMiddleC;
+ cur_audio.soundHeader.numFrames =
+ (unsigned long)kOneBuffLen;
+ /* cur_audio.soundHeader.AIFFSampleRate = 0; */
+ /* unused */
+ cur_audio.soundHeader.markerChunk = nil;
+ cur_audio.soundHeader.futureUse2 = 0;
+ cur_audio.soundHeader.stateVars = nil;
+ cur_audio.soundHeader.leftOverSamples = nil;
+ cur_audio.soundHeader.compressionID = 0;
+ /* no compression */
+ cur_audio.soundHeader.packetSize = 0;
+ /* no compression */
+ cur_audio.soundHeader.snthID = 0;
+ cur_audio.soundHeader.sampleSize = (1 << kLn2SoundSampSz);
+ /* 8 or 16 bits per sample */
+ cur_audio.soundHeader.sampleArea[0] = 0;
+#if 3 == kLn2SoundSampSz
+ cur_audio.soundHeader.format = kSoundNotCompressed;
+#elif 4 == kLn2SoundSampSz
+ cur_audio.soundHeader.format = k16BitNativeEndianFormat;
+#else
+#error "unsupported kLn2SoundSampSz"
+#endif
+ cur_audio.soundHeader.samplePtr = (Ptr)TheSoundBuffer;
+
+ gCarbonSndPlayDoubleBufferCallBackUPP =
+ NewSndCallBackUPP(MySound_CallBack);
+ if (gCarbonSndPlayDoubleBufferCallBackUPP != NULL) {
+
+ MySound_Start();
+ /*
+ This should be taken care of by LeaveSpeedStopped,
+ but since takes a while to get going properly,
+ start early.
+ */
+
+ return trueblnr;
+ }
+ return falseblnr;
+}
+
+GLOBALOSGLUPROC MySound_EndWrite(ui4r actL)
+{
+ if (MySound_EndWrite0(actL)) {
+ }
+}
+
+LOCALPROC MySound_SecondNotify(void)
+{
+ if (sndChannel != NULL) {
+ MySound_SecondNotify0();
+ }
+}
+
+#endif
+
+#if MayFullScreen
+LOCALPROC AdjustMachineGrab(void)
+{
+#if EnableFSMouseMotion
+ AdjustMouseMotionGrab();
+#endif
+#if 0
+ AdjustMainScreenGrab();
+#endif
+}
+#endif
+
+#if MayFullScreen
+LOCALPROC UngrabMachine(void)
+{
+ GrabMachine = falseblnr;
+ AdjustMachineGrab();
+}
+#endif
+
+/* --- basic dialogs --- */
+
+LOCALPROC NativeStrFromCStr(ps3p r, char *s, blnr AddEllipsis)
+{
+ int i;
+ int L;
+ ui3b ps[ClStrMaxLength];
+
+ ClStrFromSubstCStr(&L, ps, s);
+ if (AddEllipsis) {
+ ClStrAppendChar(&L, ps, kCellEllipsis);
+ }
+
+ if (L > 255) {
+ L = 255;
+ }
+
+ for (i = 0; i < L; ++i) {
+ r[i + 1] = Cell2MacAsciiMap[ps[i]];
+ }
+
+ r[0] = L;
+}
+
+#ifndef HogCPU
+#define HogCPU 1
+#endif
+
+#if HogCPU
+LOCALVAR long NoEventsCounter = 0;
+#endif
+
+LOCALVAR blnr gBackgroundFlag = falseblnr;
+LOCALVAR blnr gTrueBackgroundFlag = falseblnr;
+LOCALVAR blnr CurSpeedStopped = trueblnr;
+
+LOCALVAR blnr ADialogIsUp = falseblnr;
+
+LOCALPROC MyBeginDialog(void)
+{
+ DisconnectKeyCodes3();
+ ADialogIsUp = trueblnr;
+#if MayFullScreen
+ UngrabMachine();
+#endif
+}
+
+LOCALPROC MyEndDialog(void)
+{
+#if HogCPU
+ NoEventsCounter = 0;
+#endif
+ ADialogIsUp = falseblnr;
+ ReconnectKeyCodes3();
+}
+
+
+#define kMyStandardAlert 128
+
+LOCALPROC CheckSavedMacMsg(void)
+{
+ /*
+ This is currently only used in the
+ rare case where there is a message
+ still pending as the program quits.
+ */
+ Str255 briefMsgp;
+ Str255 longMsgp;
+
+ if (nullpr != SavedBriefMsg) {
+ NativeStrFromCStr(briefMsgp, SavedBriefMsg, falseblnr);
+ NativeStrFromCStr(longMsgp, SavedLongMsg, falseblnr);
+#if AppearanceAvail
+ if (HaveAppearanceAvail()) {
+ AlertStdAlertParamRec param;
+ short itemHit;
+
+ param.movable = 0;
+ param.filterProc = nil;
+ param.defaultText = "\pOK";
+ param.cancelText = nil;
+ param.otherText = nil;
+ param.helpButton = false;
+ param.defaultButton = kAlertStdAlertOKButton;
+ param.cancelButton = 0;
+ param.position = kWindowDefaultPosition;
+
+ StandardAlert(
+ (SavedFatalMsg) ? kAlertStopAlert : kAlertCautionAlert,
+ briefMsgp, longMsgp, ¶m, &itemHit);
+ } else
+#endif
+ {
+ ParamText(briefMsgp, longMsgp, "\p", "\p");
+ if (SavedFatalMsg) {
+ while (StopAlert(kMyStandardAlert, NULL) != 1) {
+ }
+ } else {
+ while (CautionAlert(kMyStandardAlert, NULL) != 1) {
+ }
+ }
+ /* Alert (kMyStandardAlert, 0L); */
+ }
+
+ SavedBriefMsg = nullpr;
+ }
+}
+
+/* --- hide/show menubar --- */
+
+#if MayFullScreen
+#if MightNotHaveWindows85Avail
+LOCALVAR RgnHandle GrayRgnSave = NULL;
+LOCALVAR short mBarHeightSave;
+#endif
+#endif
+
+#if MayFullScreen
+LOCALPROC My_HideMenuBar(void)
+{
+#if Windows85APIAvail
+ if (HaveHideShowMenuAvail()) {
+ if (IsMenuBarVisible()) {
+ HideMenuBar();
+ }
+ } else
+#endif
+ {
+#if MightNotHaveWindows85Avail
+ if (NULL == GrayRgnSave) {
+ RgnHandle mBarRgn = NewRgn();
+ if (mBarRgn != NULL) {
+ GrayRgnSave = NewRgn();
+ if (GrayRgnSave != NULL) {
+ CopyRgn(My_GetGrayRgn(), GrayRgnSave);
+ RectRgn(mBarRgn, &qd.screenBits.bounds);
+ DiffRgn(mBarRgn, My_GetGrayRgn(), mBarRgn);
+ /*
+ menu bar rgn, plus corner areas
+ of main screen
+ */
+ mBarHeightSave = My_LMGetMBarHeight();
+ LMSetMBarHeight(0);
+ UnionRgn(My_GetGrayRgn(), mBarRgn, My_GetGrayRgn());
+ PaintBehind(LMGetWindowList(), mBarRgn);
+ CalcVisBehind(LMGetWindowList(), mBarRgn);
+#if 0
+ controlStripHidden = false;
+ if (noErr == Gestalt(
+ gestaltControlStripVersion, &result))
+ {
+ if (SBIsControlStripVisible()) {
+ controlStripHidden = true;
+ SBShowHideControlStrip(false);
+ }
+ }
+#endif
+ }
+ DisposeRgn(mBarRgn);
+ }
+ }
+#endif
+ }
+}
+#endif
+
+#if MayFullScreen
+LOCALPROC My_ShowMenuBar(void)
+{
+#if Windows85APIAvail
+ if (HaveHideShowMenuAvail()) {
+ if (! IsMenuBarVisible()) {
+ ShowMenuBar();
+ }
+ } else
+#endif
+ {
+#if MightNotHaveWindows85Avail
+ if (GrayRgnSave != NULL) {
+ LMSetMBarHeight(mBarHeightSave);
+ CopyRgn(GrayRgnSave, My_GetGrayRgn());
+ /*
+ PaintBehind(LMGetWindowList(), GrayRgnSave);
+ CalcVisBehind(LMGetWindowList(), GrayRgnSave);
+ */
+ DisposeRgn(GrayRgnSave);
+ DrawMenuBar();
+ GrayRgnSave = NULL;
+#if 0
+ if (controlStripHidden) {
+ controlStripHidden = falseblnr;
+ if (noErr ==
+ Gestalt(gestaltControlStripVersion, &result))
+ {
+ SBShowHideControlStrip(true);
+ }
+ }
+#endif
+ }
+#endif
+ }
+}
+#endif
+
+#if IncludePbufs
+LOCALVAR Handle PbufDat[NumPbufs];
+#endif
+
+#if IncludePbufs
+LOCALFUNC tMacErr PbufNewFromHandle(Handle h, ui5b count, tPbuf *r)
+{
+ tPbuf i;
+ tMacErr err;
+
+ if (! FirstFreePbuf(&i)) {
+ DisposeHandle(h);
+ err = mnvm_miscErr;
+ } else {
+ *r = i;
+ PbufDat[i] = h;
+ PbufNewNotify(i, count);
+ err = mnvm_noErr;
+ }
+
+ return err;
+}
+#endif
+
+#if IncludePbufs
+GLOBALOSGLUFUNC tMacErr PbufNew(ui5b count, tPbuf *r)
+{
+ Handle h;
+ tMacErr err = mnvm_miscErr;
+
+ h = NewHandleClear(count);
+ if (h != NULL) {
+ err = PbufNewFromHandle(h, count, r);
+ }
+
+ return err;
+}
+#endif
+
+#if IncludePbufs
+GLOBALOSGLUPROC PbufDispose(tPbuf i)
+{
+ DisposeHandle(PbufDat[i]);
+ PbufDisposeNotify(i);
+}
+#endif
+
+#if IncludePbufs
+LOCALPROC UnInitPbufs(void)
+{
+ tPbuf i;
+
+ for (i = 0; i < NumPbufs; ++i) {
+ if (PbufIsAllocated(i)) {
+ PbufDispose(i);
+ }
+ }
+}
+#endif
+
+#if IncludePbufs
+#define PbufHaveLock 1
+#endif
+
+#if IncludePbufs
+LOCALFUNC ui3p PbufLock(tPbuf i)
+{
+ ui3p p;
+
+ Handle h = PbufDat[i];
+
+ if (NULL == h) {
+ p = nullpr;
+ } else {
+ HLock(h);
+ p = (ui3p)*h;
+ }
+
+ return p;
+}
+#endif
+
+#if IncludePbufs
+LOCALPROC PbufUnlock(tPbuf i)
+{
+ HUnlock(PbufDat[i]);
+}
+#endif
+
+#if IncludePbufs
+GLOBALOSGLUPROC PbufTransfer(ui3p Buffer,
+ tPbuf i, ui5r offset, ui5r count, blnr IsWrite)
+{
+ Handle h = PbufDat[i];
+
+ HLock(h);
+ {
+ void *p = ((ui3p)*h) + offset;
+ if (IsWrite) {
+ BlockMove(Buffer, p, count);
+ } else {
+ BlockMove(p, Buffer, count);
+ }
+ }
+ HUnlock(h);
+}
+#endif
+
+/* --- clipboard --- */
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEexport(tPbuf i)
+{
+ /*
+ PBuf i is an array of macintosh
+ style characters. (using the
+ MacRoman character set.)
+
+ Should export this Buffer to the
+ native clipboard, performing character
+ set translation, and eof character translation
+ as needed. (Not needed for this port.)
+
+ return 0 if it succeeds, nonzero (a
+ Macintosh style error code, but -1
+ will do) on failure.
+ */
+ OSErr err;
+
+ err = ZeroScrap();
+ if (noErr == err) {
+ ui5b L = PbufSize[i];
+ Handle h = PbufDat[i];
+ HLock(h);
+ err = PutScrap(L, 'TEXT', *h);
+ HUnlock(h);
+ }
+
+ PbufDispose(i);
+
+ return (tMacErr)err;
+}
+#endif
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEimport(tPbuf *r)
+{
+ /*
+ Import the native clipboard as text,
+ and convert it to Macintosh format,
+ in a Pbuf.
+
+ return 0 if it succeeds, nonzero (a
+ Macintosh style error code, but -1
+ will do) on failure.
+ */
+
+ long off;
+ long v;
+ Handle h;
+ OSErr err = (OSErr)mnvm_miscErr;
+
+ h = NewHandle(0);
+ if (h != NULL) {
+ v = GetScrap(h, 'TEXT', &off);
+ if (v < 0) {
+ err = v;
+ } else {
+ err = (OSErr)PbufNewFromHandle(h, v, r);
+ h = NULL;
+ }
+ if (NULL != h) {
+ DisposeHandle(h);
+ }
+ }
+
+ return (tMacErr)err;
+}
+#endif
+
+/* --- drives --- */
+
+LOCALVAR short Drives[NumDrives]; /* open disk image files */
+#if (IncludeSonyGetName || IncludeSonyNew) && HaveCPUfamM68K
+LOCALVAR Handle DriveNames[NumDrives];
+#endif
+
+LOCALPROC InitDrives(void)
+{
+ /*
+ This isn't really needed, Drives[i] and DriveNames[i]
+ need not have valid values when not vSonyIsInserted[i].
+ */
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ Drives[i] = NotAfileRef;
+#if (IncludeSonyGetName || IncludeSonyNew) && HaveCPUfamM68K
+ DriveNames[i] = NULL;
+#endif
+ }
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer,
+ tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
+ ui5r *Sony_ActCount)
+{
+ /*
+ return 0 if it succeeds, nonzero (a
+ Macintosh style error code, but -1
+ will do) on failure.
+ */
+ tMacErr result;
+ ui5r NewSony_Count = Sony_Count;
+
+ result =
+ (tMacErr)SetFPos(Drives[Drive_No], fsFromStart, Sony_Start);
+ if (mnvm_noErr == result) {
+ if (IsWrite) {
+ /*
+ write Sony_Count bytes from Buffer, to disk image
+ number Drive_No, starting at offset Sony_Start.
+ */
+
+ result = (tMacErr)FSWrite(Drives[Drive_No],
+ (long *)&NewSony_Count, Buffer);
+ } else {
+ /*
+ read Sony_Count bytes into Buffer, from disk image
+ number Drive_No, starting at offset Sony_Start.
+ */
+
+ result = (tMacErr)FSRead(Drives[Drive_No],
+ (long *)&NewSony_Count, Buffer);
+ }
+ }
+
+ if (nullpr != Sony_ActCount) {
+ *Sony_ActCount = NewSony_Count;
+ }
+
+ return result;
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count)
+{
+ /*
+ set Sony_Count to the size of disk image number Drive_No.
+
+ return 0 if it succeeds, nonzero (a
+ Macintosh style error code, but -1
+ will do) on failure.
+ */
+ return GetEOF(Drives[Drive_No], (long *)Sony_Count);
+}
+
+LOCALFUNC OSErr vSonyEject0(tDrive Drive_No)
+{
+ /*
+ close disk image number Drive_No.
+
+ return 0 if it succeeds, nonzero (a
+ Macintosh style error code, but -1
+ will do) on failure.
+ */
+ short refnum = Drives[Drive_No];
+ Drives[Drive_No] = NotAfileRef; /* not really needed */
+
+ DiskEjectedNotify(Drive_No);
+
+#if (IncludeSonyGetName || IncludeSonyNew) && HaveCPUfamM68K
+ {
+ Handle h = DriveNames[Drive_No];
+ if (NULL != h) {
+ DisposeHandle(h);
+ DriveNames[Drive_No] = NULL; /* not really needed */
+ }
+ }
+#endif
+
+ return FSClose(refnum);
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No)
+{
+ OSErr result;
+ short vRefNum;
+ blnr DidEject = falseblnr;
+ short refnum = Drives[Drive_No];
+
+ result = GetVRefNum(refnum, &vRefNum);
+ if (noErr == result) {
+ DidEject = trueblnr;
+ result = vSonyEject0(Drive_No);
+ (void) FlushVol(NULL, vRefNum);
+ }
+
+ if (! DidEject) {
+ result = vSonyEject0(Drive_No);
+ }
+
+ return (tMacErr)result;
+}
+
+#if IncludeSonyNew
+GLOBALOSGLUFUNC tMacErr vSonyEjectDelete(tDrive Drive_No)
+{
+ OSErr result;
+ Str255 s;
+ blnr DidEject = falseblnr;
+ short refnum = Drives[Drive_No];
+
+#if HaveCPUfamM68K
+ if (! HaveFSSpecCallsAvail()) {
+ Handle h = DriveNames[Drive_No];
+ if (NULL != h) {
+ short vRefNum;
+ result = GetVRefNum(refnum, &vRefNum);
+ if (noErr == result) {
+ PStrFromHandle(s, h, 255);
+ result = vSonyEject0(Drive_No);
+ DidEject = trueblnr;
+ (void) FSDelete(s, vRefNum);
+ }
+ }
+ } else
+#endif
+ {
+ FCBPBRec b;
+
+ b.ioCompletion = NULL;
+ b.ioNamePtr = (StringPtr)s;
+ b.ioVRefNum = 0;
+ b.ioRefNum = refnum;
+ b.ioFCBIndx = 0;
+ result = PBGetFCBInfoSync(&b);
+ if (noErr == result) {
+ FSSpec spec;
+ result = FSMakeFSSpec(b.ioFCBVRefNum, b.ioFCBParID,
+ s, &spec);
+ if (noErr == result) {
+ result = vSonyEject0(Drive_No);
+ DidEject = trueblnr;
+ (void) FSpDelete(&spec);
+ }
+ }
+ }
+
+ if (! DidEject) {
+ (void) vSonyEject0(Drive_No);
+ }
+
+ return (tMacErr)result;
+}
+#endif
+
+LOCALPROC UnInitDrives(void)
+{
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ if (vSonyIsInserted(i)) {
+ (void) vSonyEject(i);
+ }
+ }
+}
+
+#if IncludeSonyGetName
+GLOBALOSGLUFUNC tMacErr vSonyGetName(tDrive Drive_No, tPbuf *r)
+{
+ FCBPBRec b;
+ Str255 s;
+ tMacErr err = mnvm_miscErr;
+
+#if HaveCPUfamM68K
+ if (! HaveFSSpecCallsAvail()) {
+ Handle h = DriveNames[Drive_No];
+ if (NULL != h) {
+ PStrFromHandle(s, h, 255);
+ err = mnvm_noErr;
+ }
+ } else
+#endif
+ {
+ b.ioCompletion = NULL;
+ b.ioNamePtr = (StringPtr)s;
+ b.ioVRefNum = 0;
+ b.ioRefNum = Drives[Drive_No];
+ b.ioFCBIndx = 0;
+ err = To_tMacErr(PBGetFCBInfoSync(&b));
+ }
+
+ if (mnvm_noErr == err) {
+ Handle h;
+ err = PStrToHand(s, &h);
+ if (noErr == err) {
+ err = PbufNewFromHandle(h, s[0], r);
+ }
+ }
+
+ return err;
+}
+#endif
+
+LOCALFUNC tMacErr Sony_Insert0(short refnum, blnr locked, ps3p s)
+{
+ /*
+ Given reference to open file, mount it as
+ a disk image file. if "locked", then mount
+ it as a locked disk.
+ */
+
+ tDrive Drive_No;
+
+#if ! ((IncludeSonyGetName || IncludeSonyNew) && HaveCPUfamM68K)
+ UnusedParam(s);
+#endif
+
+ if (! FirstFreeDisk(&Drive_No)) {
+ (void) FSClose(refnum);
+ return mnvm_tmfoErr; /* too many files open */
+ } else {
+ Drives[Drive_No] = refnum;
+ DiskInsertNotify(Drive_No, locked);
+#if (IncludeSonyGetName || IncludeSonyNew) && HaveCPUfamM68K
+ if (s != NULL) {
+ Handle h;
+
+ if (mnvm_noErr != PStrToHand(s, &h)) {
+ h = NULL;
+ }
+ DriveNames[Drive_No] = h;
+ }
+#endif
+ return mnvm_noErr;
+ }
+}
+
+LOCALPROC ReportStandardOpenDiskError(tMacErr err)
+{
+ if (mnvm_noErr != err) {
+ if (mnvm_tmfoErr == err) {
+ MacMsg(kStrTooManyImagesTitle,
+ kStrTooManyImagesMessage, falseblnr);
+ } else if (mnvm_opWrErr == err) {
+ MacMsg(kStrImageInUseTitle,
+ kStrImageInUseMessage, falseblnr);
+ } else {
+ MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
+ }
+ }
+}
+
+LOCALFUNC tMacErr InsertADiskFromFileRef(FSSpec *spec)
+{
+ short refnum;
+ tMacErr err;
+ blnr locked = falseblnr;
+
+ err = To_tMacErr(FSpOpenDF(spec, fsRdWrPerm, &refnum));
+ switch (err) {
+ case mnvm_permErr:
+ case mnvm_wrPermErr:
+ case mnvm_afpAccessDenied:
+ locked = trueblnr;
+ err = To_tMacErr(FSpOpenDF(spec, fsRdPerm, &refnum));
+ break;
+ default:
+ break;
+ }
+ if (mnvm_noErr == err) {
+ err = Sony_Insert0(refnum, locked, NULL);
+ }
+
+ return err;
+}
+
+#if HaveCPUfamM68K
+LOCALFUNC tMacErr InsertADiskFromNamevRef(ConstStr255Param fileName,
+ short vRefNum)
+{
+ ParamBlockRec R;
+ tMacErr err;
+ blnr locked = falseblnr;
+
+ R.ioParam.ioCompletion = NULL;
+ R.ioParam.ioNamePtr = (StringPtr)fileName;
+ R.ioParam.ioVRefNum = vRefNum;
+ R.ioParam.ioVersNum = 0;
+ R.ioParam.ioPermssn = fsRdWrPerm;
+ R.ioParam.ioMisc = NULL;
+ err = To_tMacErr(PBOpen(&R, false));
+ switch (err) {
+ case mnvm_permErr:
+ case mnvm_wrPermErr:
+ case mnvm_afpAccessDenied:
+ locked = trueblnr;
+ R.ioParam.ioPermssn = fsRdPerm;
+ err = To_tMacErr(PBOpen(&R, false));
+ break;
+ default:
+ break;
+ }
+ if (mnvm_noErr == err) {
+ err = Sony_Insert0(R.ioParam.ioRefNum, locked, (ps3p)fileName);
+ }
+
+ return err;
+}
+#endif
+
+LOCALFUNC tMacErr LoadMacRomFromRefNum(short refnum)
+{
+ /*
+ load the ROM image file into ptr ROM
+ */
+ tMacErr err;
+ long count = kROM_Size;
+
+ if (mnvm_noErr != (err = To_tMacErr(
+ FSRead(refnum, &count, ROM))))
+ {
+ if (mnvm_eofErr == err) {
+ MacMsgOverride(kStrShortROMTitle, kStrShortROMMessage);
+ } else {
+ MacMsgOverride(kStrNoReadROMTitle, kStrNoReadROMMessage);
+ }
+ } else
+ {
+ err = ROM_IsValid();
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr LoadMacRomFromFSSpec(FSSpec *spec)
+{
+ tMacErr err;
+ short refnum;
+
+ if (mnvm_noErr == (err =
+ To_tMacErr(FSpOpenDF(spec, fsRdPerm, &refnum))))
+ {
+ err = LoadMacRomFromRefNum(refnum);
+ (void) FSClose(refnum);
+ }
+
+ return err;
+}
+
+#if HaveCPUfamM68K
+LOCALFUNC tMacErr LoadMacRomFromNamevRef(ConstStr255Param fileName,
+ short vRefNum)
+{
+ tMacErr err;
+ ParamBlockRec R;
+
+ R.ioParam.ioCompletion = NULL;
+ R.ioParam.ioNamePtr = (StringPtr)fileName;
+ R.ioParam.ioVRefNum = vRefNum;
+ R.ioParam.ioVersNum = 0;
+ R.ioParam.ioPermssn = fsRdPerm;
+ R.ioParam.ioMisc = NULL;
+ if (mnvm_noErr == (err = To_tMacErr(PBOpen(&R, false)))) {
+ err = LoadMacRomFromRefNum(R.ioParam.ioRefNum);
+ (void) FSClose(R.ioParam.ioRefNum);
+ }
+
+ return err;
+}
+#endif
+
+#if HaveCPUfamM68K
+LOCALFUNC tMacErr InsertADiskFromNamevRef1(ConstStr255Param fileName,
+ short vRefNum)
+{
+ tMacErr err;
+
+ if (! ROM_loaded) {
+ err = LoadMacRomFromNamevRef(fileName, vRefNum);
+ } else {
+ err = InsertADiskFromNamevRef(fileName, vRefNum);
+ }
+
+ return err;
+}
+#endif
+
+LOCALFUNC tMacErr InsertADiskOrAliasFromSpec(FSSpec *spec,
+ blnr MaybeROM, blnr MaybeAlias)
+{
+ Boolean isFolder;
+ Boolean isAlias;
+ tMacErr err;
+
+ if ((! MaybeAlias)
+ || CheckSaveMacErr(ResolveAliasFile(spec, true,
+ &isFolder, &isAlias)))
+ {
+ if (MaybeROM && ! ROM_loaded) {
+ err = LoadMacRomFromFSSpec(spec);
+ } else {
+ err = InsertADiskFromFileRef(spec);
+ }
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr InsertDisksFromDocList(AEDescList *docList)
+{
+ tMacErr err = mnvm_noErr;
+ long itemsInList;
+ long index;
+ AEKeyword keyword;
+ DescType typeCode;
+ FSSpec spec;
+ Size actualSize;
+
+ if (CheckSaveMacErr(AECountItems(docList, &itemsInList))) {
+ for (index = 1; index <= itemsInList; ++index) {
+ if (CheckSaveMacErr(AEGetNthPtr(docList, index, typeFSS,
+ &keyword, &typeCode, (Ptr)&spec, sizeof(FSSpec),
+ &actualSize)))
+ if (CheckSavetMacErr(InsertADiskOrAliasFromSpec(&spec,
+ trueblnr, falseblnr)))
+ {
+ }
+ if (mnvm_noErr != err) {
+ goto label_fail;
+ }
+ }
+ }
+
+label_fail:
+ return err;
+}
+
+LOCALFUNC tMacErr InsertADiskFromNameEtc(MyDir_R *d,
+ ConstStr255Param fileName)
+{
+ tMacErr err;
+
+#if HaveCPUfamM68K
+ if (! HaveFSSpecCallsAvail()) {
+ err = InsertADiskFromNamevRef(fileName, d->VRefNum);
+ } else
+#endif
+ {
+ FSSpec spec;
+
+ if (CheckSaveMacErr(
+ FSMakeFSSpec(d->VRefNum, d->DirId, fileName, &spec)))
+ {
+ err = InsertADiskOrAliasFromSpec(&spec,
+ falseblnr, trueblnr);
+ }
+ }
+
+ return err;
+}
+
+#if NavigationAvail
+pascal Boolean NavigationFilterProc(
+ AEDesc* theItem, void* info, void* NavCallBackUserData,
+ NavFilterModes theNavFilterModes);
+pascal Boolean NavigationFilterProc(
+ AEDesc* theItem, void* info, void* NavCallBackUserData,
+ NavFilterModes theNavFilterModes)
+{
+ Boolean display = true;
+ NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*)info;
+ UnusedParam(theNavFilterModes);
+ UnusedParam(NavCallBackUserData);
+
+ if (typeFSS == theItem->descriptorType) {
+ if (! theInfo->isFolder) {
+ /*
+ use:
+ 'theInfo->fileAndFolder.fileInfo.finderInfo.fdType'
+ to check for the file type you want to filter.
+ */
+ }
+ }
+ return display;
+}
+#endif
+
+
+#if NavigationAvail
+pascal void NavigationEventProc(
+ NavEventCallbackMessage callBackSelector,
+ NavCBRecPtr callBackParms, void *NavCallBackUserData);
+pascal void NavigationEventProc(
+ NavEventCallbackMessage callBackSelector,
+ NavCBRecPtr callBackParms, void *NavCallBackUserData)
+{
+ UnusedParam(NavCallBackUserData);
+
+ if (kNavCBEvent == callBackSelector) {
+ switch (callBackParms->eventData.eventDataParms.event->what) {
+ case updateEvt:
+ {
+ WindowPtr which =
+ (WindowPtr)callBackParms
+ ->eventData.eventDataParms.event
+ ->message;
+
+ BeginUpdate(which);
+
+ if (which == gMyMainWindow) {
+ Update_Screen();
+ }
+
+ EndUpdate(which);
+ }
+ break;
+ }
+ }
+}
+#endif
+
+#define PStrConstBlank ((ps3p)"\000")
+
+LOCALPROC InsertADisk0(void)
+{
+#if NavigationAvail
+#define MyDisposeNavEventUPP(userUPP) \
+ DisposeRoutineDescriptor(userUPP)
+#define MyDisposeNavObjectFilterUPP(userUPP) \
+ DisposeRoutineDescriptor(userUPP)
+#define MyNewNavObjectFilterUPP NewNavObjectFilterProc
+#define MyNewNavEventUPP NewNavEventProc
+
+ if (HaveNavServicesAvail()) {
+ NavReplyRecord theReply;
+ NavDialogOptions dialogOptions;
+ OSErr theErr = noErr;
+ NavTypeListHandle openList = NULL;
+ NavObjectFilterUPP filterUPP =
+ MyNewNavObjectFilterUPP(
+ /* (NavObjectFilterProcPtr) */ NavigationFilterProc);
+ NavEventUPP eventUPP = MyNewNavEventUPP(
+ /* (NavEventProcPtr) */ NavigationEventProc);
+
+ theErr = NavGetDefaultDialogOptions(&dialogOptions);
+
+ dialogOptions.dialogOptionFlags |= kNavDontAutoTranslate;
+ /*
+ dialogOptions.dialogOptionFlags &= ~ kNavAllowMultipleFiles;
+ */
+ dialogOptions.dialogOptionFlags &= ~ kNavAllowPreviews;
+
+ MyBeginDialog();
+ theErr = NavGetFile(NULL,
+ &theReply,
+ &dialogOptions,
+ /* NULL */ eventUPP,
+ NULL,
+ filterUPP,
+ (NavTypeListHandle)openList,
+ NULL);
+ MyEndDialog();
+
+ MyDisposeNavObjectFilterUPP(filterUPP);
+ MyDisposeNavEventUPP(eventUPP);
+
+
+ if (noErr == theErr) {
+ if (theReply.validRecord) {
+ ReportStandardOpenDiskError(InsertDisksFromDocList(
+ &theReply.selection));
+ }
+
+ NavDisposeReply(&theReply);
+ }
+
+ } else
+#endif
+#if HaveCPUfamM68K
+ if (! HaveFSSpecCallsAvail()) {
+ Point where;
+ SFReply reply;
+
+ where.h = 50;
+ where.v = 50;
+ MyBeginDialog();
+ SFGetFile(*(Point *)&where, PStrConstBlank, NULL,
+ -1 /* kNumFileTypes */, NULL /* fileTypes */,
+ NULL, &reply);
+ MyEndDialog();
+ if (reply.good) {
+ ReportStandardOpenDiskError(
+ InsertADiskFromNamevRef1(reply.fName, reply.vRefNum));
+ }
+ } else
+#endif
+ {
+ StandardFileReply reply;
+
+ MyBeginDialog();
+ StandardGetFile(0L, -1, 0L, &reply);
+ MyEndDialog();
+ if (reply.sfGood) {
+ ReportStandardOpenDiskError(
+ InsertADiskOrAliasFromSpec(&reply.sfFile,
+ trueblnr, falseblnr));
+ }
+ }
+}
+
+#ifndef MyAppIsBundle
+#define MyAppIsBundle 0
+#endif
+
+LOCALVAR MyDir_R MyDatDir;
+
+#if MyAppIsBundle
+LOCALFUNC blnr DirectorySpec2DirId(FSSpec *spec, long *dirID)
+{
+ CInfoPBRec b;
+
+ b.hFileInfo.ioCompletion = NULL;
+ b.hFileInfo.ioNamePtr = (StringPtr)spec->name;
+ b.hFileInfo.ioVRefNum = spec->vRefNum;
+ b.dirInfo.ioFDirIndex = 0;
+ b.dirInfo.ioDrDirID = spec->parID;
+ if (noErr == PBGetCatInfo(&b, false)) {
+ *dirID = b.dirInfo.ioDrDirID;
+ return trueblnr;
+ } else {
+ return falseblnr;
+ }
+}
+#endif
+
+#if MyAppIsBundle
+LOCALFUNC blnr FindNamedChildDirId(short TrueParentVol,
+ long ParentDirId, StringPtr ChildName,
+ short *TrueChildVol, long *ChildDirId)
+{
+
+ FSSpec temp_spec;
+ Boolean isFolder;
+ Boolean isAlias;
+
+ if (noErr == FSMakeFSSpec(TrueParentVol, ParentDirId,
+ ChildName, &temp_spec))
+ if (noErr == ResolveAliasFile(&temp_spec, true,
+ &isFolder, &isAlias))
+ if (isFolder)
+ if (DirectorySpec2DirId(&temp_spec, ChildDirId))
+ {
+ *TrueChildVol = temp_spec.vRefNum;
+ return trueblnr;
+ }
+ return falseblnr;
+}
+#endif
+
+LOCALFUNC blnr InitMyApplInfo(void)
+{
+#if HaveCPUfamM68K
+ if (! HaveFSSpecCallsAvail()) {
+ if (noErr == GetVol(NULL, &MyDatDir.VRefNum)) {
+ MyDatDir.DirId = 0;
+ return trueblnr;
+ }
+ } else
+#endif
+ {
+ FCBPBRec pb;
+ Str255 fileName;
+
+ pb.ioCompletion = NULL;
+ pb.ioNamePtr = fileName;
+ pb.ioVRefNum = 0;
+ pb.ioRefNum = CurResFile();
+ pb.ioFCBIndx = 0;
+ if (noErr == PBGetFCBInfoSync(&pb)) {
+ MyDatDir.VRefNum = pb.ioFCBVRefNum;
+ MyDatDir.DirId = pb.ioFCBParID;
+ return trueblnr;
+ }
+ }
+
+ return falseblnr;
+}
+
+LOCALFUNC tMacErr MyDirFromWD_v2(short VRefNum, MyDir_R *d)
+{
+ tMacErr err;
+ Str63 s;
+ WDPBRec pb;
+
+#if Support64kROM
+ if (Have64kROM()) {
+ d->VRefNum = VRefNum;
+ d->DirId = 0;
+ err = mnvm_noErr;
+ } else
+#endif
+ {
+ pb.ioCompletion = NULL;
+ pb.ioNamePtr = s;
+ pb.ioVRefNum = VRefNum;
+ pb.ioWDIndex = 0;
+ pb.ioWDProcID = 0;
+ err = To_tMacErr(PBGetWDInfoSync(&pb));
+ if (mnvm_noErr == err) {
+ d->VRefNum = pb.ioWDVRefNum;
+ d->DirId = pb.ioWDDirID;
+ }
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr FindPrefFolder(MyDir_R *d)
+{
+ tMacErr err;
+ long reply;
+
+ if (HaveGestaltAvail()
+ && (noErr == Gestalt(gestaltFindFolderAttr, &reply))
+ && TestBit(reply, gestaltFindFolderPresent)
+ )
+ {
+ err = To_tMacErr(FindFolder(
+ kOnSystemDisk,
+ kPreferencesFolderType,
+ kDontCreateFolder,
+ &d->VRefNum,
+ &d->DirId));
+ } else {
+ SysEnvRec info;
+
+ err = To_tMacErr(SysEnvirons(1, &info));
+ if (mnvm_noErr == err) {
+ err = MyDirFromWD_v2(info.sysVRefNum, d);
+ }
+ }
+
+ return err;
+}
+
+#define CatInfoIsFolder(cPB) \
+ (((cPB)->hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0)
+
+#define PStrLength(s) (*(s))
+#define SizeOfListMyChar(n) (n)
+#define PStrToTotSize(s) (SizeOfListMyChar(PStrLength(s) + 1))
+ /* + 1 for length byte */
+
+LOCALPROC PStrCopy(ps3p r, ps3p s)
+{
+ MyMoveBytes((anyp)s, (anyp)r, PStrToTotSize(s));
+}
+
+LOCALFUNC tMacErr MyFindNamedChildDir_v2(MyDir_R *src_d, StringPtr s,
+ MyDir_R *dst_d)
+{
+ tMacErr err;
+ Str255 NameBuffer;
+ CInfoPBRec cPB;
+
+ cPB.hFileInfo.ioCompletion = NULL;
+ cPB.hFileInfo.ioVRefNum = src_d->VRefNum;
+ cPB.dirInfo.ioDrDirID = src_d->DirId;
+ cPB.hFileInfo.ioNamePtr = NameBuffer;
+ PStrCopy(NameBuffer, s);
+ cPB.dirInfo.ioFDirIndex = 0;
+
+ err = To_tMacErr(PBGetCatInfoSync(&cPB));
+
+ if (mnvm_noErr == err) {
+ if (! CatInfoIsFolder(&cPB)) {
+ err = mnvm_dirNFErr;
+ } else {
+ dst_d->VRefNum = cPB.hFileInfo.ioVRefNum;
+ dst_d->DirId = cPB.dirInfo.ioDrDirID;
+ }
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr MyResolveAliasDir_v2(MyDir_R *src_d, StringPtr s,
+ MyDir_R *dst_d)
+{
+ tMacErr err;
+ FSSpec spec;
+ Boolean isFolder;
+ Boolean isAlias;
+ MyDir_R src2_d;
+
+ spec.vRefNum = src_d->VRefNum;
+ spec.parID = src_d->DirId;
+ PStrCopy(spec.name, s);
+ err = To_tMacErr(
+ ResolveAliasFile(&spec, true, &isFolder, &isAlias));
+ if (mnvm_noErr == err) {
+ if (! isAlias) {
+ err = mnvm_dirNFErr;
+ } else {
+ src2_d.VRefNum = spec.vRefNum;
+ src2_d.DirId = spec.parID;
+ err = MyFindNamedChildDir_v2(&src2_d, spec.name, dst_d);
+ }
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr MyResolveNamedChildDir_v2(MyDir_R *src_d, StringPtr s,
+ MyDir_R *dst_d)
+{
+ tMacErr err;
+
+ err = MyFindNamedChildDir_v2(src_d, s, dst_d);
+ if (mnvm_dirNFErr == err) {
+ if (HaveAliasMgrAvail()) {
+ err = MyResolveAliasDir_v2(src_d, s, dst_d);
+ }
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr OpenNamedFileInFolderCStr(MyDir_R *d,
+ char *s, short *refnum)
+{
+ Str255 fileName;
+
+ PStrFromCStr(fileName, s);
+ return OpenNamedFileInFolder(d, fileName, refnum);
+}
+
+LOCALFUNC tMacErr MyResolveNamedChildDirCStr(MyDir_R *src_d,
+ char *s, MyDir_R *dst_d)
+{
+ Str255 fileName;
+
+ PStrFromCStr(fileName, s);
+ return MyResolveNamedChildDir_v2(src_d, fileName, dst_d);
+}
+
+LOCALFUNC tMacErr LoadMacRomFromNameFolder(MyDir_R *d,
+ char *s)
+{
+ tMacErr err;
+ short refnum;
+
+ if (mnvm_noErr == (err =
+ OpenNamedFileInFolderCStr(d, s, &refnum)))
+ {
+ err = LoadMacRomFromRefNum(refnum);
+ (void) FSClose(refnum);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr LoadMacRomFromPrefDir(void)
+{
+ tMacErr err;
+ MyDir_R PrefRef;
+ MyDir_R GryphelRef;
+ MyDir_R ROMsRef;
+
+ if (mnvm_noErr == (err = FindPrefFolder(&PrefRef)))
+ if (mnvm_noErr == (err = MyResolveNamedChildDirCStr(&PrefRef,
+ "Gryphel", &GryphelRef)))
+ if (mnvm_noErr == (err = MyResolveNamedChildDirCStr(&GryphelRef,
+ "mnvm_rom", &ROMsRef)))
+ if (mnvm_noErr == (err = LoadMacRomFromNameFolder(&ROMsRef,
+ RomFileName)))
+ {
+ /* ok */
+ }
+
+ return err;
+}
+
+LOCALFUNC blnr LoadMacRom(void)
+{
+ tMacErr err;
+
+ if (mnvm_fnfErr == (err =
+ LoadMacRomFromNameFolder(&MyDatDir, RomFileName)))
+ if (mnvm_fnfErr == (err =
+ LoadMacRomFromPrefDir()))
+ {
+ }
+
+ return trueblnr; /* keep launching Mini vMac, regardless */
+}
+
+LOCALFUNC blnr Sony_InsertIth(int i)
+{
+ if ((i > 9) || ! FirstFreeDisk(nullpr)) {
+ return falseblnr;
+ } else {
+ Str255 s;
+ tMacErr err = mnvm_noErr;
+
+ PStrFromCStr(s, "disk?.dsk");
+
+ s[5] = '0' + i;
+ if (! CheckSavetMacErr(InsertADiskFromNameEtc(&MyDatDir, s))) {
+ if (mnvm_fnfErr != err) {
+ ReportStandardOpenDiskError(err);
+ }
+ return falseblnr;
+ }
+
+ return trueblnr;
+ }
+}
+
+LOCALFUNC blnr LoadInitialImages(void)
+{
+ int i;
+
+ for (i = 1; Sony_InsertIth(i); ++i) {
+ /* stop on first error (including file not found) */
+ }
+
+ return trueblnr;
+}
+
+#if IncludeSonyNew
+LOCALFUNC tMacErr WriteZero(SInt16 refnum, ui5b L)
+{
+#define ZeroBufferSize 2048
+ tMacErr err;
+ ui5b i;
+ ui3b buffer[ZeroBufferSize];
+
+ if (CheckSaveMacErr(SetFPos(refnum, fsFromStart, 0))) {
+
+ for (i = 0; i < ZeroBufferSize; ++i) {
+ buffer[i] = 0;
+ }
+ while (L > 0) {
+ i = (L > ZeroBufferSize) ? ZeroBufferSize : L;
+ err = To_tMacErr(FSWrite(refnum, (long *)&i, buffer));
+ if (mnvm_noErr != err) {
+ goto label_fail;
+ }
+ L -= i;
+ }
+ }
+
+label_fail:
+ return err;
+}
+#endif
+
+#if HaveCPUfamM68K && IncludeSonyNew
+LOCALPROC MakeNewDiskFromNamevRef(ps3p Name, short vRefNum,
+ ui5b L)
+{
+ short refNum;
+ tMacErr err;
+
+ err = To_tMacErr(Create(Name, vRefNum, '????', '????'));
+ if (mnvm_dupFNErr == err) {
+ if (CheckSaveMacErr(FSDelete(Name, vRefNum))) {
+ err = To_tMacErr(Create(Name, vRefNum, '????', '????'));
+ }
+ }
+ if (mnvm_noErr == err) {
+ if (CheckSaveMacErr(FSOpen(Name, vRefNum, &refNum))) {
+ if (CheckSaveMacErr(SetEOF(refNum, L))) {
+ if (CheckSavetMacErr(WriteZero(refNum, L))) {
+ err = Sony_Insert0(refNum, falseblnr, Name);
+ ReportStandardOpenDiskError(err);
+ refNum = NotAfileRef;
+ }
+ }
+ if (NotAfileRef != refNum) {
+ (void) FSClose(refNum);
+ }
+ }
+ if (mnvm_noErr != err) {
+ (void) FSDelete(Name, vRefNum);
+ }
+ }
+}
+#endif
+
+#if IncludeSonyNew
+LOCALPROC MakeNewDiskFromSpec(FSSpec *NewFileSpec,
+ ui5b L)
+{
+ short refNum;
+ tMacErr err;
+
+ err = To_tMacErr(FSpCreate(NewFileSpec,
+ '????', '????', smSystemScript));
+ if (mnvm_dupFNErr == err) {
+ err = To_tMacErr(FSpDelete(NewFileSpec));
+ if (mnvm_noErr == err) {
+ err = To_tMacErr(FSpCreate(NewFileSpec,
+ '????', '????', smSystemScript));
+ }
+ }
+ if (mnvm_noErr == err) {
+ if (CheckSaveMacErr(
+ FSpOpenDF(NewFileSpec, fsRdWrPerm, &refNum)))
+ {
+ if (CheckSaveMacErr(SetEOF(refNum, L))) {
+ if (CheckSavetMacErr(WriteZero(refNum, L))) {
+ err = Sony_Insert0(refNum, falseblnr, NULL);
+ ReportStandardOpenDiskError(err);
+ refNum = NotAfileRef;
+ }
+ }
+ if (NotAfileRef != refNum) {
+ (void) FSClose(refNum);
+ }
+ }
+ if (mnvm_noErr != err) {
+ (void) FSpDelete(NewFileSpec);
+ }
+ }
+}
+#endif
+
+#if UseActvFile || (IncludeSonyNew && ! SaveDialogEnable)
+LOCALFUNC tMacErr MyMakeNamedDir_v2(MyDir_R *d, StringPtr s,
+ MyDir_R *new_d)
+{
+ tMacErr err;
+ HParamBlockRec r;
+
+ r.fileParam.ioCompletion = NULL;
+ r.fileParam.ioVRefNum = d->VRefNum;
+ r.fileParam.ioDirID = d->DirId;
+ r.fileParam.ioNamePtr = s;
+ err = To_tMacErr(PBDirCreateSync(&r));
+ if (mnvm_noErr == err) {
+ new_d->VRefNum = d->VRefNum;
+ new_d->DirId = r.fileParam.ioDirID;
+ }
+
+ return err;
+}
+#endif
+
+#if UseActvFile || (IncludeSonyNew && ! SaveDialogEnable)
+LOCALFUNC tMacErr FindOrMakeMakeNamedDir_v2(MyDir_R *new_d,
+ MyDir_R *d, StringPtr s)
+{
+ tMacErr err;
+
+ err = MyResolveNamedChildDir_v2(d, s, new_d);
+ if (mnvm_fnfErr == err) {
+ err = MyMakeNamedDir_v2(d, s, new_d);
+ }
+
+ return err;
+}
+#endif
+
+#if UseActvFile || (IncludeSonyNew && ! SaveDialogEnable)
+LOCALFUNC tMacErr FindOrMakeChildDirCStr(MyDir_R *new_d,
+ MyDir_R *d, char *name)
+{
+ Str255 s;
+
+ PStrFromCStr(s, name);
+ return FindOrMakeMakeNamedDir_v2(new_d, d, s);
+}
+#endif
+
+#if IncludeSonyNew
+LOCALPROC MakeNewDisk(ui5b L, Handle NewDiskName)
+{
+#if SaveDialogEnable
+ OSErr theErr;
+
+#if NavigationAvail
+ if (HaveNavServicesAvail()) {
+ NavReplyRecord theReply;
+ NavDialogOptions dialogOptions;
+ NavEventUPP eventUPP = MyNewNavEventUPP(
+ /* (NavEventProcPtr) */ NavigationEventProc);
+
+ theErr = NavGetDefaultDialogOptions(&dialogOptions);
+ dialogOptions.dialogOptionFlags |= kNavNoTypePopup;
+#if IncludeSonyNameNew
+ if (NewDiskName != NULL) {
+ PStrFromHandle(dialogOptions.savedFileName,
+ NewDiskName, 255);
+ }
+#endif
+ MyBeginDialog();
+ theErr = NavPutFile(NULL, &theReply, &dialogOptions,
+ /* NULL */ eventUPP, '????', '????', NULL);
+ MyEndDialog();
+
+ MyDisposeNavEventUPP(eventUPP);
+
+ if (noErr == theErr) {
+ if (theReply.validRecord) {
+ long itemsInList;
+ AEKeyword keyword;
+ DescType typeCode;
+ Size actualSize;
+ FSSpec NewFileSpec;
+
+ if (noErr ==
+ AECountItems(&theReply.selection, &itemsInList))
+ if (1 == itemsInList)
+ if (noErr == AEGetNthPtr(&theReply.selection,
+ 1, typeFSS, &keyword, &typeCode,
+ (Ptr)&NewFileSpec, sizeof(FSSpec), &actualSize))
+ {
+ MakeNewDiskFromSpec(&NewFileSpec, L);
+ }
+ }
+ NavDisposeReply(&theReply);
+ }
+ } else
+#endif
+ {
+ Str255 Title;
+ Str255 prompt;
+
+#if IncludeSonyNameNew
+ if (NewDiskName != NULL) {
+ PStrFromHandle(Title, NewDiskName, 255);
+ } else
+#endif
+ {
+ NativeStrFromCStr(Title, "untitled", falseblnr);
+ }
+ NativeStrFromCStr(prompt, "Please select a file", falseblnr);
+
+#if HaveCPUfamM68K
+ if (! HaveFSSpecCallsAvail()) {
+ Point where;
+ SFReply reply;
+
+ where.h = 50;
+ where.v = 50;
+ MyBeginDialog();
+ SFPutFile(*(Point *)&where, prompt, Title, NULL, &reply);
+ MyEndDialog();
+
+ if (reply.good) {
+ MakeNewDiskFromNamevRef(reply.fName,
+ reply.vRefNum, L);
+ }
+ } else
+#endif
+ {
+ StandardFileReply reply;
+
+ MyBeginDialog();
+ StandardPutFile(prompt, Title, &reply);
+ MyEndDialog();
+
+ if (reply.sfGood) {
+ MakeNewDiskFromSpec(&reply.sfFile, L);
+ }
+ }
+ }
+#else /* SaveDialogEnable */
+ tMacErr err;
+ Str255 Title;
+ MyDir_R OutDir;
+ FSSpec spec;
+
+#if IncludeSonyNameNew
+ if (NewDiskName != NULL) {
+ PStrFromHandle(Title, NewDiskName, 255);
+ } else
+#endif
+ {
+ NativeStrFromCStr(Title, "untitled", falseblnr);
+ }
+
+ if (mnvm_noErr == (err = FindOrMakeChildDirCStr(&OutDir,
+ &MyDatDir, "out")))
+ {
+#if HaveCPUfamM68K
+ if (! HaveFSSpecCallsAvail()) {
+ MakeNewDiskFromNamevRef(Title, OutDir.VRefNum, L);
+ } else
+#endif
+ {
+ err = To_tMacErr(FSMakeFSSpec(OutDir.VRefNum, OutDir.DirId,
+ Title, &spec));
+ if ((mnvm_noErr == err) || (mnvm_fnfErr == err)) {
+ MakeNewDiskFromSpec(&spec, L);
+ }
+ }
+ }
+#endif /* SaveDialogEnable */
+}
+#endif
+
+#if UseActvFile
+
+LOCALFUNC tMacErr MyCreateFile_v2(MyDir_R *d, StringPtr s)
+{
+ tMacErr err;
+ HParamBlockRec r;
+
+ r.fileParam.ioFlVersNum = 0;
+ /*
+ Think reference says to do this,
+ but not Inside Mac IV
+ */
+
+ r.fileParam.ioCompletion = NULL;
+ r.fileParam.ioNamePtr = s;
+ r.fileParam.ioVRefNum = d->VRefNum;
+ r.fileParam.ioFVersNum = 0; /* needed if MFS volume */
+
+#if Support64kROM
+ if (Have64kROM()) {
+ err = To_tMacErr(PBCreateSync((ParamBlockRec *)&r));
+ } else
+#endif
+ {
+ r.fileParam.ioDirID = d->DirId;
+ err = To_tMacErr(PBHCreateSync(&r));
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr MyDeleteFile_v2(MyDir_R *d, StringPtr s)
+{
+ tMacErr err;
+ HParamBlockRec r;
+
+ r.fileParam.ioCompletion = NULL;
+ r.fileParam.ioVRefNum = d->VRefNum;
+ r.fileParam.ioNamePtr = s;
+ r.fileParam.ioFVersNum = 0; /* needed if MFS volume */
+
+#if Support64kROM
+ if (Have64kROM()) {
+ err = To_tMacErr(PBDeleteSync((ParamBlockRec *)&r));
+ } else
+#endif
+ {
+ r.fileParam.ioDirID = d->DirId;
+ err = To_tMacErr(PBHDeleteSync(&r));
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr MyCreateFileOverWrite_v2(MyDir_R *d, StringPtr s)
+{
+ tMacErr err;
+
+ err = MyCreateFile_v2(d, s);
+ if (mnvm_dupFNErr == err) {
+ if (mnvm_noErr == (err = MyDeleteFile_v2(d, s))) {
+ err = MyCreateFile_v2(d, s);
+ }
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr MyFileOpen_v2(MyDir_R *d, StringPtr s,
+ char Permssn, short *refnum)
+{
+ tMacErr err;
+ HParamBlockRec r;
+
+ r.ioParam.ioCompletion = NULL;
+ r.ioParam.ioNamePtr = s;
+ r.ioParam.ioVRefNum = d->VRefNum;
+ r.ioParam.ioPermssn = Permssn;
+ r.ioParam.ioMisc = 0; /* use volume buffer */
+ r.ioParam.ioVersNum = 0; /* needed if MFS volume */
+
+#if Support64kROM
+ if (Have64kROM()) {
+ err = To_tMacErr(PBOpenSync((ParamBlockRec *)&r));
+ } else
+#endif
+ {
+ r.fileParam.ioDirID = d->DirId;
+ err = To_tMacErr(PBHOpenSync(&r));
+ }
+
+ if (noErr == err) {
+ *refnum = r.ioParam.ioRefNum;
+ /*
+ Don't change *refnum unless file opened,
+ so can initialize to NotAfileRef, and
+ compare later before closing in uninit.
+ */
+ }
+ return err;
+}
+
+LOCALFUNC tMacErr MyFileOpenWrite_v2(MyDir_R *d, StringPtr s,
+ short *refnum)
+{
+ return MyFileOpen_v2(d, s, (char)fsWrPerm, refnum);
+}
+
+LOCALFUNC tMacErr MyOpenOverWriteFile_v2(MyDir_R *d, StringPtr s,
+ short *refnum)
+{
+ tMacErr err;
+
+ err = MyCreateFileOverWrite_v2(d, s);
+ if (mnvm_noErr == err) {
+ err = MyFileOpenWrite_v2(d, s, refnum);
+
+ if (mnvm_noErr != err) {
+ (void) MyDeleteFile_v2(d, s);
+ /* ignore any error, since already got one */
+ }
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr MyOpenOverWriteFileCStr(MyDir_R *d, char *name,
+ short *refnum)
+{
+ Str255 s;
+
+ PStrFromCStr(s, name);
+ return MyOpenOverWriteFile_v2(d, s, refnum);
+}
+
+#define ActvCodeFileName "act_1"
+
+LOCALFUNC tMacErr OpenActvCodeFile(short *refnum)
+{
+ tMacErr err;
+ MyDir_R PrefRef;
+ MyDir_R GryphelRef;
+ MyDir_R ActRef;
+
+ if (mnvm_noErr == (err = FindPrefFolder(&PrefRef)))
+ if (mnvm_noErr == (err = MyResolveNamedChildDirCStr(&PrefRef,
+ "Gryphel", &GryphelRef)))
+ if (mnvm_noErr == (err = MyResolveNamedChildDirCStr(&GryphelRef,
+ "mnvm_act", &ActRef)))
+ if (mnvm_noErr == (err = OpenNamedFileInFolderCStr(&ActRef,
+ ActvCodeFileName, refnum)))
+ {
+ /* ok */
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr ActvCodeFileLoad(ui3p p)
+{
+ tMacErr err;
+ short refnum;
+
+ if (CheckSavetMacErr(OpenActvCodeFile(&refnum))) {
+ long count = ActvCodeFileLen;
+ err = To_tMacErr(FSRead(refnum, &count, p));
+ (void) FSClose(refnum);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr ActvCodeFileSave(ui3p p)
+{
+ tMacErr err;
+ short refnum;
+ MyDir_R PrefRef;
+ MyDir_R GryphelRef;
+ MyDir_R ActRef;
+ long count = ActvCodeFileLen;
+
+ if (mnvm_noErr == (err = FindPrefFolder(&PrefRef)))
+ if (mnvm_noErr == (err = FindOrMakeChildDirCStr(&GryphelRef,
+ &PrefRef, "Gryphel")))
+ if (mnvm_noErr == (err = FindOrMakeChildDirCStr(&ActRef,
+ &GryphelRef, "mnvm_act")))
+ if (mnvm_noErr == (err = MyOpenOverWriteFileCStr(&ActRef,
+ ActvCodeFileName, &refnum)))
+ {
+ err = To_tMacErr(FSWrite(refnum, &count, p));
+ (void) FSClose(refnum);
+ }
+
+ return err;
+ /* return mnvm_miscErr; */
+}
+
+#endif /* UseActvFile */
+
+#define openOnly 1
+#define openPrint 2
+
+LOCALFUNC blnr GotRequiredParams(AppleEvent *theAppleEvent)
+{
+ DescType typeCode;
+ Size actualSize;
+ OSErr theErr;
+
+ theErr = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr,
+ typeWildCard, &typeCode, NULL, 0, &actualSize);
+ if (errAEDescNotFound == theErr) { /* No more required params. */
+ return trueblnr;
+ } else if (noErr == theErr) { /* More required params! */
+ return /* CheckSysCode(errAEEventNotHandled) */ falseblnr;
+ } else { /* Unexpected Error! */
+ return /* CheckSysCode(theErr) */ falseblnr;
+ }
+}
+
+LOCALFUNC blnr GotRequiredParams0(AppleEvent *theAppleEvent)
+{
+ DescType typeCode;
+ Size actualSize;
+ OSErr theErr;
+
+ theErr = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr,
+ typeWildCard, &typeCode, NULL, 0, &actualSize);
+ if (errAEDescNotFound == theErr) { /* No more required params. */
+ return trueblnr;
+ } else if (noErr == theErr) { /* More required params! */
+ return trueblnr; /* errAEEventNotHandled; */ /*^*/
+ } else { /* Unexpected Error! */
+ return /* CheckSysCode(theErr) */ falseblnr;
+ }
+}
+
+/* call back */ static pascal OSErr OpenOrPrintFiles(
+ AppleEvent *theAppleEvent, AppleEvent *reply, long aRefCon)
+{
+ /*
+ Adapted from IM VI: AppleEvent Manager:
+ Handling Required AppleEvents
+ */
+ AEDescList docList;
+
+ UnusedParam(reply);
+ UnusedParam(aRefCon);
+ /* put the direct parameter (a list of descriptors) into docList */
+ if (noErr == (AEGetParamDesc(theAppleEvent,
+ keyDirectObject, typeAEList, &docList)))
+ {
+ if (GotRequiredParams0(theAppleEvent)) {
+ /* Check for missing required parameters */
+ /* printIt = (openPrint == aRefCon) */
+ ReportStandardOpenDiskError(
+ InsertDisksFromDocList(&docList));
+ }
+ /* vCheckSysCode */ (void) (AEDisposeDesc(&docList));
+ }
+ return /* GetASysResultCode() */ 0;
+}
+
+/* call back */ static pascal OSErr DoOpenEvent(
+ AppleEvent *theAppleEvent, AppleEvent *reply, long aRefCon)
+/*
+ This is the alternative to getting an
+ open document event on startup.
+*/
+{
+ UnusedParam(reply);
+ UnusedParam(aRefCon);
+ if (GotRequiredParams0(theAppleEvent)) {
+ }
+ return /* GetASysResultCode() */ 0;
+ /* Make sure there are no additional "required" parameters. */
+}
+
+
+/* call back */ static pascal OSErr DoQuitEvent(
+ AppleEvent *theAppleEvent, AppleEvent *reply, long aRefCon)
+{
+ UnusedParam(reply);
+ UnusedParam(aRefCon);
+ if (GotRequiredParams(theAppleEvent)) {
+ RequestMacOff = trueblnr;
+ }
+
+ return /* GetASysResultCode() */ 0;
+}
+
+#define MyNewAEEventHandlerUPP NewAEEventHandlerProc
+
+LOCALFUNC blnr MyInstallEventHandler(AEEventClass theAEEventClass,
+ AEEventID theAEEventID, ProcPtr p,
+ long handlerRefcon, blnr isSysHandler)
+{
+ return noErr == (AEInstallEventHandler(theAEEventClass,
+ theAEEventID,
+#if /* useUPP */ 1
+ MyNewAEEventHandlerUPP((AEEventHandlerProcPtr)p),
+#else
+ (AEEventHandlerUPP)p,
+#endif
+ handlerRefcon, isSysHandler));
+}
+
+LOCALPROC InstallAppleEventHandlers(void)
+{
+ if (noErr == AESetInteractionAllowed(kAEInteractWithLocal))
+ if (MyInstallEventHandler(kCoreEventClass, kAEOpenApplication,
+ (ProcPtr)DoOpenEvent, 0, falseblnr))
+ if (MyInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
+ (ProcPtr)OpenOrPrintFiles, openOnly, falseblnr))
+ if (MyInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
+ (ProcPtr)OpenOrPrintFiles, openPrint, falseblnr))
+ if (MyInstallEventHandler(kCoreEventClass, kAEQuitApplication,
+ (ProcPtr)DoQuitEvent, 0, falseblnr))
+ {
+ }
+}
+
+#if EnableDragDrop
+static pascal OSErr GlobalTrackingHandler(short message,
+ WindowRef pWindow, void *handlerRefCon, DragReference theDragRef)
+{
+ RgnHandle hilightRgn;
+ Rect Bounds;
+
+ UnusedParam(pWindow);
+ UnusedParam(handlerRefCon);
+ if (! ADialogIsUp) {
+ switch(message) {
+ case kDragTrackingEnterWindow:
+ hilightRgn = NewRgn();
+ if (hilightRgn != NULL) {
+ SetScrnRectFromCoords(&Bounds,
+ 0, 0, vMacScreenHeight, vMacScreenWidth);
+ RectRgn(hilightRgn, &Bounds);
+ ShowDragHilite(theDragRef, hilightRgn, true);
+ DisposeRgn(hilightRgn);
+ }
+ break;
+ case kDragTrackingLeaveWindow:
+ HideDragHilite(theDragRef);
+ break;
+ }
+ }
+
+ return noErr;
+}
+#endif
+
+#if EnableDragDrop
+static DragTrackingHandlerUPP gGlobalTrackingHandler = NULL;
+#endif
+
+#if EnableDragDrop
+static pascal OSErr GlobalReceiveHandler(WindowRef pWindow,
+ void *handlerRefCon, DragReference theDragRef)
+{
+ unsigned short items;
+ unsigned short index;
+ ItemReference theItem;
+ Size SentSize;
+ HFSFlavor r;
+
+ UnusedParam(pWindow);
+ UnusedParam(handlerRefCon);
+ if (! ADialogIsUp)
+ if (noErr == CountDragItems(theDragRef, &items))
+ {
+ for (index = 1; index <= items; ++index) {
+ if (noErr == GetDragItemReferenceNumber(theDragRef,
+ index, &theItem))
+ if (noErr == GetFlavorDataSize(theDragRef,
+ theItem, flavorTypeHFS, &SentSize))
+ /*
+ On very old macs SentSize might only be big enough
+ to hold the actual file name. Have not seen this
+ in OS X, but still leave the check
+ as '<=' instead of '=='.
+ */
+ if (SentSize <= sizeof(HFSFlavor))
+ if (noErr == GetFlavorData(theDragRef, theItem,
+ flavorTypeHFS, (Ptr)&r, &SentSize, 0))
+ {
+ ReportStandardOpenDiskError(
+ InsertADiskOrAliasFromSpec(&r.fileSpec,
+ trueblnr, trueblnr));
+ }
+ }
+
+ if (gTrueBackgroundFlag) {
+ ProcessSerialNumber currentProcess = {0, kCurrentProcess};
+
+ (void) SetFrontProcess(¤tProcess);
+
+ WantCmdOptOnReconnect = trueblnr;
+ }
+ }
+
+ return noErr;
+}
+#endif
+
+#if EnableDragDrop
+static DragReceiveHandlerUPP gGlobalReceiveHandler = NULL;
+#endif
+
+#if EnableDragDrop
+#define MyNewDragTrackingHandlerUPP NewDragTrackingHandlerProc
+#define MyNewDragReceiveHandlerUPP NewDragReceiveHandlerProc
+#if ! OPAQUE_UPP_TYPES
+#define MyDisposeDragReceiveHandlerUPP(userUPP) \
+ DisposeRoutineDescriptor(userUPP)
+#define MyDisposeDragTrackingHandlerUPP(userUPP) \
+ DisposeRoutineDescriptor(userUPP)
+#else
+#define MyDisposeDragReceiveHandlerUPP DisposeDragReceiveHandlerUPP
+#define MyDisposeDragTrackingHandlerUPP DisposeDragTrackingHandlerUPP
+#endif
+#endif
+
+#if EnableDragDrop
+LOCALPROC UnPrepareForDragging(void)
+{
+ if (NULL != gGlobalReceiveHandler) {
+ RemoveReceiveHandler(gGlobalReceiveHandler, gMyMainWindow);
+ MyDisposeDragReceiveHandlerUPP(gGlobalReceiveHandler);
+ gGlobalReceiveHandler = NULL;
+ }
+ if (NULL != gGlobalTrackingHandler) {
+ RemoveTrackingHandler(gGlobalTrackingHandler, gMyMainWindow);
+ MyDisposeDragTrackingHandlerUPP(gGlobalTrackingHandler);
+ gGlobalTrackingHandler = NULL;
+ }
+}
+#endif
+
+#if EnableDragDrop
+LOCALFUNC blnr PrepareForDragging(void)
+{
+ blnr IsOk = falseblnr;
+
+ gGlobalTrackingHandler = MyNewDragTrackingHandlerUPP(
+ GlobalTrackingHandler);
+ if (gGlobalTrackingHandler != NULL) {
+ gGlobalReceiveHandler = MyNewDragReceiveHandlerUPP(
+ GlobalReceiveHandler);
+ if (gGlobalReceiveHandler != NULL) {
+ if (noErr == InstallTrackingHandler(gGlobalTrackingHandler,
+ gMyMainWindow, nil))
+ {
+ if (noErr == InstallReceiveHandler(
+ gGlobalReceiveHandler, gMyMainWindow, nil))
+ {
+ IsOk = trueblnr;
+ }
+ }
+ }
+ }
+
+ return IsOk;
+}
+#endif
+
+#if EnableMagnify
+#define ScaleBuffSzMult (MyWindowScale * MyWindowScale)
+#endif
+
+LOCALFUNC blnr MyCreateNewWindow(Rect *Bounds, WindowPtr *theWindow)
+{
+ WindowPtr ResultWin;
+ blnr IsOk = falseblnr;
+
+ ResultWin = NewWindow(
+ 0L, Bounds, LMGetCurApName() /* "\pMini vMac" */, false,
+ noGrowDocProc, /* Could use kWindowSimpleProc for Full Screen */
+ (WindowPtr) -1, true, 0);
+ if (ResultWin != NULL) {
+ *theWindow = ResultWin;
+
+ IsOk = trueblnr;
+ }
+
+ return IsOk;
+}
+
+LOCALPROC ZapMyWState(void)
+{
+ gMyMainWindow = NULL;
+ gGlobalReceiveHandler = NULL;
+ gGlobalTrackingHandler = NULL;
+}
+
+LOCALPROC CloseMainWindow(void)
+{
+ /*
+ Dispose of anything set up by CreateMainWindow.
+ */
+
+#if EnableDragDrop
+ UnPrepareForDragging();
+#endif
+
+ if (gMyMainWindow != NULL) {
+ DisposeWindow(gMyMainWindow);
+ gMyMainWindow = NULL;
+ }
+}
+
+enum {
+ kMagStateNormal,
+#if EnableMagnify
+ kMagStateMagnifgy,
+#endif
+ kNumMagStates
+};
+
+#define kMagStateAuto kNumMagStates
+
+#if MayNotFullScreen
+LOCALVAR int CurWinIndx;
+LOCALVAR blnr HavePositionWins[kNumMagStates];
+LOCALVAR Point WinPositionWins[kNumMagStates];
+#endif
+
+LOCALFUNC blnr CreateMainWindow(void)
+{
+ /*
+ Set up somewhere for us to draw the emulated screen and
+ receive mouse input. i.e. usually a window, as is the case
+ for this port.
+
+ The window should not be resizeable.
+
+ Should look at the current value of UseMagnify and
+ UseFullScreen.
+
+ */
+#if MayNotFullScreen
+ int WinIndx;
+#endif
+ Rect MainScrnBounds;
+ Rect AllScrnBounds;
+ Rect NewWinRect;
+ short leftPos;
+ short topPos;
+ short NewWindowHeight = vMacScreenHeight;
+ short NewWindowWidth = vMacScreenWidth;
+ blnr IsOk = falseblnr;
+
+#if VarFullScreen
+ if (UseFullScreen) {
+ My_HideMenuBar();
+ } else {
+ My_ShowMenuBar();
+ }
+#else
+#if MayFullScreen
+ My_HideMenuBar();
+#endif
+#endif
+
+ MyGetGrayRgnBounds(&AllScrnBounds);
+ MyGetScreenBitsBounds(&MainScrnBounds);
+
+#if EnableMagnify
+ if (UseMagnify) {
+ NewWindowHeight *= MyWindowScale;
+ NewWindowWidth *= MyWindowScale;
+ }
+#endif
+
+ leftPos = MainScrnBounds.left
+ + ((MainScrnBounds.right - MainScrnBounds.left)
+ - NewWindowWidth) / 2;
+ topPos = MainScrnBounds.top
+ + ((MainScrnBounds.bottom - MainScrnBounds.top)
+ - NewWindowHeight) / 2;
+ if (leftPos < MainScrnBounds.left) {
+ leftPos = MainScrnBounds.left;
+ }
+ if (topPos < MainScrnBounds.top) {
+ topPos = MainScrnBounds.top;
+ }
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ ViewHSize = MainScrnBounds.right - MainScrnBounds.left;
+ ViewVSize = MainScrnBounds.bottom - MainScrnBounds.top;
+#if EnableMagnify
+ if (UseMagnify) {
+ ViewHSize /= MyWindowScale;
+ ViewVSize /= MyWindowScale;
+ }
+#endif
+ if (ViewHSize >= vMacScreenWidth) {
+ ViewHStart = 0;
+ ViewHSize = vMacScreenWidth;
+ } else {
+ ViewHSize &= ~ 1;
+ }
+ if (ViewVSize >= vMacScreenHeight) {
+ ViewVStart = 0;
+ ViewVSize = vMacScreenHeight;
+ } else {
+ ViewVSize &= ~ 1;
+ }
+ }
+#endif
+
+ /* Create window rectangle and centre it on the screen */
+ SetRect(&MainScrnBounds, 0, 0, NewWindowWidth, NewWindowHeight);
+ OffsetRect(&MainScrnBounds, leftPos, topPos);
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewWinRect = AllScrnBounds;
+ }
+#endif
+#if VarFullScreen
+ else
+#endif
+#if MayNotFullScreen
+ {
+#if EnableMagnify
+ if (UseMagnify) {
+ WinIndx = kMagStateMagnifgy;
+ } else
+#endif
+ {
+ WinIndx = kMagStateNormal;
+ }
+
+ if (! HavePositionWins[WinIndx]) {
+ WinPositionWins[WinIndx].h = leftPos;
+ WinPositionWins[WinIndx].v = topPos;
+ HavePositionWins[WinIndx] = trueblnr;
+ NewWinRect = MainScrnBounds;
+ } else {
+ SetRect(&NewWinRect, 0, 0, NewWindowWidth, NewWindowHeight);
+ OffsetRect(&NewWinRect,
+ WinPositionWins[WinIndx].h, WinPositionWins[WinIndx].v);
+ }
+ }
+#endif
+
+#if MayNotFullScreen
+ CurWinIndx = WinIndx;
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ hOffset = MainScrnBounds.left - AllScrnBounds.left;
+ vOffset = MainScrnBounds.top - AllScrnBounds.top;
+ }
+#endif
+
+ if (MyCreateNewWindow(&NewWinRect, &gMyMainWindow)) {
+ ShowWindow(gMyMainWindow);
+
+ /* check if window rect valid */
+#if VarFullScreen
+ if (! UseFullScreen)
+#endif
+#if MayNotFullScreen
+ {
+ Rect tr;
+
+ if (MyGetWindowTitleBounds(gMyMainWindow, &tr)) {
+ if (! RectInRgn(&tr, My_GetGrayRgn())) {
+ MySetMacWindContRect(gMyMainWindow,
+ &MainScrnBounds);
+ if (MyGetWindowTitleBounds(gMyMainWindow, &tr)) {
+ if (! RectInRgn(&tr, My_GetGrayRgn())) {
+ OffsetRect(&MainScrnBounds,
+ 0, AllScrnBounds.top - tr.top);
+ MySetMacWindContRect(gMyMainWindow,
+ &MainScrnBounds);
+ }
+ }
+ }
+ }
+ }
+#endif
+
+#if EnableDragDrop
+ if (HaveDragMgrAvail()) {
+ (void) PrepareForDragging();
+ }
+#endif
+
+ IsOk = trueblnr;
+ }
+
+ return IsOk;
+}
+
+struct MyWState {
+ WindowPtr f_MainWindow;
+#if MayFullScreen
+ short f_hOffset;
+ short f_vOffset;
+ ui4r f_ViewHSize;
+ ui4r f_ViewVSize;
+ ui4r f_ViewHStart;
+ ui4r f_ViewVStart;
+#endif
+#if VarFullScreen
+ blnr f_UseFullScreen;
+#endif
+#if EnableMagnify
+ blnr f_UseMagnify;
+#endif
+#if MayNotFullScreen
+ int f_CurWinIndx;
+#endif
+ DragTrackingHandlerUPP f_gGlobalTrackingHandler;
+ DragReceiveHandlerUPP f_gGlobalReceiveHandler;
+};
+typedef struct MyWState MyWState;
+
+LOCALPROC GetMyWState(MyWState *r)
+{
+ r->f_MainWindow = gMyMainWindow;
+#if MayFullScreen
+ r->f_hOffset = hOffset;
+ r->f_vOffset = vOffset;
+ r->f_ViewHSize = ViewHSize;
+ r->f_ViewVSize = ViewVSize;
+ r->f_ViewHStart = ViewHStart;
+ r->f_ViewVStart = ViewVStart;
+#endif
+#if VarFullScreen
+ r->f_UseFullScreen = UseFullScreen;
+#endif
+#if EnableMagnify
+ r->f_UseMagnify = UseMagnify;
+#endif
+#if MayNotFullScreen
+ r->f_CurWinIndx = CurWinIndx;
+#endif
+ r->f_gGlobalTrackingHandler = gGlobalTrackingHandler;
+ r->f_gGlobalReceiveHandler = gGlobalReceiveHandler;
+}
+
+LOCALPROC SetMyWState(MyWState *r)
+{
+ gMyMainWindow = r->f_MainWindow;
+#if MayFullScreen
+ hOffset = r->f_hOffset;
+ vOffset = r->f_vOffset;
+ ViewHSize = r->f_ViewHSize;
+ ViewVSize = r->f_ViewVSize;
+ ViewHStart = r->f_ViewHStart;
+ ViewVStart = r->f_ViewVStart;
+#endif
+#if VarFullScreen
+ UseFullScreen = r->f_UseFullScreen;
+#endif
+#if EnableMagnify
+ UseMagnify = r->f_UseMagnify;
+#endif
+#if MayNotFullScreen
+ CurWinIndx = r->f_CurWinIndx;
+#endif
+ gGlobalTrackingHandler = r->f_gGlobalTrackingHandler;
+ gGlobalReceiveHandler = r->f_gGlobalReceiveHandler;
+}
+
+LOCALFUNC blnr ReCreateMainWindow(void)
+{
+ /*
+ Like CreateMainWindow (which it calls), except may be
+ called when already have window, without CloseMainWindow
+ being called first. (Usually with different
+ values of WantMagnify and WantFullScreen than
+ on the previous call.)
+
+ If there is existing window, and fail to create
+ the new one, then existing window must be left alone,
+ in valid state. (and return falseblnr. otherwise,
+ if succeed, return trueblnr)
+
+ i.e. can allocate the new one before disposing
+ of the old one.
+ */
+ MyWState old_state;
+ MyWState new_state;
+
+#if VarFullScreen
+ if (! UseFullScreen)
+#endif
+#if MayNotFullScreen
+ {
+ /* save old position */
+ if (gMyMainWindow != NULL) {
+ Rect r;
+
+ if (MyGetWindowContBounds(gMyMainWindow, &r)) {
+ WinPositionWins[CurWinIndx].h = r.left;
+ WinPositionWins[CurWinIndx].v = r.top;
+ }
+ }
+ }
+#endif
+
+#if MayFullScreen
+ UngrabMachine();
+#endif
+
+ GetMyWState(&old_state);
+
+ ZapMyWState();
+
+#if VarFullScreen
+ UseFullScreen = WantFullScreen;
+#endif
+#if EnableMagnify
+ UseMagnify = WantMagnify;
+#endif
+
+ ColorTransValid = falseblnr;
+
+ if (! CreateMainWindow()) {
+ CloseMainWindow();
+ SetMyWState(&old_state);
+
+#if VarFullScreen
+ if (UseFullScreen) {
+ My_HideMenuBar();
+ } else {
+ My_ShowMenuBar();
+ }
+#endif
+
+ /* avoid retry */
+#if VarFullScreen
+ WantFullScreen = UseFullScreen;
+#endif
+#if EnableMagnify
+ WantMagnify = UseMagnify;
+#endif
+
+ return falseblnr;
+ } else {
+ GetMyWState(&new_state);
+ SetMyWState(&old_state);
+ CloseMainWindow();
+ SetMyWState(&new_state);
+
+ if (HaveCursorHidden) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ WantCursorHidden = trueblnr;
+ }
+
+ return trueblnr;
+ }
+}
+
+#if VarFullScreen && EnableMagnify
+enum {
+ kWinStateWindowed,
+#if EnableMagnify
+ kWinStateFullScreen,
+#endif
+ kNumWinStates
+};
+#endif
+
+#if VarFullScreen && EnableMagnify
+LOCALVAR int WinMagStates[kNumWinStates];
+#endif
+
+LOCALPROC ZapWinStateVars(void)
+{
+#if MayNotFullScreen
+ {
+ int i;
+
+ for (i = 0; i < kNumMagStates; ++i) {
+ HavePositionWins[i] = falseblnr;
+ }
+ }
+#endif
+#if VarFullScreen && EnableMagnify
+ {
+ int i;
+
+ for (i = 0; i < kNumWinStates; ++i) {
+ WinMagStates[i] = kMagStateAuto;
+ }
+ }
+#endif
+}
+
+#if VarFullScreen
+LOCALPROC ToggleWantFullScreen(void)
+{
+ WantFullScreen = ! WantFullScreen;
+
+#if EnableMagnify
+ {
+ int OldWinState =
+ UseFullScreen ? kWinStateFullScreen : kWinStateWindowed;
+ int OldMagState =
+ UseMagnify ? kMagStateMagnifgy : kMagStateNormal;
+ int NewWinState =
+ WantFullScreen ? kWinStateFullScreen : kWinStateWindowed;
+ int NewMagState = WinMagStates[NewWinState];
+
+ WinMagStates[OldWinState] = OldMagState;
+ if (kMagStateAuto != NewMagState) {
+ WantMagnify = (kMagStateMagnifgy == NewMagState);
+ } else {
+ WantMagnify = falseblnr;
+ if (WantFullScreen) {
+ Rect r;
+
+ MyGetScreenBitsBounds(&r);
+ if (((r.right - r.left)
+ >= vMacScreenWidth * MyWindowScale)
+ && ((r.bottom - r.top)
+ >= vMacScreenHeight * MyWindowScale)
+ )
+ {
+ WantMagnify = trueblnr;
+ }
+ }
+ }
+ }
+#endif
+}
+#endif
+
+LOCALPROC LeaveBackground(void)
+{
+#if HogCPU
+ NoEventsCounter = 0;
+#endif
+
+ SetCursorArrow();
+ ReconnectKeyCodes3();
+}
+
+LOCALPROC EnterBackground(void)
+{
+ DisconnectKeyCodes3();
+
+#if VarFullScreen
+ if (WantFullScreen) {
+ ToggleWantFullScreen();
+ }
+#endif
+}
+
+LOCALPROC LeaveSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Start();
+#endif
+
+ StartUpTimeAdjust();
+}
+
+LOCALPROC EnterSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+}
+
+LOCALPROC CheckForSavedTasks(void)
+{
+ if (MyEvtQNeedRecover) {
+ MyEvtQNeedRecover = falseblnr;
+
+ /* attempt cleanup, MyEvtQNeedRecover may get set again */
+ MyEvtQTryRecoverFromFull();
+ }
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMouseConstrain();
+ }
+#endif
+
+ if (RequestMacOff) {
+ RequestMacOff = falseblnr;
+ if (AnyDiskInserted()) {
+ MacMsgOverride(kStrQuitWarningTitle,
+ kStrQuitWarningMessage);
+ } else {
+ ForceMacOff = trueblnr;
+ }
+ }
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (gTrueBackgroundFlag != gBackgroundFlag) {
+ gBackgroundFlag = gTrueBackgroundFlag;
+ if (gTrueBackgroundFlag) {
+ EnterBackground();
+ } else {
+ LeaveBackground();
+ }
+ }
+
+ if (CurSpeedStopped != (SpeedStopped ||
+ (gBackgroundFlag && ! RunInBackground
+#if EnableAutoSlow && 0
+ && (QuietSubTicks >= 4092)
+#endif
+ )))
+ {
+ CurSpeedStopped = ! CurSpeedStopped;
+ if (CurSpeedStopped) {
+ EnterSpeedStopped();
+ } else {
+ LeaveSpeedStopped();
+ }
+ }
+
+#if EnableRecreateW
+ if (! (gTrueBackgroundFlag)) {
+ if (0
+#if EnableMagnify
+ || (UseMagnify != WantMagnify)
+#endif
+#if VarFullScreen
+ || (UseFullScreen != WantFullScreen)
+#endif
+ )
+ {
+ (void) ReCreateMainWindow();
+#if HogCPU
+ NoEventsCounter = 0;
+#endif
+ }
+ }
+#endif
+
+#if MayFullScreen
+ if (GrabMachine != (
+#if VarFullScreen
+ UseFullScreen &&
+#endif
+ ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ GrabMachine = ! GrabMachine;
+ AdjustMachineGrab();
+ }
+#endif
+
+ if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) {
+ MacMsgDisplayOn();
+ }
+
+ if (NeedWholeScreenDraw) {
+ NeedWholeScreenDraw = falseblnr;
+ ScreenChangedAll();
+ }
+
+ if (gTrueBackgroundFlag) {
+ /*
+ dialog during drag and drop hangs if in background
+ and don't want recursive dialogs
+ so wait til later to display dialog
+ */
+ } else {
+#if IncludeSonyNew
+ if (vSonyNewDiskWanted) {
+#if IncludeSonyNameNew
+ if (vSonyNewDiskName != NotAPbuf) {
+ MakeNewDisk(vSonyNewDiskSize,
+ PbufDat[vSonyNewDiskName]);
+ PbufDispose(vSonyNewDiskName);
+ vSonyNewDiskName = NotAPbuf;
+ } else
+#endif
+ {
+ MakeNewDisk(vSonyNewDiskSize, NULL);
+ }
+ vSonyNewDiskWanted = falseblnr;
+ /* must be done after may have gotten disk */
+ }
+#endif
+ if (RequestInsertDisk) {
+ RequestInsertDisk = falseblnr;
+ InsertADisk0();
+ }
+ }
+
+#if NeedRequestIthDisk
+ if (0 != RequestIthDisk) {
+ Sony_InsertIth(RequestIthDisk);
+ RequestIthDisk = 0;
+ }
+#endif
+
+ if (HaveCursorHidden != (WantCursorHidden
+ && ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ HaveCursorHidden = ! HaveCursorHidden;
+ if (HaveCursorHidden) {
+ HideCursor();
+ } else {
+ ShowCursor();
+ }
+ }
+}
+
+GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void)
+{
+ UpdateTrueEmulatedTime();
+ return TrueEmulatedTime == OnTrueTime;
+}
+
+#define CheckItem CheckMenuItem
+
+/* Menu Constants */
+
+#define kAppleMenu 128
+#define kFileMenu 129
+#define kSpecialMenu 130
+
+/* Apple */
+
+enum {
+ kAppleNull,
+
+ kAppleAboutItem,
+ kAppleSep1,
+
+ kNumAppleItems
+};
+
+/* File */
+
+enum {
+ kFileNull,
+
+ kFileOpenDiskImage,
+ kFileSep1,
+ kFileQuitItem,
+
+ kNumFileItems
+};
+
+/* Special */
+
+enum {
+ kSpecialNull,
+
+ kSpecialMoreCommandsItem,
+
+ kNumSpecialItems
+};
+
+LOCALPROC DoOpenDA(short menuItem)
+{
+ Str32 name;
+ GrafPtr savePort;
+
+ GetPort(&savePort);
+ GetMenuItemText(GetMenuHandle(kAppleMenu), menuItem, name);
+ OpenDeskAcc(name);
+ SystemTask();
+ SetPort(savePort);
+}
+
+LOCALPROC MacOS_HandleMenu(short menuID, short menuItem)
+{
+ switch (menuID) {
+ case kAppleMenu:
+ if (kAppleAboutItem == menuItem) {
+ DoAboutMsg();
+ } else {
+ DoOpenDA(menuItem);
+ }
+ break;
+
+ case kFileMenu:
+ switch (menuItem) {
+ case kFileOpenDiskImage:
+ RequestInsertDisk = trueblnr;
+ break;
+
+ case kFileQuitItem:
+ RequestMacOff = trueblnr;
+ break;
+ }
+ break;
+
+ case kSpecialMenu:
+ switch (menuItem) {
+ case kSpecialMoreCommandsItem:
+ DoMoreCommandsMsg();
+ break;
+ }
+ break;
+
+ default:
+ /* if 0 == menuID, then no command chosen from menu */
+ /* do nothing */
+ break;
+ }
+}
+
+LOCALPROC HandleMacEvent(EventRecord *theEvent)
+{
+ WindowPtr whichWindow;
+ GrafPtr savePort;
+
+ switch(theEvent->what) {
+ case mouseDown:
+ switch (FindWindow(theEvent->where, &whichWindow)) {
+ case inSysWindow:
+ SystemClick(theEvent, whichWindow);
+ break;
+ case inMenuBar:
+ ForceShowCursor();
+ {
+ long menuSelection =
+ MenuSelect(theEvent->where);
+ MacOS_HandleMenu(HiWord(menuSelection),
+ LoWord(menuSelection));
+ }
+ HiliteMenu(0);
+ break;
+
+ case inDrag:
+ {
+ Rect r;
+
+ MyGetScreenBitsBounds(&r);
+ DragWindow(whichWindow, theEvent->where, &r);
+ }
+ break;
+
+ case inContent:
+ if (FrontWindow() != whichWindow) {
+ SelectWindow(whichWindow);
+ }
+ if (whichWindow == gMyMainWindow) {
+ MousePositionNotifyFromGlobal(theEvent->where);
+ MyMouseButtonSet(trueblnr);
+ }
+ break;
+
+ case inGoAway:
+ if (TrackGoAway(whichWindow, theEvent->where)) {
+ RequestMacOff = trueblnr;
+ }
+ break;
+
+ case inZoomIn:
+ case inZoomOut:
+ /* Zoom Boxes */
+ break;
+ }
+ break;
+ case mouseUp:
+ MousePositionNotifyFromGlobal(theEvent->where);
+ MyMouseButtonSet(falseblnr);
+ break;
+
+ case updateEvt:
+ GetPort(&savePort);
+ BeginUpdate((WindowPtr) theEvent->message);
+
+ if ((WindowPtr)theEvent->message == gMyMainWindow) {
+ Update_Screen();
+ }
+
+ EndUpdate((WindowPtr) theEvent->message);
+ SetPort(savePort);
+ break;
+
+ case keyDown:
+ case autoKey:
+ case keyUp:
+ /* ignore it */
+ break;
+ case osEvt:
+ if ((theEvent->message >> 24) & suspendResumeMessage) {
+ if (theEvent->message & 1) {
+ gTrueBackgroundFlag = falseblnr;
+ } else {
+ gTrueBackgroundFlag = trueblnr;
+ }
+ }
+ break;
+ case kHighLevelEvent:
+ if (kCoreEventClass == (AEEventClass)theEvent->message) {
+ if (/* CheckSysCode */ noErr ==
+ (AEProcessAppleEvent(theEvent)))
+ {
+ }
+ } else {
+ /* vCheckSysCode(errAENotAppleEvent); */
+ }
+ break;
+ }
+}
+
+LOCALPROC WaitForTheNextEvent(void)
+{
+ /*
+ Wait for the next event
+ from the operating system, we have nothing better
+ to do. Call HandleTheEvent and return (only
+ wait for one event).
+ */
+
+ EventRecord theEvent;
+
+ if (
+#if HaveCPUfamM68K
+ (! HaveWaitNextEventAvail()) ?
+ GetNextEvent(everyEvent, &theEvent) :
+#endif
+ WaitNextEvent(everyEvent, &theEvent,
+ (gTrueBackgroundFlag && ! RunInBackground)
+ ? 5 * 60 * 60
+ : 5,
+ /*
+ still need to check for
+ control key when SpeedStopped,
+ don't get event
+ */
+ NULL))
+ {
+ HandleMacEvent(&theEvent);
+ }
+}
+
+LOCALPROC DontWaitForEvent(void)
+{
+ /* we're busy, but see what system wants */
+
+ EventRecord theEvent;
+ int i = 0;
+
+#if 0 /* this seems to cause crashes on some machines */
+ if (EventAvail(everyEvent, &theEvent)) {
+ NoEventsCounter = 0;
+#endif
+
+ while ((
+#if HaveCPUfamM68K
+ (! HaveWaitNextEventAvail()) ?
+ GetNextEvent(everyEvent, &theEvent) :
+#endif
+ WaitNextEvent(everyEvent, &theEvent, 0, NULL))
+ && (i < 10))
+ {
+ HandleMacEvent(&theEvent);
+#if HogCPU
+ NoEventsCounter = 0;
+#endif
+ ++i;
+ }
+#if 0
+ }
+#endif
+}
+
+#define PrivateEventMask \
+ (mDownMask | mUpMask | keyDownMask | keyUpMask | autoKeyMask)
+
+#define IsPowOf2(x) (0 == ((x) & ((x) - 1)))
+
+LOCALPROC CheckForSystemEvents(void)
+{
+ /*
+ Handle any events that are waiting for us.
+ Return immediately when no more events
+ are waiting, don't wait for more.
+ */
+
+#if HogCPU && MayFullScreen
+ /*
+ only hog cpu in full screen mode
+ */
+ if (
+#if VarFullScreen
+ UseFullScreen &&
+#endif
+ ((ui3b) -1 == SpeedValue) && ! CurSpeedStopped)
+ {
+ EventRecord theEvent;
+
+ if (! OSEventAvail(everyEvent, &theEvent)) {
+ /*
+ if no OSEvent now, and not looking for aftermath of
+ event, assume there is no event of any kind we need
+ to look at
+ */
+ if (NoEventsCounter < 256) {
+ ++NoEventsCounter;
+ if (IsPowOf2(NoEventsCounter)) {
+ DontWaitForEvent();
+ }
+ }
+ } else {
+ WindowPtr whichWindow;
+
+ blnr PrivateEvent = falseblnr;
+ switch (theEvent.what) {
+ case keyDown:
+ case autoKey:
+ case keyUp:
+ case mouseUp:
+ PrivateEvent = trueblnr;
+ break;
+ case mouseDown:
+ if ((inContent ==
+ FindWindow(theEvent.where, &whichWindow))
+ && (whichWindow == gMyMainWindow)
+ && (FrontWindow() == whichWindow))
+ {
+ PrivateEvent = trueblnr;
+ }
+ break;
+ }
+ if (PrivateEvent) {
+ /*
+ if event can effect only us, and not looking out
+ for aftermath of another event, then hog the cpu
+ */
+ if (GetOSEvent(PrivateEventMask, &theEvent)) {
+ HandleMacEvent(&theEvent);
+ }
+ } else {
+ NoEventsCounter = 0;
+ /*
+ Have an Event, so reset NoEventsCounter, no matter
+ what. WaitNextEvent can return false, even if it did
+ handle an event. Such as a click in the collapse
+ box. In this case we need to look out for update
+ events.
+ */
+ DontWaitForEvent();
+ }
+ }
+ } else
+#endif
+ {
+ DontWaitForEvent();
+ }
+
+ if (! gBackgroundFlag) {
+ CheckKeyBoardState();
+ }
+}
+
+GLOBALOSGLUPROC WaitForNextTick(void)
+{
+label_retry:
+ CheckForSystemEvents();
+ CheckForSavedTasks();
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (CurSpeedStopped) {
+ DoneWithDrawingForTick();
+ WaitForTheNextEvent();
+ goto label_retry;
+ }
+
+ /*
+ Wait until the end of the current
+ tick, then emulate the next tick.
+ */
+
+ if (ExtraTimeNotOver()) {
+#if HaveCPUfamM68K
+ if (HaveWaitNextEventAvail())
+#endif
+ {
+ EventRecord theEvent;
+
+ if (WaitNextEvent(everyEvent, &theEvent, 1, NULL)) {
+ HandleMacEvent(&theEvent);
+#if HogCPU
+ NoEventsCounter = 0;
+#endif
+ }
+ }
+ goto label_retry;
+ }
+
+ if (CheckDateTime()) {
+#if MySoundEnabled
+ MySound_SecondNotify();
+#endif
+#if EnableDemoMsg
+ DemoModeSecondNotify();
+#endif
+ }
+
+ if (! (gBackgroundFlag)) {
+ CheckMouseState();
+ }
+
+ OnTrueTime = TrueEmulatedTime;
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("WaitForNextTick, OnTrueTime", OnTrueTime);
+#endif
+}
+
+#include "PROGMAIN.h"
+
+LOCALPROC AppendMenuCStr(MenuHandle menu, char *s)
+{
+ Str255 t;
+
+ PStrFromCStr(t, s);
+ AppendMenu(menu, t);
+}
+
+LOCALPROC AppendMenuConvertCStr(MenuHandle menu,
+ char *s, blnr WantEllipsis)
+{
+ Str255 t;
+
+ NativeStrFromCStr(t, s, WantEllipsis);
+ AppendMenu(menu, t);
+}
+
+LOCALPROC AppendMenuSep(MenuHandle menu)
+{
+ AppendMenuCStr(menu, "(-");
+}
+
+LOCALFUNC MenuHandle NewMenuFromConvertCStr(short menuID, char *s)
+{
+ Str255 r;
+
+ NativeStrFromCStr(r, s, falseblnr);
+ return NewMenu(menuID, r);
+}
+
+LOCALFUNC blnr InstallOurMenus(void)
+{
+ MenuHandle menu;
+ Str255 s;
+
+ PStrFromChar(s, (char)20);
+ menu = NewMenu(kAppleMenu, s);
+ if (menu != NULL) {
+ AppendMenuConvertCStr(menu,
+ kStrMenuItemAbout, trueblnr);
+ AppendMenuSep(menu);
+ AppendResMenu(menu, 'DRVR');
+ InsertMenu(menu, 0);
+ }
+
+ menu = NewMenuFromConvertCStr(kFileMenu, kStrMenuFile);
+ if (menu != NULL) {
+ AppendMenuConvertCStr(menu,
+ kStrMenuItemOpen, trueblnr);
+ {
+ AppendMenuSep(menu);
+ AppendMenuConvertCStr(menu,
+ kStrMenuItemQuit, falseblnr);
+ }
+ InsertMenu(menu, 0);
+ }
+
+ menu = NewMenuFromConvertCStr(kSpecialMenu, kStrMenuSpecial);
+ if (menu != NULL) {
+ AppendMenuConvertCStr(menu,
+ kStrMenuItemMore, trueblnr);
+ InsertMenu(menu, 0);
+ }
+
+ DrawMenuBar();
+
+ return trueblnr;
+}
+
+#if AppearanceAvail
+LOCALFUNC blnr InstallOurAppearanceClient(void)
+{
+ if (HaveAppearanceAvail()) {
+ RegisterAppearanceClient();
+ }
+ return trueblnr;
+}
+#endif
+
+LOCALFUNC blnr InstallOurEventHandlers(void)
+{
+ InitKeyCodes();
+
+ if (HaveAppleEvtMgrAvail()) {
+ InstallAppleEventHandlers();
+ }
+ return trueblnr;
+}
+
+LOCALPROC ZapOSGLUVars(void)
+{
+ /*
+ Set initial values of variables for
+ platform dependent code, where not
+ done using c initializers. (such
+ as for arrays.)
+ */
+
+ ZapEmKeys();
+ InitDrives();
+ ZapWinStateVars();
+}
+
+LOCALPROC ReserveAllocAll(void)
+{
+ /* !! must match ChooseTotMemSize in build system !! */
+
+#if dbglog_HAVE
+ dbglog_ReserveAlloc();
+#endif
+ ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr);
+ ReserveAllocOneBlock(&screencomparebuff,
+ vMacScreenNumBytes, 5, trueblnr);
+#if UseControlKeys
+ ReserveAllocOneBlock(&CntrlDisplayBuff,
+ vMacScreenNumBytes, 5, falseblnr);
+#endif
+#if EnableMagnify
+ ReserveAllocOneBlock(&ScalingBuff,
+ vMacScreenNumBytes * (ScaleBuffSzMult), 5, falseblnr);
+ ReserveAllocOneBlock(&ScalingTabl,
+ ScalingTablsz, 5, falseblnr);
+#endif
+#if MySoundEnabled
+ ReserveAllocOneBlock((ui3p *)&TheSoundBuffer,
+ dbhBufferSize, 5, falseblnr);
+#endif
+
+ EmulationReserveAlloc();
+}
+
+LOCALFUNC blnr AllocMyMemory(void)
+{
+ uimr n;
+ blnr IsOk = falseblnr;
+
+ ReserveAllocOffset = 0;
+ ReserveAllocBigBlock = nullpr;
+ ReserveAllocAll();
+ n = ReserveAllocOffset;
+ ReserveAllocBigBlock = (ui3p)NewPtr(n);
+ if (NULL == ReserveAllocBigBlock) {
+ MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr);
+ } else {
+ ReserveAllocOffset = 0;
+ ReserveAllocAll();
+ if (n != ReserveAllocOffset) {
+ /* oops, program error */
+ } else {
+ IsOk = trueblnr;
+ }
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr InitOSGLU(void)
+{
+ /*
+ run all the initializations
+ needed for the program.
+ */
+
+ if (InitMacManagers())
+ if (AllocMyMemory())
+ if (InitMyApplInfo())
+#if dbglog_HAVE
+ if (dbglog_open())
+#endif
+#if AppearanceAvail
+ if (InstallOurAppearanceClient())
+#endif
+ if (InstallOurEventHandlers())
+ if (InstallOurMenus())
+#if MySoundEnabled
+ if (MySound_Init())
+#endif
+ if (ReCreateMainWindow())
+ if (LoadMacRom())
+ if (LoadInitialImages())
+#if UseActvCode
+ if (ActvCodeInit())
+#endif
+ if (InitLocationDat())
+ if (WaitForRom())
+ {
+ return trueblnr;
+ }
+ return falseblnr;
+}
+
+LOCALPROC UnInitOSGLU(void)
+{
+ /*
+ Do all clean ups needed
+ before the program quits.
+ */
+
+ if (MacMsgDisplayed) {
+ MacMsgDisplayOff();
+ }
+
+#if MayFullScreen
+ UngrabMachine();
+#endif
+
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+
+ CloseMainWindow();
+
+#if MayFullScreen
+ My_ShowMenuBar();
+#endif
+
+#if IncludePbufs
+ UnInitPbufs();
+#endif
+ UnInitDrives();
+
+#if dbglog_HAVE
+ dbglog_close();
+#endif
+
+ ForceShowCursor();
+
+ if (! gTrueBackgroundFlag) {
+ CheckSavedMacMsg();
+ }
+}
+
+#ifndef MainReturnsInt
+#define MainReturnsInt 0
+#endif
+
+#ifndef NeedLongGlue
+#define NeedLongGlue 0
+#endif
+
+#if NeedLongGlue
+#define main long_main
+#endif
+
+#if MainReturnsInt
+int
+#else
+void
+#endif
+main(void)
+{
+ ZapOSGLUVars();
+ if (InitOSGLU()) {
+ ProgramMain();
+ }
+ UnInitOSGLU();
+
+#if MainReturnsInt
+ return 0;
+#endif
+}
--- /dev/null
+++ b/src/OSGLUNDS.c
@@ -1,0 +1,1387 @@
+/*
+ OSGLUNDS.c
+
+ Copyright (C) 2012 Lazyone, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Operating System GLUe for Nintendo DS
+*/
+
+#include "CNFGRAPI.h"
+#include "SYSDEPNS.h"
+#include "ENDIANAC.h"
+
+#include "MYOSGLUE.h"
+
+#include "STRCONST.h"
+
+#include "FB1BPP2I.h"
+
+#define CONSOLE_TRACE() \
+ fprintf(stderr, "%s() at line %d\n", __FUNCTION__, __LINE__)
+
+/* --- some simple utilities --- */
+
+GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount)
+{
+ (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount);
+}
+
+/*
+ Nintendo DS port globals
+*/
+#define DS_ScreenWidth 256
+#define DS_ScreenHeight 192
+
+LOCALVAR volatile int VBlankCounter = 0;
+LOCALVAR volatile int HBlankCounter = 0;
+LOCALVAR volatile unsigned int TimerBaseMSec = 0;
+LOCALVAR Keyboard* DSKeyboard = NULL;
+LOCALVAR volatile int LastKeyboardKey = NOKEY;
+LOCALVAR volatile int KeyboardKey = NOKEY;
+LOCALVAR volatile int KeysHeld = 0;
+LOCALVAR volatile int CursorX = 0;
+LOCALVAR volatile int CursorY = 0;
+LOCALVAR int Display_bg2_Main = 0;
+
+/* --- control mode and internationalization --- */
+
+#define NeedCell2PlainAsciiMap 1
+
+#include "INTLCHAR.h"
+
+/* --- sending debugging info to file --- */
+
+#if dbglog_HAVE
+
+#define dbglog_ToStdErr 1
+
+#if ! dbglog_ToStdErr
+LOCALVAR FILE *dbglog_File = NULL;
+#endif
+
+LOCALFUNC blnr dbglog_open0(void)
+{
+#if dbglog_ToStdErr
+ return trueblnr;
+#else
+ dbglog_File = fopen("dbglog.txt", "w");
+ return (NULL != dbglog_File);
+#endif
+}
+
+LOCALPROC dbglog_write0(char *s, uimr L)
+{
+#if dbglog_ToStdErr
+ (void) fwrite(s, 1, L, stderr);
+#else
+ if (dbglog_File != NULL) {
+ (void) fwrite(s, 1, L, dbglog_File);
+ }
+#endif
+}
+
+LOCALPROC dbglog_close0(void)
+{
+#if ! dbglog_ToStdErr
+ if (dbglog_File != NULL) {
+ fclose(dbglog_File);
+ dbglog_File = NULL;
+ }
+#endif
+}
+
+#endif
+
+/* --- debug settings and utilities --- */
+
+#if ! dbglog_HAVE
+#define WriteExtraErr(s)
+#else
+LOCALPROC WriteExtraErr(char *s)
+{
+ dbglog_writeCStr("*** error: ");
+ dbglog_writeCStr(s);
+ dbglog_writeReturn();
+}
+#endif
+
+/* --- information about the environment --- */
+
+#define WantColorTransValid 0
+
+#include "COMOSGLU.h"
+#include "CONTROLM.h"
+
+LOCALPROC NativeStrFromCStr(char *r, char *s)
+{
+ ui3b ps[ClStrMaxLength];
+ int i;
+ int L;
+
+ ClStrFromSubstCStr(&L, ps, s);
+
+ for (i = 0; i < L; ++i) {
+ r[i] = Cell2PlainAsciiMap[ps[i]];
+ }
+
+ r[L] = 0;
+}
+
+/* --- drives --- */
+
+#define NotAfileRef NULL
+
+LOCALVAR FILE *Drives[NumDrives]; /* open disk image files */
+#if IncludeSonyGetName || IncludeSonyNew
+LOCALVAR char *DriveNames[NumDrives];
+#endif
+
+LOCALPROC InitDrives(void)
+{
+ /*
+ This isn't really needed, Drives[i] and DriveNames[i]
+ need not have valid values when not vSonyIsInserted[i].
+ */
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ Drives[i] = NotAfileRef;
+#if IncludeSonyGetName || IncludeSonyNew
+ DriveNames[i] = NULL;
+#endif
+ }
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer,
+ tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
+ ui5r *Sony_ActCount)
+{
+ tMacErr err = mnvm_miscErr;
+ FILE *refnum = Drives[Drive_No];
+ ui5r NewSony_Count = 0;
+
+ if (0 == fseek(refnum, Sony_Start, SEEK_SET)) {
+ if (IsWrite) {
+ NewSony_Count = fwrite(Buffer, 1, Sony_Count, refnum);
+ } else {
+ NewSony_Count = fread(Buffer, 1, Sony_Count, refnum);
+ }
+
+ if (NewSony_Count == Sony_Count) {
+ err = mnvm_noErr;
+ }
+ }
+
+ if (nullpr != Sony_ActCount) {
+ *Sony_ActCount = NewSony_Count;
+ }
+
+ return err; /*& figure out what really to return &*/
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count)
+{
+ tMacErr err = mnvm_miscErr;
+ FILE *refnum = Drives[Drive_No];
+ long v;
+
+ if (0 == fseek(refnum, 0, SEEK_END)) {
+ v = ftell(refnum);
+ if (v >= 0) {
+ *Sony_Count = v;
+ err = mnvm_noErr;
+ }
+ }
+
+ return err; /*& figure out what really to return &*/
+}
+
+LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit)
+{
+ FILE *refnum = Drives[Drive_No];
+
+ DiskEjectedNotify(Drive_No);
+
+ fclose(refnum);
+ Drives[Drive_No] = NotAfileRef; /* not really needed */
+
+#if IncludeSonyGetName || IncludeSonyNew
+ {
+ char *s = DriveNames[Drive_No];
+ if (NULL != s) {
+ if (deleteit) {
+ remove(s);
+ }
+ free(s);
+ DriveNames[Drive_No] = NULL; /* not really needed */
+ }
+ }
+#endif
+
+ return mnvm_noErr;
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No)
+{
+ return vSonyEject0(Drive_No, falseblnr);
+}
+
+#if IncludeSonyNew
+GLOBALOSGLUFUNC tMacErr vSonyEjectDelete(tDrive Drive_No)
+{
+ return vSonyEject0(Drive_No, trueblnr);
+}
+#endif
+
+LOCALPROC UnInitDrives(void)
+{
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ if (vSonyIsInserted(i)) {
+ (void) vSonyEject(i);
+ }
+ }
+}
+
+#if IncludeSonyGetName
+GLOBALOSGLUFUNC tMacErr vSonyGetName(tDrive Drive_No, tPbuf *r)
+{
+ char *drivepath = DriveNames[Drive_No];
+ if (NULL == drivepath) {
+ return mnvm_miscErr;
+ } else {
+ char *s = strrchr(drivepath, '/');
+ if (NULL == s) {
+ s = drivepath;
+ } else {
+ ++s;
+ }
+ return NativeTextToMacRomanPbuf(s, r);
+ }
+}
+#endif
+
+LOCALFUNC blnr Sony_Insert0(FILE *refnum, blnr locked,
+ char *drivepath)
+{
+ tDrive Drive_No;
+ blnr IsOk = falseblnr;
+
+ if (! FirstFreeDisk(&Drive_No)) {
+ MacMsg(kStrTooManyImagesTitle, kStrTooManyImagesMessage,
+ falseblnr);
+ } else {
+ /* printf("Sony_Insert0 %d\n", (int)Drive_No); */
+
+ {
+ Drives[Drive_No] = refnum;
+ DiskInsertNotify(Drive_No, locked);
+
+#if IncludeSonyGetName || IncludeSonyNew
+ {
+ ui5b L = strlen(drivepath);
+ char *p = malloc(L + 1);
+ if (p != NULL) {
+ (void) memcpy(p, drivepath, L + 1);
+ }
+ DriveNames[Drive_No] = p;
+ }
+#endif
+
+ IsOk = trueblnr;
+ }
+ }
+
+ if (! IsOk) {
+ fclose(refnum);
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr Sony_Insert1(char *drivepath, blnr silentfail)
+{
+ blnr locked = falseblnr;
+ /* printf("Sony_Insert1 %s\n", drivepath); */
+ FILE *refnum = fopen(drivepath, "rb+");
+ if (NULL == refnum) {
+ locked = trueblnr;
+ refnum = fopen(drivepath, "rb");
+ CONSOLE_TRACE();
+ }
+ if (NULL == refnum) {
+ if (! silentfail) {
+ MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
+ CONSOLE_TRACE();
+ }
+ } else {
+ CONSOLE_TRACE();
+ return Sony_Insert0(refnum, locked, drivepath);
+ }
+
+ return falseblnr;
+}
+
+#define Sony_Insert2(s) Sony_Insert1(s, trueblnr)
+
+LOCALFUNC blnr Sony_InsertIth(int i)
+{
+ blnr v;
+
+ if ((i > 9) || ! FirstFreeDisk(nullpr)) {
+ v = falseblnr;
+ } else {
+ char s[] = "disk?.dsk";
+
+ s[4] = '0' + i;
+
+ v = Sony_Insert2(s);
+ }
+
+ return v;
+}
+
+LOCALFUNC blnr LoadInitialImages(void)
+{
+ int i;
+
+ CONSOLE_TRACE();
+
+ for (i = 1; Sony_InsertIth(i); ++i) {
+ /* stop on first error (including file not found) */
+ }
+
+ return trueblnr;
+}
+
+#if IncludeSonyNew
+LOCALFUNC blnr WriteZero(FILE *refnum, ui5b L)
+{
+#define ZeroBufferSize 2048
+ ui5b i;
+ ui3b buffer[ZeroBufferSize];
+
+ memset(&buffer, 0, ZeroBufferSize);
+
+ while (L > 0) {
+ i = (L > ZeroBufferSize) ? ZeroBufferSize : L;
+ if (fwrite(buffer, 1, i, refnum) != i) {
+ return falseblnr;
+ }
+ L -= i;
+ }
+ return trueblnr;
+}
+#endif
+
+#if IncludeSonyNew
+LOCALPROC MakeNewDisk(ui5b L, char *drivepath)
+{
+ blnr IsOk = falseblnr;
+ FILE *refnum = fopen(drivepath, "wb+");
+ if (NULL == refnum) {
+ MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
+ } else {
+ if (WriteZero(refnum, L)) {
+ IsOk = Sony_Insert0(refnum, falseblnr, drivepath);
+ refnum = NULL;
+ }
+ if (refnum != NULL) {
+ fclose(refnum);
+ }
+ if (! IsOk) {
+ (void) remove(drivepath);
+ }
+ }
+}
+#endif
+
+#if IncludeSonyNew
+LOCALPROC MakeNewDiskAtDefault(ui5b L)
+{
+ char s[ClStrMaxLength + 1];
+
+ NativeStrFromCStr(s, "untitled.dsk");
+ MakeNewDisk(L, s);
+}
+#endif
+
+/* --- ROM --- */
+
+LOCALFUNC tMacErr LoadMacRomFrom(char *path)
+{
+ tMacErr err;
+ FILE *ROM_File;
+ int File_Size;
+
+ ROM_File = fopen(path, "rb");
+ if (NULL == ROM_File) {
+ err = mnvm_fnfErr;
+ } else {
+ File_Size = fread(ROM, 1, kROM_Size, ROM_File);
+ if (kROM_Size != File_Size) {
+ if (feof(ROM_File)) {
+ MacMsgOverride(kStrShortROMTitle,
+ kStrShortROMMessage);
+ err = mnvm_eofErr;
+ } else {
+ MacMsgOverride(kStrNoReadROMTitle,
+ kStrNoReadROMMessage);
+ err = mnvm_miscErr;
+ }
+ } else {
+ err = ROM_IsValid();
+ }
+ fclose(ROM_File);
+ }
+
+ return err;
+}
+
+LOCALFUNC blnr LoadMacRom(void)
+{
+ tMacErr err;
+
+ if (mnvm_fnfErr == (err = LoadMacRomFrom(RomFileName)))
+ {
+ }
+
+ return trueblnr; /* keep launching Mini vMac, regardless */
+}
+
+/* --- video out --- */
+
+#if MayFullScreen
+LOCALVAR short hOffset;
+LOCALVAR short vOffset;
+#endif
+
+#if VarFullScreen
+LOCALVAR blnr UseFullScreen = (WantInitFullScreen != 0);
+#endif
+
+#if EnableMagnify
+LOCALVAR blnr UseMagnify = (WantInitMagnify != 0);
+#endif
+
+LOCALVAR blnr CurSpeedStopped = trueblnr;
+
+#if EnableMagnify
+#define MaxScale MyWindowScale
+#else
+#define MaxScale 1
+#endif
+
+LOCALPROC HaveChangedScreenBuff(ui4r top, ui4r left,
+ ui4r bottom, ui4r right)
+{
+ /*
+ Oh god, clean this up.
+ */
+ u8 *octpix = NULL;
+ u32 *vram = NULL;
+
+ octpix = (u8 *)GetCurDrawBuff();
+ vram = (u32 *)BG_BMP_RAM(0);
+
+ octpix += ((top * vMacScreenWidth ) >> 3);
+ vram += ((top * vMacScreenWidth ) >> 2);
+
+ FB1BPPtoIndexed(vram, octpix,
+ ((bottom - top) * vMacScreenWidth) >> 3);
+}
+
+LOCALPROC MyDrawChangesAndClear(void)
+{
+ if (ScreenChangedBottom > ScreenChangedTop) {
+ HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft,
+ ScreenChangedBottom, ScreenChangedRight);
+ ScreenClearChanges();
+ }
+}
+
+GLOBALOSGLUPROC DoneWithDrawingForTick(void)
+{
+#if 0 && EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ AutoScrollScreen();
+ }
+#endif
+ MyDrawChangesAndClear();
+}
+
+/* --- mouse --- */
+
+/* cursor state */
+
+LOCALPROC CheckMouseState(void)
+{
+ si5b MotionX;
+ si5b MotionY;
+
+ /*
+ TODO:
+
+ - Don't hardcode motion values
+ - Acceleration?
+ - Allow key remapping
+ - Handle touchscreen input (non-mouse motion)
+ - Handle touchscreen input (trackpad style mouse motion)
+ */
+
+ if (0 != (KeysHeld & KEY_LEFT)) {
+ MotionX = -4;
+ } else if (0 != (KeysHeld & KEY_RIGHT)) {
+ MotionX = 4;
+ }
+
+ if (0 != (KeysHeld & KEY_UP)) {
+ MotionY = -4;
+ } else if (0 != (KeysHeld & KEY_DOWN)) {
+ MotionY = 4;
+ }
+
+ HaveMouseMotion = trueblnr;
+
+ MyMousePositionSetDelta(MotionX, MotionY);
+ MyMouseButtonSet(0 != (KeysHeld & KEY_A));
+}
+
+/* --- keyboard input --- */
+
+LOCALVAR ui3b KC2MKC[256];
+
+/*
+ AHA!
+ GCC Was turning this into a macro of some sort which of course
+ broke horribly with libnds's keyboard having some negative values.
+*/
+LOCALPROC AssignKeyToMKC(int UKey, int LKey, ui3r MKC)
+{
+ if (UKey != NOKEY) {
+ KC2MKC[UKey] = MKC;
+ }
+
+ if (LKey != NOKEY) {
+ KC2MKC[LKey] = MKC;
+ }
+}
+
+LOCALFUNC blnr KC2MKCInit(void)
+{
+ int i;
+
+ for (i = 0; i < 256; ++i) {
+ KC2MKC[i] = MKC_None;
+ }
+
+ AssignKeyToMKC('A', 'a', MKC_A);
+ AssignKeyToMKC('B', 'b', MKC_B);
+ AssignKeyToMKC('C', 'c', MKC_C);
+ AssignKeyToMKC('D', 'd', MKC_D);
+ AssignKeyToMKC('E', 'e', MKC_E);
+ AssignKeyToMKC('F', 'f', MKC_F);
+ AssignKeyToMKC('G', 'g', MKC_G);
+ AssignKeyToMKC('H', 'h', MKC_H);
+ AssignKeyToMKC('I', 'i', MKC_I);
+ AssignKeyToMKC('J', 'j', MKC_J);
+ AssignKeyToMKC('K', 'k', MKC_K);
+ AssignKeyToMKC('L', 'l', MKC_L);
+ AssignKeyToMKC('M', 'm', MKC_M);
+ AssignKeyToMKC('N', 'n', MKC_N);
+ AssignKeyToMKC('O', 'o', MKC_O);
+ AssignKeyToMKC('P', 'p', MKC_P);
+ AssignKeyToMKC('Q', 'q', MKC_Q);
+ AssignKeyToMKC('R', 'r', MKC_R);
+ AssignKeyToMKC('S', 's', MKC_S);
+ AssignKeyToMKC('T', 't', MKC_T);
+ AssignKeyToMKC('U', 'u', MKC_U);
+ AssignKeyToMKC('V', 'v', MKC_V);
+ AssignKeyToMKC('W', 'w', MKC_W);
+ AssignKeyToMKC('X', 'x', MKC_X);
+ AssignKeyToMKC('Y', 'y', MKC_Y);
+ AssignKeyToMKC('Z', 'z', MKC_Z);
+
+ AssignKeyToMKC(')', '0', MKC_0);
+ AssignKeyToMKC('!', '1', MKC_1);
+ AssignKeyToMKC('@', '2', MKC_2);
+ AssignKeyToMKC('#', '3', MKC_3);
+ AssignKeyToMKC('$', '4', MKC_4);
+ AssignKeyToMKC('%', '5', MKC_5);
+ AssignKeyToMKC('^', '6', MKC_6);
+ AssignKeyToMKC('&', '7', MKC_7);
+ AssignKeyToMKC('*', '8', MKC_8);
+ AssignKeyToMKC('(', '9', MKC_9);
+
+ AssignKeyToMKC('~', '`', MKC_formac_Grave);
+ AssignKeyToMKC('_', '-', MKC_Minus);
+ AssignKeyToMKC('+', '=', MKC_Equal);
+ AssignKeyToMKC(':', ';', MKC_SemiColon);
+ AssignKeyToMKC('\"', '\'', MKC_SingleQuote);
+ AssignKeyToMKC('{', '[', MKC_LeftBracket);
+ AssignKeyToMKC('}', ']', MKC_RightBracket);
+ AssignKeyToMKC('|', '\\', MKC_formac_BackSlash);
+ AssignKeyToMKC('<', ',', MKC_Comma);
+ AssignKeyToMKC('>', '.', MKC_Period);
+ AssignKeyToMKC('?', '/', MKC_formac_Slash);
+
+ AssignKeyToMKC(NOKEY, DVK_SPACE, MKC_Space);
+ AssignKeyToMKC(NOKEY, DVK_BACKSPACE, MKC_BackSpace);
+ AssignKeyToMKC(NOKEY, DVK_ENTER, MKC_formac_Enter);
+ AssignKeyToMKC(NOKEY, DVK_TAB, MKC_Tab);
+
+ InitKeyCodes();
+
+ return trueblnr;
+}
+
+LOCALPROC DoKeyCode0(int i, blnr down)
+{
+ ui3r key = KC2MKC[i];
+ if (MKC_None != key) {
+ fprintf(stderr, "%s() :: %c (%d) == %d\n",
+ __FUNCTION__, (char) i, key, down);
+ Keyboard_UpdateKeyMap2(key, down);
+ }
+}
+
+LOCALPROC DoKeyCode(int i, blnr down)
+{
+ if ((i >= 0) && (i < 256)) {
+ DoKeyCode0(i, down);
+ }
+}
+
+/*
+ TODO:
+
+ Rethink keyboard input...
+ Especially shift and capslock, the libnds keyboard
+ is weird about those.
+*/
+
+LOCALVAR blnr DS_Keystate_Menu = falseblnr;
+LOCALVAR blnr DS_Keystate_Shift = falseblnr;
+
+LOCALPROC DS_HandleKey(si5b Key, blnr Down)
+{
+ if (Key == NOKEY) {
+ return;
+ }
+
+ switch (Key) {
+ case DVK_UP:
+ Keyboard_UpdateKeyMap2(MKC_Up, Down);
+ break;
+
+ case DVK_DOWN:
+ Keyboard_UpdateKeyMap2(MKC_Down, Down);
+ break;
+
+ case DVK_LEFT:
+ Keyboard_UpdateKeyMap2(MKC_Left, Down);
+ break;
+
+ case DVK_RIGHT:
+ Keyboard_UpdateKeyMap2(MKC_Right, Down);
+ break;
+
+ case DVK_SHIFT:
+ Keyboard_UpdateKeyMap2(MKC_formac_Shift, trueblnr);
+ break;
+
+ default:
+ if (Key > 0) {
+ DoKeyCode(Key, Down);
+ Keyboard_UpdateKeyMap2(MKC_formac_Shift, falseblnr);
+ }
+ break;
+ }
+}
+
+LOCALPROC DS_HandleKeyboard(void)
+{
+ LastKeyboardKey = KeyboardKey;
+ KeyboardKey = keyboardUpdate();
+
+ if ((KeyboardKey == NOKEY) && (LastKeyboardKey != NOKEY)) {
+ DS_HandleKey(LastKeyboardKey, falseblnr);
+ LastKeyboardKey = NOKEY;
+ } else {
+ DS_HandleKey(KeyboardKey, trueblnr);
+ LastKeyboardKey = KeyboardKey;
+ }
+}
+
+/* --- time, date, location --- */
+
+LOCALVAR ui5b TrueEmulatedTime = 0;
+
+#include "DATE2SEC.h"
+
+#define TicksPerSecond 1000000
+/* #define TicksPerSecond 1000 */
+
+LOCALVAR blnr HaveTimeDelta = falseblnr;
+LOCALVAR ui5b TimeDelta;
+
+LOCALVAR ui5b NewMacDateInSeconds;
+
+LOCALVAR ui5b LastTimeSec;
+LOCALVAR ui5b LastTimeUsec;
+
+LOCALPROC GetCurrentTicks(void)
+{
+ struct timeval t;
+
+ gettimeofday(&t, NULL);
+
+ /*
+ HACKHACKHACK
+ */
+ t.tv_usec = TimerBaseMSec + TIMER1_DATA;
+ t.tv_usec = t.tv_usec * 1000;
+
+ if (! HaveTimeDelta) {
+ time_t Current_Time;
+ struct tm *s;
+
+ (void) time(&Current_Time);
+ s = localtime(&Current_Time);
+ TimeDelta = Date2MacSeconds(s->tm_sec, s->tm_min, s->tm_hour,
+ s->tm_mday, 1 + s->tm_mon, 1900 + s->tm_year) - t.tv_sec;
+#if 0 && AutoTimeZone /* how portable is this ? */
+ CurMacDelta = ((ui5b)(s->tm_gmtoff) & 0x00FFFFFF)
+ | ((s->tm_isdst ? 0x80 : 0) << 24);
+#endif
+ HaveTimeDelta = trueblnr;
+ }
+
+ NewMacDateInSeconds = t.tv_sec + TimeDelta;
+ LastTimeSec = (ui5b)t.tv_sec;
+ LastTimeUsec = (ui5b)t.tv_usec;
+}
+
+/* #define MyInvTimeStep 16626 */ /* TicksPerSecond / 60.14742 */
+#define MyInvTimeStep 17
+
+LOCALVAR ui5b NextTimeSec;
+LOCALVAR ui5b NextTimeUsec;
+
+LOCALPROC IncrNextTime(void)
+{
+ NextTimeUsec += MyInvTimeStep;
+ if (NextTimeUsec >= TicksPerSecond) {
+ NextTimeUsec -= TicksPerSecond;
+ NextTimeSec += 1;
+ }
+}
+
+LOCALPROC InitNextTime(void)
+{
+ NextTimeSec = LastTimeSec;
+ NextTimeUsec = LastTimeUsec;
+ IncrNextTime();
+}
+
+LOCALPROC StartUpTimeAdjust(void)
+{
+ GetCurrentTicks();
+ InitNextTime();
+}
+
+LOCALFUNC si5b GetTimeDiff(void)
+{
+ return ((si5b)(LastTimeSec - NextTimeSec)) * TicksPerSecond
+ + ((si5b)(LastTimeUsec - NextTimeUsec));
+}
+
+LOCALPROC UpdateTrueEmulatedTime(void)
+{
+ si5b TimeDiff;
+
+ GetCurrentTicks();
+
+ TimeDiff = GetTimeDiff();
+ if (TimeDiff >= 0) {
+ if (TimeDiff > 4 * MyInvTimeStep) {
+ /* emulation interrupted, forget it */
+ ++TrueEmulatedTime;
+ InitNextTime();
+ } else {
+ do {
+ ++TrueEmulatedTime;
+ IncrNextTime();
+ TimeDiff -= TicksPerSecond;
+ } while (TimeDiff >= 0);
+ }
+ } else if (TimeDiff < - 2 * MyInvTimeStep) {
+ /* clock goofed if ever get here, reset */
+ InitNextTime();
+ }
+}
+
+LOCALFUNC blnr CheckDateTime(void)
+{
+ if (CurMacDateInSeconds != NewMacDateInSeconds) {
+ CurMacDateInSeconds = NewMacDateInSeconds;
+ return trueblnr;
+ } else {
+ return falseblnr;
+ }
+}
+
+LOCALFUNC blnr InitLocationDat(void)
+{
+ GetCurrentTicks();
+ CurMacDateInSeconds = NewMacDateInSeconds;
+
+ return trueblnr;
+}
+
+/* --- basic dialogs --- */
+
+LOCALPROC CheckSavedMacMsg(void)
+{
+ /* called only on quit, if error saved but not yet reported */
+
+ if (nullpr != SavedBriefMsg) {
+ char briefMsg0[ClStrMaxLength + 1];
+ char longMsg0[ClStrMaxLength + 1];
+
+ NativeStrFromCStr(briefMsg0, SavedBriefMsg);
+ NativeStrFromCStr(longMsg0, SavedLongMsg);
+
+ fprintf(stderr, "%s\n", briefMsg0);
+ fprintf(stderr, "%s\n", longMsg0);
+
+ SavedBriefMsg = nullpr;
+ }
+}
+
+/* --- main window creation and disposal --- */
+
+/*
+ Screen_Init
+
+ Mode 5 gives us 2 text backgrounds 0-1 (tiled mode) and
+ 2 extended rotation backgrounds 2-3. (linear fb)
+
+ Also we need to map 2 banks of vram so we have enough space for
+ our 512x512 surface.
+*/
+LOCALFUNC blnr Screen_Init(void)
+{
+ videoSetMode(MODE_5_2D);
+ vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
+ vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
+
+ Display_bg2_Main = bgInit(2, BgType_Bmp8, BgSize_B8_512x512, 0, 0);
+
+ BG_PALETTE[0] = RGB15(31, 31, 31);
+ BG_PALETTE[1] = RGB15(0, 0, 0);
+
+ return trueblnr;
+}
+
+#if VarFullScreen
+LOCALPROC ToggleWantFullScreen(void)
+{
+ WantFullScreen = ! WantFullScreen;
+}
+#endif
+
+/* --- SavedTasks --- */
+
+LOCALPROC LeaveSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Start();
+#endif
+
+ StartUpTimeAdjust();
+}
+
+LOCALPROC EnterSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+}
+
+LOCALPROC CheckForSavedTasks(void)
+{
+ if (MyEvtQNeedRecover) {
+ MyEvtQNeedRecover = falseblnr;
+
+ /* attempt cleanup, MyEvtQNeedRecover may get set again */
+ MyEvtQTryRecoverFromFull();
+ }
+
+ if (RequestMacOff) {
+ RequestMacOff = falseblnr;
+ if (AnyDiskInserted()) {
+ MacMsgOverride(kStrQuitWarningTitle,
+ kStrQuitWarningMessage);
+ } else {
+ ForceMacOff = trueblnr;
+ }
+ }
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (CurSpeedStopped != SpeedStopped) {
+ CurSpeedStopped = ! CurSpeedStopped;
+ if (CurSpeedStopped) {
+ EnterSpeedStopped();
+ } else {
+ LeaveSpeedStopped();
+ }
+ }
+
+#if IncludeSonyNew
+ if (vSonyNewDiskWanted) {
+#if IncludeSonyNameNew
+ if (vSonyNewDiskName != NotAPbuf) {
+ ui3p NewDiskNameDat;
+ if (MacRomanTextToNativePtr(vSonyNewDiskName, trueblnr,
+ &NewDiskNameDat))
+ {
+ MakeNewDisk(vSonyNewDiskSize, (char *)NewDiskNameDat);
+ free(NewDiskNameDat);
+ }
+ PbufDispose(vSonyNewDiskName);
+ vSonyNewDiskName = NotAPbuf;
+ } else
+#endif
+ {
+ MakeNewDiskAtDefault(vSonyNewDiskSize);
+ }
+ vSonyNewDiskWanted = falseblnr;
+ /* must be done after may have gotten disk */
+ }
+#endif
+
+ if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) {
+ MacMsgDisplayOn();
+ }
+
+ if (NeedWholeScreenDraw) {
+ NeedWholeScreenDraw = falseblnr;
+ ScreenChangedAll();
+ }
+
+#if NeedRequestIthDisk
+ if (0 != RequestIthDisk) {
+ Sony_InsertIth(RequestIthDisk);
+ RequestIthDisk = 0;
+ }
+#endif
+}
+
+/* --- main program flow --- */
+
+GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void)
+{
+ UpdateTrueEmulatedTime();
+ return TrueEmulatedTime == OnTrueTime;
+}
+
+LOCALPROC WaitForTheNextEvent(void)
+{
+}
+
+LOCALPROC CheckForSystemEvents(void)
+{
+ DS_HandleKeyboard();
+}
+
+GLOBALOSGLUPROC WaitForNextTick(void)
+{
+label_retry:
+ CheckForSystemEvents();
+ CheckForSavedTasks();
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (CurSpeedStopped) {
+ MyDrawChangesAndClear();
+ WaitForTheNextEvent();
+ goto label_retry;
+ }
+
+ if (ExtraTimeNotOver()) {
+ si5b TimeDiff = GetTimeDiff();
+ if (TimeDiff < 0) {
+ /*
+ FIXME:
+
+ Implement this?
+
+ struct timespec rqt;
+ struct timespec rmt;
+
+ rqt.tv_sec = 0;
+ rqt.tv_nsec = (- TimeDiff) * 1000;
+
+ (void) nanosleep(&rqt, &rmt);
+ */
+ }
+ goto label_retry;
+ }
+
+ if (CheckDateTime()) {
+#if MySoundEnabled
+ MySound_SecondNotify();
+#endif
+#if EnableDemoMsg
+ DemoModeSecondNotify();
+#endif
+ }
+
+ CheckMouseState();
+
+ OnTrueTime = TrueEmulatedTime;
+}
+
+/*
+ DS_ScrollBackground:
+
+ Positions the screen as to center it over the emulated cursor.
+*/
+LOCALPROC DS_ScrollBackground(void)
+{
+ int ScrollX = 0;
+ int ScrollY = 0;
+ int Scale = 0;
+
+ /*
+ TODO:
+ Lots of magic numbers here.
+ */
+#if EnableMagnify
+ if (WantMagnify) {
+ ScrollX = ((int) CurMouseH) - (DS_ScreenWidth / 4);
+ ScrollY = ((int) CurMouseV) - (DS_ScreenHeight / 4);
+ Scale = 128;
+
+ ScrollX = ScrollX > vMacScreenWidth - (DS_ScreenWidth / 2)
+ ? vMacScreenWidth - (DS_ScreenWidth / 2)
+ : ScrollX;
+ ScrollY = ScrollY > vMacScreenHeight - (DS_ScreenHeight / 2)
+ ? vMacScreenHeight - (DS_ScreenHeight / 2)
+ : ScrollY;
+ } else
+#endif
+ {
+ ScrollX = ((int) CurMouseH) - (DS_ScreenWidth / 2);
+ ScrollY = ((int) CurMouseV) - (DS_ScreenHeight / 2);
+ Scale = 256;
+
+ ScrollX = ScrollX > vMacScreenWidth - DS_ScreenWidth
+ ? vMacScreenWidth - DS_ScreenWidth
+ : ScrollX;
+ ScrollY = ScrollY > vMacScreenHeight - DS_ScreenHeight
+ ? vMacScreenHeight - DS_ScreenHeight
+ : ScrollY;
+ }
+
+ ScrollX = ScrollX < 0 ? 0 : ScrollX;
+ ScrollY = ScrollY < 0 ? 0 : ScrollY;
+
+ if (Display_bg2_Main) {
+ bgSetScale(Display_bg2_Main, Scale, Scale);
+ bgSetScroll(Display_bg2_Main, ScrollX, ScrollY);
+ }
+}
+
+/*
+ DS_Timer1_IRQ
+
+ Called when TIMER0_DATA overflows.
+*/
+LOCALPROC DS_Timer1_IRQ(void)
+{
+ TimerBaseMSec += 65536;
+}
+
+/*
+ DS_VBlank_IRQ
+
+ Vertical blank interrupt callback.
+*/
+LOCALPROC DS_VBlank_IRQ(void)
+{
+ scanKeys();
+
+ KeysHeld = keysHeld();
+
+ if (++VBlankCounter == 60) {
+ VBlankCounter = 0;
+ }
+
+ /*
+ TODO:
+ Rewrite this at some point, I'm not sure I like it.
+ */
+ if (0 != (KeysHeld & KEY_LEFT)) {
+ --CursorX;
+ } else if (0 != (KeysHeld & KEY_RIGHT)) {
+ ++CursorX;
+ }
+
+ if (0 != (KeysHeld & KEY_UP)) {
+ --CursorY;
+ } else if (0 != (KeysHeld & KEY_DOWN)) {
+ ++CursorY;
+ }
+
+ CursorX = CursorX < 0 ? 0 : CursorX;
+ CursorX = CursorX > vMacScreenWidth ? vMacScreenWidth : CursorX;
+
+ CursorY = CursorY < 0 ? 0 : CursorY;
+ CursorY = CursorY > vMacScreenHeight ? vMacScreenHeight : CursorY;
+
+ DS_ScrollBackground();
+ bgUpdate();
+}
+
+/*
+ DS_HBlank_IRQ
+
+ Called at the start of the horizontal blanking period.
+ This is here mainly as a simple performance test.
+*/
+LOCALPROC DS_HBlank_IRQ(void)
+{
+ ++HBlankCounter;
+}
+
+/*
+ DS_SysInit
+
+ Initializes DS specific system hardware and interrupts.
+*/
+LOCALPROC DS_SysInit(void)
+{
+ defaultExceptionHandler();
+ powerOn(POWER_ALL_2D);
+ lcdMainOnTop();
+
+ irqSet(IRQ_VBLANK, DS_VBlank_IRQ);
+ irqSet(IRQ_HBLANK, DS_HBlank_IRQ);
+ irqSet(IRQ_TIMER1, DS_Timer1_IRQ);
+
+ irqEnable(IRQ_VBLANK);
+ irqEnable(IRQ_HBLANK);
+ irqEnable(IRQ_TIMER1);
+
+ /*
+ This sets up 2 timers as a milisecond counter.
+ TIMER0_DATA Will overflow roughly every 1 msec into TIMER1_DATA.
+ When TIMER1_DATA overflows an interrupt will be generated
+ and DS_Timer1_IRQ will be called.
+ */
+ TIMER0_DATA = 32768;
+
+ TIMER0_CR = TIMER_DIV_1 | TIMER_ENABLE;
+
+
+
+ TIMER1_DATA = 0;
+
+ TIMER1_CR = TIMER_ENABLE | TIMER_CASCADE | TIMER_IRQ_REQ;
+
+ /*
+ Testing.
+ */
+ consoleDemoInit();
+ consoleDebugInit(DebugDevice_NOCASH);
+
+ /*
+ Use the default keyboard until I design a (good) UI...
+ */
+ DSKeyboard = keyboardDemoInit();
+ keyboardShow();
+
+ /*
+ Drop back to a read only filesystem embedded in the
+ Mini vMac binary if we cannot open a media device.
+ */
+ if (! fatInitDefault()) {
+ nitroFSInit();
+ }
+}
+
+/*
+ DS_ClearVRAM:
+
+ Make sure all of the video memory and background/object palettes
+ are zeroed out just in-case the loader doesn't do it for us.
+*/
+LOCALPROC DS_ClearVRAM(void)
+{
+ vramSetPrimaryBanks(VRAM_A_LCD, VRAM_B_LCD, VRAM_C_LCD, VRAM_D_LCD);
+
+ dmaFillWords(0, (void *) VRAM_A, 128 * 1024 * 4);
+ dmaFillWords(0, (void *) BG_PALETTE, 256 * 2);
+ dmaFillWords(0, (void *) BG_PALETTE_SUB, 256 * 2);
+ dmaFillWords(0, (void *) SPRITE_PALETTE, 256 * 2);
+ dmaFillWords(0, (void *) SPRITE_PALETTE_SUB, 256 * 2);
+
+ vramDefault();
+}
+
+/* --- platform independent code can be thought of as going here --- */
+
+#include "PROGMAIN.h"
+
+LOCALPROC ReserveAllocAll(void)
+{
+#if dbglog_HAVE
+ dbglog_ReserveAlloc();
+#endif
+ ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr);
+
+ ReserveAllocOneBlock(&screencomparebuff,
+ vMacScreenNumBytes, 5, trueblnr);
+#if UseControlKeys
+ ReserveAllocOneBlock(&CntrlDisplayBuff,
+ vMacScreenNumBytes, 5, falseblnr);
+#endif
+
+#if MySoundEnabled
+ ReserveAllocOneBlock((ui3p *)&TheSoundBuffer,
+ dbhBufferSize, 5, falseblnr);
+#endif
+
+ EmulationReserveAlloc();
+}
+
+LOCALFUNC blnr AllocMyMemory(void)
+{
+ uimr n;
+ blnr IsOk = falseblnr;
+
+ ReserveAllocOffset = 0;
+ ReserveAllocBigBlock = nullpr;
+ ReserveAllocAll();
+ n = ReserveAllocOffset;
+ ReserveAllocBigBlock = (ui3p)calloc(1, n);
+ if (NULL == ReserveAllocBigBlock) {
+ MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr);
+ } else {
+ ReserveAllocOffset = 0;
+ ReserveAllocAll();
+ if (n != ReserveAllocOffset) {
+ /* oops, program error */
+ } else {
+ IsOk = trueblnr;
+ }
+ }
+
+ return IsOk;
+}
+
+LOCALPROC UnallocMyMemory(void)
+{
+ if (nullpr != ReserveAllocBigBlock) {
+ free((char *)ReserveAllocBigBlock);
+ }
+}
+
+LOCALPROC ZapOSGLUVars(void)
+{
+ InitDrives();
+ DS_ClearVRAM();
+}
+
+LOCALFUNC blnr InitOSGLU(void)
+{
+ DS_SysInit();
+
+ if (AllocMyMemory())
+#if dbglog_HAVE
+ if (dbglog_open())
+#endif
+ if (LoadMacRom())
+ if (LoadInitialImages())
+ if (InitLocationDat())
+#if MySoundEnabled
+ if (MySound_Init())
+#endif
+ if (Screen_Init())
+ if (KC2MKCInit())
+ if (WaitForRom())
+ {
+ return trueblnr;
+ }
+
+ return falseblnr;
+}
+
+LOCALPROC UnInitOSGLU(void)
+{
+ if (MacMsgDisplayed) {
+ MacMsgDisplayOff();
+ }
+
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+#if MySoundEnabled
+ MySound_UnInit();
+#endif
+
+ UnInitDrives();
+
+#if dbglog_HAVE
+ dbglog_close();
+#endif
+
+ UnallocMyMemory();
+ CheckSavedMacMsg();
+}
+
+int main(int argc, char **argv)
+{
+ ZapOSGLUVars();
+
+ if (InitOSGLU()) {
+ iprintf("Entering ProgramMain...\n");
+
+ ProgramMain();
+
+ iprintf("Leaving ProgramMain...\n");
+ }
+
+ UnInitOSGLU();
+
+ /*
+ On some homebrew launchers this could return to
+ the menu by default.
+ */
+ exit(1);
+
+ while (1) {
+ swiWaitForVBlank();
+ }
+
+ return 0;
+}
--- /dev/null
+++ b/src/OSGLUOSX.c
@@ -1,0 +1,5564 @@
+/*
+ OSGLUOSX.c
+
+ Copyright (C) 2009 Philip Cummins, Richard F. Bannister,
+ Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Operating System GLUe for macintosh OS X
+
+ All operating system dependent code for the
+ Macintosh platform should go here.
+
+ This code is descended from Richard F. Bannister's Macintosh
+ port of vMac, by Philip Cummins.
+
+ The main entry point 'main' is at the end of this file.
+*/
+
+#include "CNFGRAPI.h"
+#include "SYSDEPNS.h"
+#include "ENDIANAC.h"
+
+#include "MYOSGLUE.h"
+
+/* --- adapting to API/ABI version differences --- */
+
+/*
+ if UsingCarbonLib, instead of native Macho,
+ then some APIs are missing
+*/
+#ifndef UsingCarbonLib
+#define UsingCarbonLib 0
+#endif
+
+LOCALVAR CFBundleRef AppServBunRef;
+
+LOCALVAR blnr DidApplicationServicesBun = falseblnr;
+
+LOCALFUNC blnr HaveApplicationServicesBun(void)
+{
+ if (! DidApplicationServicesBun) {
+ AppServBunRef = CFBundleGetBundleWithIdentifier(
+ CFSTR("com.apple.ApplicationServices"));
+ DidApplicationServicesBun = trueblnr;
+ }
+ return (AppServBunRef != NULL);
+}
+
+#if MayFullScreen || UsingCarbonLib
+
+LOCALVAR CFBundleRef HIToolboxBunRef;
+
+LOCALVAR blnr DidHIToolboxBunRef = falseblnr;
+
+LOCALFUNC blnr HaveHIToolboxBunRef(void)
+{
+ if (! DidHIToolboxBunRef) {
+ HIToolboxBunRef = CFBundleGetBundleWithIdentifier(
+ CFSTR("com.apple.HIToolbox"));
+ DidHIToolboxBunRef = trueblnr;
+ }
+ return (HIToolboxBunRef != NULL);
+}
+
+#endif
+
+LOCALVAR CFBundleRef AGLBunRef;
+
+LOCALVAR blnr DidAGLBunRef = falseblnr;
+
+LOCALFUNC blnr HaveAGLBunRef(void)
+{
+ if (! DidAGLBunRef) {
+ AGLBunRef = CFBundleGetBundleWithIdentifier(
+ CFSTR("com.apple.agl"));
+ DidAGLBunRef = trueblnr;
+ }
+ return (AGLBunRef != NULL);
+}
+
+
+#if MayFullScreen
+
+/* SetSystemUIModeProcPtr API always not available */
+
+typedef UInt32 MySystemUIMode;
+typedef OptionBits MySystemUIOptions;
+
+enum {
+ MykUIModeNormal = 0,
+ MykUIModeAllHidden = 3
+};
+
+enum {
+ MykUIOptionAutoShowMenuBar = 1 << 0,
+ MykUIOptionDisableAppleMenu = 1 << 2,
+ MykUIOptionDisableProcessSwitch = 1 << 3,
+ MykUIOptionDisableForceQuit = 1 << 4,
+ MykUIOptionDisableSessionTerminate = 1 << 5,
+ MykUIOptionDisableHide = 1 << 6
+};
+
+typedef OSStatus (*SetSystemUIModeProcPtr)
+ (MySystemUIMode inMode, MySystemUIOptions inOptions);
+LOCALVAR SetSystemUIModeProcPtr MySetSystemUIMode = NULL;
+LOCALVAR blnr DidSetSystemUIMode = falseblnr;
+
+LOCALFUNC blnr HaveMySetSystemUIMode(void)
+{
+ if (! DidSetSystemUIMode) {
+ if (HaveHIToolboxBunRef()) {
+ MySetSystemUIMode =
+ (SetSystemUIModeProcPtr)
+ CFBundleGetFunctionPointerForName(
+ HIToolboxBunRef, CFSTR("SetSystemUIMode"));
+ }
+ DidSetSystemUIMode = trueblnr;
+ }
+ return (MySetSystemUIMode != NULL);
+}
+
+#endif
+
+/* In 10.1 or later */
+
+typedef OSStatus (*LSCopyDisplayNameForRefProcPtr)
+ (const FSRef *inRef, CFStringRef *outDisplayName);
+LOCALVAR LSCopyDisplayNameForRefProcPtr MyLSCopyDisplayNameForRef
+ = NULL;
+LOCALVAR blnr DidLSCopyDisplayNameForRef = falseblnr;
+
+LOCALFUNC blnr HaveMyLSCopyDisplayNameForRef(void)
+{
+ if (! DidLSCopyDisplayNameForRef) {
+ if (HaveApplicationServicesBun()) {
+ MyLSCopyDisplayNameForRef =
+ (LSCopyDisplayNameForRefProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("LSCopyDisplayNameForRef"));
+ }
+ DidLSCopyDisplayNameForRef = trueblnr;
+ }
+ return (MyLSCopyDisplayNameForRef != NULL);
+}
+
+/* In 10.5 or later */
+
+typedef GLboolean (*aglSetWindowRefProcPtr)
+ (AGLContext ctx, WindowRef window);
+LOCALVAR aglSetWindowRefProcPtr MyaglSetWindowRef = NULL;
+LOCALVAR blnr DidaglSetWindowRef = falseblnr;
+
+LOCALFUNC blnr HaveMyaglSetWindowRef(void)
+{
+ if (! DidaglSetWindowRef) {
+ if (HaveAGLBunRef()) {
+ MyaglSetWindowRef =
+ (aglSetWindowRefProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AGLBunRef, CFSTR("aglSetWindowRef"));
+ }
+ DidaglSetWindowRef = trueblnr;
+ }
+ return (MyaglSetWindowRef != NULL);
+}
+
+/* Deprecated as of 10.5 */
+
+typedef CGrafPtr My_AGLDrawable;
+typedef GLboolean (*aglSetDrawableProcPtr)
+ (AGLContext ctx, My_AGLDrawable draw);
+LOCALVAR aglSetDrawableProcPtr MyaglSetDrawable = NULL;
+LOCALVAR blnr DidaglSetDrawable = falseblnr;
+
+LOCALFUNC blnr HaveMyaglSetDrawable(void)
+{
+ if (! DidaglSetDrawable) {
+ if (HaveAGLBunRef()) {
+ MyaglSetDrawable =
+ (aglSetDrawableProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AGLBunRef, CFSTR("aglSetDrawable"));
+ }
+ DidaglSetDrawable = trueblnr;
+ }
+ return (MyaglSetDrawable != NULL);
+}
+
+/* routines not in carbon lib */
+
+
+#if UsingCarbonLib
+
+typedef CGDisplayErr
+(*CGGetActiveDisplayListProcPtr) (
+ CGDisplayCount maxDisplays,
+ CGDirectDisplayID * activeDspys,
+ CGDisplayCount * dspyCnt);
+LOCALVAR CGGetActiveDisplayListProcPtr MyCGGetActiveDisplayList = NULL;
+LOCALVAR blnr DidCGGetActiveDisplayList = falseblnr;
+
+LOCALFUNC blnr HaveMyCGGetActiveDisplayList(void)
+{
+ if (! DidCGGetActiveDisplayList) {
+ if (HaveApplicationServicesBun()) {
+ MyCGGetActiveDisplayList =
+ (CGGetActiveDisplayListProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("CGGetActiveDisplayList"));
+ }
+ DidCGGetActiveDisplayList = trueblnr;
+ }
+ return (MyCGGetActiveDisplayList != NULL);
+}
+
+#else
+
+#define HaveMyCGGetActiveDisplayList() trueblnr
+#define MyCGGetActiveDisplayList CGGetActiveDisplayList
+
+#endif /* ! UsingCarbonLib */
+
+
+#if UsingCarbonLib
+
+typedef CGRect
+(*CGDisplayBoundsProcPtr) (CGDirectDisplayID display);
+LOCALVAR CGDisplayBoundsProcPtr MyCGDisplayBounds = NULL;
+LOCALVAR blnr DidCGDisplayBounds = falseblnr;
+
+LOCALFUNC blnr HaveMyCGDisplayBounds(void)
+{
+ if (! DidCGDisplayBounds) {
+ if (HaveApplicationServicesBun()) {
+ MyCGDisplayBounds =
+ (CGDisplayBoundsProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("CGDisplayBounds"));
+ }
+ DidCGDisplayBounds = trueblnr;
+ }
+ return (MyCGDisplayBounds != NULL);
+}
+
+#else
+
+#define HaveMyCGDisplayBounds() trueblnr
+#define MyCGDisplayBounds CGDisplayBounds
+
+#endif /* ! UsingCarbonLib */
+
+
+#if UsingCarbonLib
+
+typedef size_t
+(*CGDisplayPixelsWideProcPtr) (CGDirectDisplayID display);
+LOCALVAR CGDisplayPixelsWideProcPtr MyCGDisplayPixelsWide = NULL;
+LOCALVAR blnr DidCGDisplayPixelsWide = falseblnr;
+
+LOCALFUNC blnr HaveMyCGDisplayPixelsWide(void)
+{
+ if (! DidCGDisplayPixelsWide) {
+ if (HaveApplicationServicesBun()) {
+ MyCGDisplayPixelsWide =
+ (CGDisplayPixelsWideProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("CGDisplayPixelsWide"));
+ }
+ DidCGDisplayPixelsWide = trueblnr;
+ }
+ return (MyCGDisplayPixelsWide != NULL);
+}
+
+#else
+
+#define HaveMyCGDisplayPixelsWide() trueblnr
+#define MyCGDisplayPixelsWide CGDisplayPixelsWide
+
+#endif /* ! UsingCarbonLib */
+
+
+#if UsingCarbonLib
+
+typedef size_t
+(*CGDisplayPixelsHighProcPtr) (CGDirectDisplayID display);
+LOCALVAR CGDisplayPixelsHighProcPtr MyCGDisplayPixelsHigh = NULL;
+LOCALVAR blnr DidCGDisplayPixelsHigh = falseblnr;
+
+LOCALFUNC blnr HaveMyCGDisplayPixelsHigh(void)
+{
+ if (! DidCGDisplayPixelsHigh) {
+ if (HaveApplicationServicesBun()) {
+ MyCGDisplayPixelsHigh =
+ (CGDisplayPixelsHighProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("CGDisplayPixelsHigh"));
+ }
+ DidCGDisplayPixelsHigh = trueblnr;
+ }
+ return (MyCGDisplayPixelsHigh != NULL);
+}
+
+#else
+
+#define HaveMyCGDisplayPixelsHigh() trueblnr
+#define MyCGDisplayPixelsHigh CGDisplayPixelsHigh
+
+#endif /* ! UsingCarbonLib */
+
+
+#if UsingCarbonLib
+
+typedef CGDisplayErr
+(*CGDisplayHideCursorProcPtr) (CGDirectDisplayID display);
+LOCALVAR CGDisplayHideCursorProcPtr MyCGDisplayHideCursor = NULL;
+LOCALVAR blnr DidCGDisplayHideCursor = falseblnr;
+
+LOCALFUNC blnr HaveMyCGDisplayHideCursor(void)
+{
+ if (! DidCGDisplayHideCursor) {
+ if (HaveApplicationServicesBun()) {
+ MyCGDisplayHideCursor =
+ (CGDisplayHideCursorProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("CGDisplayHideCursor"));
+ }
+ DidCGDisplayHideCursor = trueblnr;
+ }
+ return (MyCGDisplayHideCursor != NULL);
+}
+
+#else
+
+#define HaveMyCGDisplayHideCursor() trueblnr
+#define MyCGDisplayHideCursor CGDisplayHideCursor
+
+#endif /* ! UsingCarbonLib */
+
+
+#if UsingCarbonLib
+
+typedef CGDisplayErr
+(*CGDisplayShowCursorProcPtr) (CGDirectDisplayID display);
+LOCALVAR CGDisplayShowCursorProcPtr MyCGDisplayShowCursor = NULL;
+LOCALVAR blnr DidCGDisplayShowCursor = falseblnr;
+
+LOCALFUNC blnr HaveMyCGDisplayShowCursor(void)
+{
+ if (! DidCGDisplayShowCursor) {
+ if (HaveApplicationServicesBun()) {
+ MyCGDisplayShowCursor =
+ (CGDisplayShowCursorProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("CGDisplayShowCursor"));
+ }
+ DidCGDisplayShowCursor = trueblnr;
+ }
+ return (MyCGDisplayShowCursor != NULL);
+}
+
+#else
+
+#define HaveMyCGDisplayShowCursor() trueblnr
+#define MyCGDisplayShowCursor CGDisplayShowCursor
+
+#endif /* ! UsingCarbonLib */
+
+
+#if 0
+
+typedef CGDisplayErr (*CGDisplayMoveCursorToPointProcPtr)
+ (CGDirectDisplayID display, CGPoint point);
+LOCALVAR CGDisplayMoveCursorToPointProcPtr MyCGDisplayMoveCursorToPoint
+ = NULL;
+LOCALVAR blnr DidCGDisplayMoveCursorToPoint = falseblnr;
+
+LOCALFUNC blnr HaveMyCGDisplayMoveCursorToPoint(void)
+{
+ if (! DidCGDisplayMoveCursorToPoint) {
+ if (HaveApplicationServicesBun()) {
+ MyCGDisplayMoveCursorToPoint =
+ (CGDisplayMoveCursorToPointProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("CGDisplayMoveCursorToPoint"));
+ }
+ DidCGDisplayMoveCursorToPoint = trueblnr;
+ }
+ return (MyCGDisplayMoveCursorToPoint != NULL);
+}
+
+#endif /* 0 */
+
+
+#if UsingCarbonLib
+
+typedef CGEventErr
+(*CGWarpMouseCursorPositionProcPtr) (CGPoint newCursorPosition);
+LOCALVAR CGWarpMouseCursorPositionProcPtr MyCGWarpMouseCursorPosition
+ = NULL;
+LOCALVAR blnr DidCGWarpMouseCursorPosition = falseblnr;
+
+LOCALFUNC blnr HaveMyCGWarpMouseCursorPosition(void)
+{
+ if (! DidCGWarpMouseCursorPosition) {
+ if (HaveApplicationServicesBun()) {
+ MyCGWarpMouseCursorPosition =
+ (CGWarpMouseCursorPositionProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("CGWarpMouseCursorPosition"));
+ }
+ DidCGWarpMouseCursorPosition = trueblnr;
+ }
+ return (MyCGWarpMouseCursorPosition != NULL);
+}
+
+#else
+
+#define HaveMyCGWarpMouseCursorPosition() trueblnr
+#define MyCGWarpMouseCursorPosition CGWarpMouseCursorPosition
+
+#endif /* ! UsingCarbonLib */
+
+
+#if UsingCarbonLib
+
+typedef CGEventErr
+(*CGSetLocalEventsSuppressionIntervalProcPtr) (CFTimeInterval seconds);
+LOCALVAR CGSetLocalEventsSuppressionIntervalProcPtr
+ MyCGSetLocalEventsSuppressionInterval = NULL;
+LOCALVAR blnr DidCGSetLocalEventsSuppressionInterval = falseblnr;
+
+LOCALFUNC blnr HaveMyCGSetLocalEventsSuppressionInterval(void)
+{
+ if (! DidCGSetLocalEventsSuppressionInterval) {
+ if (HaveApplicationServicesBun()) {
+ MyCGSetLocalEventsSuppressionInterval =
+ (CGSetLocalEventsSuppressionIntervalProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef,
+ CFSTR("CGSetLocalEventsSuppressionInterval"));
+ }
+ DidCGSetLocalEventsSuppressionInterval = trueblnr;
+ }
+ return (MyCGSetLocalEventsSuppressionInterval != NULL);
+}
+
+#else
+
+#define HaveMyCGSetLocalEventsSuppressionInterval() trueblnr
+#define MyCGSetLocalEventsSuppressionInterval \
+ CGSetLocalEventsSuppressionInterval
+
+#endif /* ! UsingCarbonLib */
+
+
+#if UsingCarbonLib
+
+typedef OSStatus (*CreateStandardAlertProcPtr) (
+ AlertType alertType,
+ CFStringRef error,
+ CFStringRef explanation,
+ const AlertStdCFStringAlertParamRec * param,
+ DialogRef * outAlert
+);
+LOCALVAR CreateStandardAlertProcPtr MyCreateStandardAlert = NULL;
+LOCALVAR blnr DidCreateStandardAlert = falseblnr;
+
+LOCALFUNC blnr HaveMyCreateStandardAlert(void)
+{
+ if (! DidCreateStandardAlert) {
+ if (HaveHIToolboxBunRef()) {
+ MyCreateStandardAlert =
+ (CreateStandardAlertProcPtr)
+ CFBundleGetFunctionPointerForName(
+ HIToolboxBunRef, CFSTR("CreateStandardAlert"));
+ }
+ DidCreateStandardAlert = trueblnr;
+ }
+ return (MyCreateStandardAlert != NULL);
+}
+
+#else
+
+#define HaveMyCreateStandardAlert() trueblnr
+#define MyCreateStandardAlert CreateStandardAlert
+
+#endif /* ! UsingCarbonLib */
+
+
+#if UsingCarbonLib
+
+typedef OSStatus (*RunStandardAlertProcPtr) (
+ DialogRef inAlert,
+ ModalFilterUPP filterProc,
+ DialogItemIndex * outItemHit
+);
+LOCALVAR RunStandardAlertProcPtr MyRunStandardAlert = NULL;
+LOCALVAR blnr DidRunStandardAlert = falseblnr;
+
+LOCALFUNC blnr HaveMyRunStandardAlert(void)
+{
+ if (! DidRunStandardAlert) {
+ if (HaveHIToolboxBunRef()) {
+ MyRunStandardAlert =
+ (RunStandardAlertProcPtr)
+ CFBundleGetFunctionPointerForName(
+ HIToolboxBunRef, CFSTR("RunStandardAlert"));
+ }
+ DidRunStandardAlert = trueblnr;
+ }
+ return (MyRunStandardAlert != NULL);
+}
+
+#else
+
+#define HaveMyRunStandardAlert() trueblnr
+#define MyRunStandardAlert RunStandardAlert
+
+#endif /* ! UsingCarbonLib */
+
+
+typedef CGDirectDisplayID (*CGMainDisplayIDProcPtr)(void);
+
+LOCALVAR CGMainDisplayIDProcPtr MyCGMainDisplayID = NULL;
+LOCALVAR blnr DidCGMainDisplayID = falseblnr;
+
+LOCALFUNC blnr HaveMyCGMainDisplayID(void)
+{
+ if (! DidCGMainDisplayID) {
+ if (HaveApplicationServicesBun()) {
+ MyCGMainDisplayID =
+ (CGMainDisplayIDProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("CGMainDisplayID"));
+ }
+ DidCGMainDisplayID = trueblnr;
+ }
+ return (MyCGMainDisplayID != NULL);
+}
+
+#ifndef kCGNullDirectDisplay /* not in MPW Headers */
+#define kCGNullDirectDisplay ((CGDirectDisplayID)0)
+#endif
+
+typedef CGError
+(*CGDisplayRegisterReconfigurationCallbackProcPtr) (
+ CGDisplayReconfigurationCallBack proc,
+ void *userInfo
+ );
+LOCALVAR CGDisplayRegisterReconfigurationCallbackProcPtr
+ MyCGDisplayRegisterReconfigurationCallback = NULL;
+LOCALVAR blnr DidCGDisplayRegisterReconfigurationCallback = falseblnr;
+
+LOCALFUNC blnr HaveMyCGDisplayRegisterReconfigurationCallback(void)
+{
+ if (! DidCGDisplayRegisterReconfigurationCallback) {
+ if (HaveApplicationServicesBun()) {
+ MyCGDisplayRegisterReconfigurationCallback =
+ (CGDisplayRegisterReconfigurationCallbackProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef,
+ CFSTR("CGDisplayRegisterReconfigurationCallback"));
+ }
+ DidCGDisplayRegisterReconfigurationCallback = trueblnr;
+ }
+ return (MyCGDisplayRegisterReconfigurationCallback != NULL);
+}
+
+
+typedef CGError
+(*CGDisplayRemoveReconfigurationCallbackProcPtr) (
+ CGDisplayReconfigurationCallBack proc,
+ void *userInfo
+ );
+LOCALVAR CGDisplayRemoveReconfigurationCallbackProcPtr
+ MyCGDisplayRemoveReconfigurationCallback = NULL;
+LOCALVAR blnr DidCGDisplayRemoveReconfigurationCallback = falseblnr;
+
+LOCALFUNC blnr HaveMyCGDisplayRemoveReconfigurationCallback(void)
+{
+ if (! DidCGDisplayRemoveReconfigurationCallback) {
+ if (HaveApplicationServicesBun()) {
+ MyCGDisplayRemoveReconfigurationCallback =
+ (CGDisplayRemoveReconfigurationCallbackProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef,
+ CFSTR("CGDisplayRemoveReconfigurationCallback"));
+ }
+ DidCGDisplayRemoveReconfigurationCallback = trueblnr;
+ }
+ return (MyCGDisplayRemoveReconfigurationCallback != NULL);
+}
+
+
+typedef boolean_t (*CGCursorIsVisibleProcPtr)(void);
+
+LOCALVAR CGCursorIsVisibleProcPtr MyCGCursorIsVisible = NULL;
+LOCALVAR blnr DidCGCursorIsVisible = falseblnr;
+
+LOCALFUNC blnr HaveMyCGCursorIsVisible(void)
+{
+ if (! DidCGCursorIsVisible) {
+ if (HaveApplicationServicesBun()) {
+ MyCGCursorIsVisible =
+ (CGCursorIsVisibleProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("CGCursorIsVisible"));
+ }
+ DidCGCursorIsVisible = trueblnr;
+ }
+ return (MyCGCursorIsVisible != NULL);
+}
+
+
+/* --- end of adapting to API/ABI version differences --- */
+
+/* --- some simple utilities --- */
+
+GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount)
+{
+ (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount);
+}
+
+LOCALPROC PStrFromChar(ps3p r, char x)
+{
+ r[0] = 1;
+ r[1] = (char)x;
+}
+
+/* --- mac style errors --- */
+
+#define CheckSavetMacErr(result) (mnvm_noErr == (err = (result)))
+ /*
+ where 'err' is a variable of type tMacErr in the function
+ this is used in
+ */
+
+#define To_tMacErr(result) ((tMacErr)(ui4b)(result))
+
+#define CheckSaveMacErr(result) (CheckSavetMacErr(To_tMacErr(result)))
+
+
+#include "STRCONST.h"
+
+#define NeedCell2UnicodeMap 1
+
+#include "INTLCHAR.h"
+
+LOCALPROC UniCharStrFromSubstCStr(int *L, UniChar *x, char *s)
+{
+ int i;
+ int L0;
+ ui3b ps[ClStrMaxLength];
+
+ ClStrFromSubstCStr(&L0, ps, s);
+
+ for (i = 0; i < L0; ++i) {
+ x[i] = Cell2UnicodeMap[ps[i]];
+ }
+
+ *L = L0;
+}
+
+#define NotAfileRef (-1)
+
+LOCALFUNC tMacErr MyMakeFSRefUniChar(FSRef *ParentRef,
+ UniCharCount fileNameLength, const UniChar *fileName,
+ blnr *isFolder, FSRef *ChildRef)
+{
+ tMacErr err;
+ Boolean isFolder0;
+ Boolean isAlias;
+
+ if (CheckSaveMacErr(FSMakeFSRefUnicode(ParentRef,
+ fileNameLength, fileName, kTextEncodingUnknown,
+ ChildRef)))
+ if (CheckSaveMacErr(FSResolveAliasFile(ChildRef,
+ TRUE, &isFolder0, &isAlias)))
+ {
+ *isFolder = isFolder0;
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr MyMakeFSRefC(FSRef *ParentRef, char *fileName,
+ blnr *isFolder, FSRef *ChildRef)
+{
+ int L;
+ UniChar x[ClStrMaxLength];
+
+ UniCharStrFromSubstCStr(&L, x, fileName);
+ return MyMakeFSRefUniChar(ParentRef, L, x,
+ isFolder, ChildRef);
+}
+
+#if UseActvFile
+LOCALFUNC tMacErr OpenNamedFileInFolderRef(FSRef *ParentRef,
+ char *fileName, short *refnum)
+{
+ tMacErr err;
+ blnr isFolder;
+ FSRef ChildRef;
+ HFSUniStr255 forkName;
+
+ if (CheckSavetMacErr(MyMakeFSRefC(ParentRef, fileName,
+ &isFolder, &ChildRef)))
+ if (CheckSaveMacErr(FSGetDataForkName(&forkName)))
+ if (CheckSaveMacErr(FSOpenFork(&ChildRef, forkName.length,
+ forkName.unicode, fsRdPerm, refnum)))
+ {
+ /* ok */
+ }
+
+ return err;
+}
+#endif
+
+#if dbglog_HAVE || UseActvFile
+LOCALFUNC tMacErr OpenWriteNamedFileInFolderRef(FSRef *ParentRef,
+ char *fileName, short *refnum)
+{
+ tMacErr err;
+ blnr isFolder;
+ FSRef ChildRef;
+ HFSUniStr255 forkName;
+ int L;
+ UniChar x[ClStrMaxLength];
+
+ UniCharStrFromSubstCStr(&L, x, fileName);
+ err = MyMakeFSRefUniChar(ParentRef, L, x, &isFolder, &ChildRef);
+ if (mnvm_fnfErr == err) {
+ err = To_tMacErr(FSCreateFileUnicode(ParentRef, L, x, 0, NULL,
+ &ChildRef, NULL));
+ }
+ if (mnvm_noErr == err) {
+ if (CheckSaveMacErr(FSGetDataForkName(&forkName)))
+ if (CheckSaveMacErr(FSOpenFork(&ChildRef, forkName.length,
+ forkName.unicode, fsRdWrPerm, refnum)))
+ {
+ /* ok */
+ }
+ }
+
+ return err;
+}
+#endif
+
+LOCALFUNC tMacErr FindNamedChildRef(FSRef *ParentRef,
+ char *ChildName, FSRef *ChildRef)
+{
+ tMacErr err;
+ blnr isFolder;
+
+ if (CheckSavetMacErr(MyMakeFSRefC(ParentRef, ChildName,
+ &isFolder, ChildRef)))
+ {
+ if (! isFolder) {
+ err = mnvm_miscErr;
+ }
+ }
+
+ return err;
+}
+
+#if UseActvFile || (IncludeSonyNew && ! SaveDialogEnable)
+LOCALFUNC tMacErr FindOrMakeNamedChildRef(FSRef *ParentRef,
+ char *ChildName, FSRef *ChildRef)
+{
+ tMacErr err;
+ blnr isFolder;
+ int L;
+ UniChar x[ClStrMaxLength];
+
+ UniCharStrFromSubstCStr(&L, x, ChildName);
+ if (CheckSavetMacErr(MyMakeFSRefUniChar(ParentRef, L, x,
+ &isFolder, ChildRef)))
+ {
+ if (! isFolder) {
+ err = mnvm_miscErr;
+ }
+ }
+ if (mnvm_fnfErr == err) {
+ err = To_tMacErr(FSCreateDirectoryUnicode(
+ ParentRef, L, x, kFSCatInfoNone, NULL,
+ ChildRef, NULL, NULL));
+ }
+
+ return err;
+}
+#endif
+
+LOCALVAR FSRef MyDatDirRef;
+
+LOCALVAR CFStringRef MyAppName = NULL;
+
+LOCALPROC UnInitMyApplInfo(void)
+{
+ if (MyAppName != NULL) {
+ CFRelease(MyAppName);
+ }
+}
+
+LOCALFUNC blnr InitMyApplInfo(void)
+{
+ ProcessSerialNumber currentProcess = {0, kCurrentProcess};
+ FSRef fsRef;
+ FSRef parentRef;
+
+ if (noErr == GetProcessBundleLocation(¤tProcess,
+ &fsRef))
+ if (noErr == FSGetCatalogInfo(&fsRef, kFSCatInfoNone,
+ NULL, NULL, NULL, &parentRef))
+ {
+ FSRef ContentsRef;
+ FSRef DatRef;
+
+ MyDatDirRef = parentRef;
+ if (mnvm_noErr == FindNamedChildRef(&fsRef, "Contents",
+ &ContentsRef))
+ if (mnvm_noErr == FindNamedChildRef(&ContentsRef, "mnvm_dat",
+ &DatRef))
+ {
+ MyDatDirRef = DatRef;
+ }
+
+ if (HaveMyLSCopyDisplayNameForRef()) {
+ if (noErr == MyLSCopyDisplayNameForRef(&fsRef, &MyAppName))
+ {
+ return trueblnr;
+ }
+ }
+
+ if (noErr == CopyProcessName(¤tProcess, &MyAppName)) {
+ return trueblnr;
+ }
+ }
+ return falseblnr;
+}
+
+/* --- sending debugging info to file --- */
+
+#if dbglog_HAVE
+
+LOCALVAR SInt16 dbglog_File = NotAfileRef;
+
+LOCALFUNC blnr dbglog_open0(void)
+{
+ tMacErr err;
+
+ err = OpenWriteNamedFileInFolderRef(&MyDatDirRef,
+ "dbglog.txt", &dbglog_File);
+
+ return (mnvm_noErr == err);
+}
+
+LOCALPROC dbglog_write0(char *s, uimr L)
+{
+ ByteCount actualCount;
+
+ if (dbglog_File != NotAfileRef) {
+ (void) FSWriteFork(
+ dbglog_File,
+ fsFromMark,
+ 0,
+ L,
+ s,
+ &actualCount);
+ }
+}
+
+LOCALPROC dbglog_close0(void)
+{
+ if (dbglog_File != NotAfileRef) {
+ (void) FSSetForkSize(dbglog_File, fsFromMark, 0);
+ (void) FSCloseFork(dbglog_File);
+ dbglog_File = NotAfileRef;
+ }
+}
+
+#endif
+
+#if 1 /* (0 != vMacScreenDepth) && (vMacScreenDepth < 4) */
+#define WantColorTransValid 1
+#endif
+
+#include "COMOSGLU.h"
+
+/* --- time, date --- */
+
+/*
+ be sure to avoid getting confused if TickCount
+ overflows and wraps.
+*/
+
+#define dbglog_TimeStuff (0 && dbglog_HAVE)
+
+LOCALVAR ui5b TrueEmulatedTime = 0;
+
+LOCALVAR EventTime NextTickChangeTime;
+
+#define MyTickDuration (kEventDurationSecond / 60.14742)
+
+LOCALPROC UpdateTrueEmulatedTime(void)
+{
+ EventTime LatestTime = GetCurrentEventTime();
+ EventTime TimeDiff = LatestTime - NextTickChangeTime;
+
+ if (TimeDiff >= 0.0) {
+ if (TimeDiff > 16 * MyTickDuration) {
+ /* emulation interrupted, forget it */
+ ++TrueEmulatedTime;
+ NextTickChangeTime = LatestTime + MyTickDuration;
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("emulation interrupted",
+ TrueEmulatedTime);
+#endif
+ } else {
+ do {
+ ++TrueEmulatedTime;
+ TimeDiff -= MyTickDuration;
+ NextTickChangeTime += MyTickDuration;
+ } while (TimeDiff >= 0.0);
+ }
+ }
+}
+
+GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void)
+{
+ UpdateTrueEmulatedTime();
+ return TrueEmulatedTime == OnTrueTime;
+}
+
+/* LOCALVAR EventTime ETimeBase; */
+LOCALVAR CFAbsoluteTime ATimeBase;
+LOCALVAR ui5b TimeSecBase;
+
+LOCALFUNC blnr CheckDateTime(void)
+{
+ ui5b NewMacDateInSecond = TimeSecBase
+ + (ui5b)(CFAbsoluteTimeGetCurrent() - ATimeBase);
+ /*
+ ui5b NewMacDateInSecond = TimeSecBase
+ + (ui5b)(GetCurrentEventTime() - ETimeBase);
+ */
+ /*
+ ui5b NewMacDateInSecond = ((ui5b)(CFAbsoluteTimeGetCurrent()))
+ + 3061137600UL;
+ */
+
+ if (CurMacDateInSeconds != NewMacDateInSecond) {
+ CurMacDateInSeconds = NewMacDateInSecond;
+ return trueblnr;
+ } else {
+ return falseblnr;
+ }
+}
+
+/* --- parameter buffers --- */
+
+#include "PBUFSTDC.h"
+
+/* --- drives --- */
+
+LOCALVAR SInt16 Drives[NumDrives]; /* open disk image files */
+
+GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer,
+ tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
+ ui5r *Sony_ActCount)
+{
+ ByteCount actualCount;
+ tMacErr result;
+
+ if (IsWrite) {
+ result = To_tMacErr(FSWriteFork(
+ Drives[Drive_No],
+ fsFromStart,
+ Sony_Start,
+ Sony_Count,
+ Buffer,
+ &actualCount));
+ } else {
+ result = To_tMacErr(FSReadFork(
+ Drives[Drive_No],
+ fsFromStart,
+ Sony_Start,
+ Sony_Count,
+ Buffer,
+ &actualCount));
+ }
+
+ if (nullpr != Sony_ActCount) {
+ *Sony_ActCount = actualCount;
+ }
+
+ return result;
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count)
+{
+ SInt64 forkSize;
+ tMacErr err = To_tMacErr(
+ FSGetForkSize(Drives[Drive_No], &forkSize));
+ *Sony_Count = forkSize;
+ return err;
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No)
+{
+ SInt16 refnum = Drives[Drive_No];
+ Drives[Drive_No] = NotAfileRef;
+
+ DiskEjectedNotify(Drive_No);
+
+ (void) FSCloseFork(refnum);
+
+ return mnvm_noErr;
+}
+
+#if IncludeSonyNew
+GLOBALOSGLUFUNC tMacErr vSonyEjectDelete(tDrive Drive_No)
+{
+ FSRef ref;
+ tMacErr err0;
+ tMacErr err;
+
+ err0 = To_tMacErr(FSGetForkCBInfo(Drives[Drive_No], 0,
+ NULL /* iterator */,
+ NULL /* actualRefNum */,
+ NULL /* forkInfo */,
+ &ref /* ref */,
+ NULL /* outForkName */));
+ err = vSonyEject(Drive_No);
+
+ if (mnvm_noErr != err0) {
+ err = err0;
+ } else {
+ (void) FSDeleteObject(&ref);
+ }
+
+ return err;
+}
+#endif
+
+#if IncludeSonyGetName
+GLOBALOSGLUFUNC tMacErr vSonyGetName(tDrive Drive_No, tPbuf *r)
+{
+ FSRef ref;
+ HFSUniStr255 outName;
+ CFStringRef DiskName;
+ tMacErr err;
+
+ if (CheckSaveMacErr(FSGetForkCBInfo(Drives[Drive_No], 0,
+ NULL /* iterator */,
+ NULL /* actualRefNum */,
+ NULL /* forkInfo */,
+ &ref /* ref */,
+ NULL /* outForkName */)))
+ if (CheckSaveMacErr(FSGetCatalogInfo(&ref,
+ kFSCatInfoNone /* whichInfo */,
+ NULL /* catalogInfo */,
+ &outName /* outName */,
+ NULL /* fsSpec */,
+ NULL /* parentRef */)))
+ {
+ DiskName = CFStringCreateWithCharacters(
+ kCFAllocatorDefault, outName.unicode,
+ outName.length);
+ if (NULL != DiskName) {
+ tPbuf i;
+
+ if (CheckSavetMacErr(PbufNew(outName.length, &i))) {
+ if (CFStringGetBytes(DiskName,
+ CFRangeMake(0, outName.length),
+ kCFStringEncodingMacRoman,
+ '?', false,
+ PbufDat[i],
+ outName.length,
+ NULL) != outName.length)
+ {
+ err = mnvm_miscErr;
+ }
+ if (mnvm_noErr != err) {
+ PbufDispose(i);
+ } else {
+ *r = i;
+ }
+ }
+ CFRelease(DiskName);
+ }
+ }
+
+ return err;
+}
+#endif
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEexport(tPbuf i)
+{
+ tMacErr err;
+ ScrapRef scrapRef;
+
+ if (CheckSaveMacErr(ClearCurrentScrap()))
+ if (CheckSaveMacErr(GetCurrentScrap(&scrapRef)))
+ if (CheckSaveMacErr(PutScrapFlavor(
+ scrapRef,
+ FOUR_CHAR_CODE('TEXT'),
+ kScrapFlavorMaskNone,
+ PbufSize[i],
+ PbufDat[i])))
+ {
+ /* ok */
+ }
+
+ PbufDispose(i);
+
+ return err;
+}
+#endif
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEimport(tPbuf *r)
+{
+ tMacErr err;
+ ScrapRef scrap;
+ ScrapFlavorFlags flavorFlags;
+ Size byteCount;
+ tPbuf i;
+
+ if (CheckSaveMacErr(GetCurrentScrap(&scrap)))
+ if (CheckSaveMacErr(GetScrapFlavorFlags(scrap,
+ 'TEXT', &flavorFlags)))
+ if (CheckSaveMacErr(GetScrapFlavorSize(scrap,
+ 'TEXT', &byteCount)))
+ if (CheckSavetMacErr(PbufNew(byteCount, &i)))
+ {
+ Size byteCount2 = byteCount;
+ if (CheckSaveMacErr(GetScrapFlavorData(scrap,
+ 'TEXT', &byteCount2,
+ PbufDat[i])))
+ {
+ if (byteCount != byteCount2) {
+ err = mnvm_miscErr;
+ }
+ }
+ if (mnvm_noErr != err) {
+ PbufDispose(i);
+ } else {
+ *r = i;
+ }
+ }
+
+ return err;
+}
+#endif
+
+
+#if EmLocalTalk
+
+#include "BPFILTER.h"
+
+#endif
+
+
+/* --- control mode and internationalization --- */
+
+#define WantKeyboard_RemapMac 1
+
+#include "CONTROLM.h"
+
+
+/* --- video out --- */
+
+LOCALVAR WindowPtr gMyMainWindow = NULL;
+LOCALVAR WindowPtr gMyOldWindow = NULL;
+
+#if MayFullScreen
+LOCALVAR short hOffset;
+LOCALVAR short vOffset;
+#endif
+
+#if MayFullScreen
+LOCALVAR blnr GrabMachine = falseblnr;
+#endif
+
+#if VarFullScreen
+LOCALVAR blnr UseFullScreen = (WantInitFullScreen != 0);
+#endif
+
+#if EnableMagnify
+LOCALVAR blnr UseMagnify = (WantInitMagnify != 0);
+#endif
+
+#if EnableMagnify
+LOCALPROC MyScaleRect(Rect *r)
+{
+ r->left *= MyWindowScale;
+ r->right *= MyWindowScale;
+ r->top *= MyWindowScale;
+ r->bottom *= MyWindowScale;
+}
+#endif
+
+LOCALPROC SetScrnRectFromCoords(Rect *r,
+ si4b top, si4b left, si4b bottom, si4b right)
+{
+ r->left = left;
+ r->right = right;
+ r->top = top;
+ r->bottom = bottom;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ OffsetRect(r, - ViewHStart, - ViewVStart);
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ MyScaleRect(r);
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ OffsetRect(r, hOffset, vOffset);
+ }
+#endif
+}
+
+LOCALVAR ui3p ScalingBuff = nullpr;
+
+LOCALVAR ui3p CLUT_final;
+
+#define CLUT_finalsz1 (256 * 8)
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+
+#define CLUT_finalClrSz (256 << (5 - vMacScreenDepth))
+
+#define CLUT_finalsz ((CLUT_finalClrSz > CLUT_finalsz1) \
+ ? CLUT_finalClrSz : CLUT_finalsz1)
+
+#else
+#define CLUT_finalsz CLUT_finalsz1
+#endif
+
+
+#define ScrnMapr_DoMap UpdateBWLuminanceCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+
+#define ScrnMapr_DoMap UpdateMappedColorCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#endif
+
+#if vMacScreenDepth >= 4
+
+#define ScrnTrns_DoTrans UpdateTransColorCopy
+#define ScrnTrns_Src GetCurDrawBuff()
+#define ScrnTrns_Dst ScalingBuff
+#define ScrnTrns_SrcDepth vMacScreenDepth
+#define ScrnTrns_DstDepth 5
+#define ScrnTrns_DstZLo 1
+
+#include "SCRNTRNS.h"
+
+#endif
+
+LOCALPROC UpdateLuminanceCopy(si4b top, si4b left,
+ si4b bottom, si4b right)
+{
+ int i;
+
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+
+#if vMacScreenDepth < 4
+
+ if (! ColorTransValid) {
+ int j;
+ int k;
+ ui5p p4;
+
+ p4 = (ui5p)CLUT_final;
+ for (i = 0; i < 256; ++i) {
+ for (k = 1 << (3 - vMacScreenDepth); --k >= 0; ) {
+ j = (i >> (k << vMacScreenDepth)) & (CLUT_size - 1);
+ *p4++ = (((long)CLUT_reds[j] & 0xFF00) << 16)
+ | (((long)CLUT_greens[j] & 0xFF00) << 8)
+ | ((long)CLUT_blues[j] & 0xFF00);
+ }
+ }
+ ColorTransValid = trueblnr;
+ }
+
+ UpdateMappedColorCopy(top, left, bottom, right);
+
+#else
+ UpdateTransColorCopy(top, left, bottom, right);
+#endif
+
+ } else
+#endif
+ {
+ if (! ColorTransValid) {
+ int k;
+ ui3p p4 = (ui3p)CLUT_final;
+
+ for (i = 0; i < 256; ++i) {
+ for (k = 8; --k >= 0; ) {
+ *p4++ = ((i >> k) & 0x01) - 1;
+ }
+ }
+ ColorTransValid = trueblnr;
+ }
+
+ UpdateBWLuminanceCopy(top, left, bottom, right);
+ }
+}
+
+LOCALVAR AGLContext ctx = NULL;
+LOCALVAR short GLhOffset;
+LOCALVAR short GLvOffset;
+
+#ifndef UseAGLdoublebuff
+#define UseAGLdoublebuff 0
+#endif
+
+LOCALPROC MyDrawWithOpenGL(ui4r top, ui4r left, ui4r bottom, ui4r right)
+{
+ if (NULL == ctx) {
+ /* oops */
+ } else if (GL_TRUE != aglSetCurrentContext(ctx)) {
+ /* err = aglReportError() */
+ } else {
+ si4b top2;
+ si4b left2;
+
+#if UseAGLdoublebuff
+ /* redraw all */
+ top = 0;
+ left = 0;
+ bottom = vMacScreenHeight;
+ right = vMacScreenWidth;
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ if (top < ViewVStart) {
+ top = ViewVStart;
+ }
+ if (left < ViewHStart) {
+ left = ViewHStart;
+ }
+ if (bottom > ViewVStart + ViewVSize) {
+ bottom = ViewVStart + ViewVSize;
+ }
+ if (right > ViewHStart + ViewHSize) {
+ right = ViewHStart + ViewHSize;
+ }
+
+ if ((top >= bottom) || (left >= right)) {
+ goto label_exit;
+ }
+ }
+#endif
+
+ top2 = top;
+ left2 = left;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ left2 -= ViewHStart;
+ top2 -= ViewVStart;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ top2 *= MyWindowScale;
+ left2 *= MyWindowScale;
+ }
+#endif
+
+#if 0
+ glClear(GL_COLOR_BUFFER_BIT);
+ glBitmap(vMacScreenWidth,
+ vMacScreenHeight,
+ 0,
+ 0,
+ 0,
+ 0,
+ (const GLubyte *)GetCurDrawBuff());
+#endif
+#if 1
+ UpdateLuminanceCopy(top, left, bottom, right);
+ glRasterPos2i(GLhOffset + left2, GLvOffset - top2);
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+ glDrawPixels(right - left,
+ bottom - top,
+ GL_RGBA,
+ GL_UNSIGNED_INT_8_8_8_8,
+ ScalingBuff + (left + top * vMacScreenWidth) * 4
+ );
+ } else
+#endif
+ {
+ glDrawPixels(right - left,
+ bottom - top,
+ GL_LUMINANCE,
+ GL_UNSIGNED_BYTE,
+ ScalingBuff + (left + top * vMacScreenWidth)
+ );
+ }
+#endif
+
+#if 0 /* a very quick and dirty check of where drawing */
+ glDrawPixels(right - left,
+ 1,
+ GL_RED,
+ GL_UNSIGNED_BYTE,
+ ScalingBuff + (left + top * vMacScreenWidth)
+ );
+
+ glDrawPixels(1,
+ bottom - top,
+ GL_RED,
+ GL_UNSIGNED_BYTE,
+ ScalingBuff + (left + top * vMacScreenWidth)
+ );
+#endif
+
+#if UseAGLdoublebuff
+ aglSwapBuffers(ctx);
+#else
+ glFlush();
+#endif
+ }
+
+#if MayFullScreen
+label_exit:
+ ;
+#endif
+}
+
+LOCALPROC Update_Screen(void)
+{
+ MyDrawWithOpenGL(0, 0, vMacScreenHeight, vMacScreenWidth);
+}
+
+LOCALPROC MyDrawChangesAndClear(void)
+{
+ if (ScreenChangedBottom > ScreenChangedTop) {
+ MyDrawWithOpenGL(ScreenChangedTop, ScreenChangedLeft,
+ ScreenChangedBottom, ScreenChangedRight);
+ ScreenClearChanges();
+ }
+}
+
+
+LOCALVAR blnr MouseIsOutside = falseblnr;
+ /*
+ MouseIsOutside true if sure mouse outside our window. If in
+ our window, or not sure, set false.
+ */
+
+LOCALVAR blnr WantCursorHidden = falseblnr;
+
+LOCALPROC MousePositionNotify(Point NewMousePos)
+{
+ /*
+ Not MouseIsOutside includes in the title bar, etc, so have
+ to check if in content area.
+ */
+
+ Rect r;
+ blnr ShouldHaveCursorHidden = ! MouseIsOutside;
+
+ GetWindowBounds(gMyMainWindow, kWindowContentRgn, &r);
+
+ NewMousePos.h -= r.left;
+ NewMousePos.v -= r.top;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewMousePos.h -= hOffset;
+ NewMousePos.v -= vOffset;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ NewMousePos.h /= MyWindowScale;
+ NewMousePos.v /= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewMousePos.h += ViewHStart;
+ NewMousePos.v += ViewVStart;
+ }
+#endif
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMousePositionSetDelta(NewMousePos.h - SavedMouseH,
+ NewMousePos.v - SavedMouseV);
+ SavedMouseH = NewMousePos.h;
+ SavedMouseV = NewMousePos.v;
+ } else
+#endif
+ {
+ if (NewMousePos.h < 0) {
+ NewMousePos.h = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePos.h >= vMacScreenWidth) {
+ NewMousePos.h = vMacScreenWidth - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+ if (NewMousePos.v < 0) {
+ NewMousePos.v = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePos.v >= vMacScreenHeight) {
+ NewMousePos.v = vMacScreenHeight - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+
+ /* if (ShouldHaveCursorHidden || CurMouseButton) */
+ /*
+ for a game like arkanoid, would like mouse to still
+ move even when outside window in one direction
+ */
+ MyMousePositionSet(NewMousePos.h, NewMousePos.v);
+ }
+
+ WantCursorHidden = ShouldHaveCursorHidden;
+}
+
+LOCALPROC CheckMouseState(void)
+{
+ Point NewMousePos;
+ GetGlobalMouse(&NewMousePos);
+ /*
+ Deprecated, but haven't found usable replacement.
+ Between window deactivate and then reactivate,
+ mouse can move without getting kEventMouseMoved.
+ Also no way to get initial position.
+ (Also don't get kEventMouseMoved after
+ using menu bar. Or while using menubar, but
+ that isn't too important.)
+ */
+ MousePositionNotify(NewMousePos);
+}
+
+LOCALVAR blnr gLackFocusFlag = falseblnr;
+LOCALVAR blnr gWeAreActive = falseblnr;
+
+GLOBALOSGLUPROC DoneWithDrawingForTick(void)
+{
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ AutoScrollScreen();
+ }
+#endif
+ MyDrawChangesAndClear();
+}
+
+LOCALVAR blnr CurSpeedStopped = trueblnr;
+
+/* --- keyboard --- */
+
+LOCALVAR UInt32 SavedModifiers = 0;
+
+LOCALPROC MyUpdateKeyboardModifiers(UInt32 theModifiers)
+{
+ UInt32 ChangedModifiers = theModifiers ^ SavedModifiers;
+
+ if (0 != ChangedModifiers) {
+ if (0 != (ChangedModifiers & shiftKey)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_Shift,
+ (shiftKey & theModifiers) != 0);
+ }
+ if (0 != (ChangedModifiers & cmdKey)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_Command,
+ (cmdKey & theModifiers) != 0);
+ }
+ if (0 != (ChangedModifiers & alphaLock)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_CapsLock,
+ (alphaLock & theModifiers) != 0);
+ }
+ if (0 != (ChangedModifiers & optionKey)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_Option,
+ (optionKey & theModifiers) != 0);
+ }
+ if (0 != (ChangedModifiers & controlKey)) {
+ Keyboard_UpdateKeyMap2(MKC_formac_Control,
+ (controlKey & theModifiers) != 0);
+ }
+
+ SavedModifiers = theModifiers;
+ }
+}
+
+LOCALPROC ReconnectKeyCodes3(void)
+{
+ /*
+ turn off any modifiers (other than alpha)
+ that were turned on by drag and drop,
+ unless still being held down.
+ */
+
+ UInt32 theModifiers = GetCurrentKeyModifiers();
+
+ MyUpdateKeyboardModifiers(theModifiers
+ & (SavedModifiers | alphaLock));
+
+ SavedModifiers = theModifiers;
+}
+
+/* --- display utilities --- */
+
+/* DoForEachDisplay adapted from Apple Technical Q&A QA1168 */
+
+typedef void
+(*ForEachDisplayProcPtr) (CGDirectDisplayID display);
+
+LOCALPROC DoForEachDisplay0(CGDisplayCount dspCount,
+ CGDirectDisplayID *displays, ForEachDisplayProcPtr p)
+{
+ CGDisplayCount i;
+
+ if (noErr == MyCGGetActiveDisplayList(dspCount,
+ displays, &dspCount))
+ {
+ for (i = 0; i < dspCount; ++i) {
+ p(displays[i]);
+ }
+ }
+}
+
+LOCALPROC DoForEachDisplay(ForEachDisplayProcPtr p)
+{
+ CGDisplayCount dspCount = 0;
+
+ if (HaveMyCGGetActiveDisplayList()
+ && (noErr == MyCGGetActiveDisplayList(0, NULL, &dspCount)))
+ {
+ if (dspCount <= 2) {
+ CGDirectDisplayID displays[2];
+ DoForEachDisplay0(dspCount, displays, p);
+ } else {
+ CGDirectDisplayID *displays =
+ calloc((size_t)dspCount, sizeof(CGDirectDisplayID));
+ if (NULL != displays) {
+ DoForEachDisplay0(dspCount, displays, p);
+ free(displays);
+ }
+ }
+ }
+}
+
+LOCALVAR void *datp;
+
+LOCALPROC MyMainDisplayIDProc(CGDirectDisplayID display)
+{
+ CGDirectDisplayID *p = (CGDirectDisplayID *)datp;
+
+ if (kCGNullDirectDisplay == *p) {
+ *p = display;
+ }
+}
+
+LOCALFUNC CGDirectDisplayID MyMainDisplayID(void)
+{
+ if (HaveMyCGMainDisplayID()) {
+ return MyCGMainDisplayID();
+ } else {
+ /* for before OS X 10.2 */
+ CGDirectDisplayID r = kCGNullDirectDisplay;
+ void *savedatp = datp;
+ datp = (void *)&r;
+ DoForEachDisplay(MyMainDisplayIDProc);
+ datp = savedatp;
+ return r;
+ }
+}
+
+/* --- cursor hiding --- */
+
+#if 0
+LOCALPROC MyShowCursorProc(CGDirectDisplayID display)
+{
+ (void) CGDisplayShowCursor(display);
+}
+#endif
+
+LOCALPROC MyShowCursor(void)
+{
+#if 0
+ /* ShowCursor(); deprecated */
+ DoForEachDisplay(MyShowCursorProc);
+#endif
+ if (HaveMyCGDisplayShowCursor()) {
+ (void) MyCGDisplayShowCursor(MyMainDisplayID());
+ /* documentation now claims argument ignored */
+ }
+}
+
+#if 0
+LOCALPROC MyHideCursorProc(CGDirectDisplayID display)
+{
+ (void) CGDisplayHideCursor(display);
+}
+#endif
+
+LOCALPROC MyHideCursor(void)
+{
+#if 0
+ /* HideCursor(); deprecated */
+ DoForEachDisplay(MyHideCursorProc);
+#endif
+ if (HaveMyCGDisplayHideCursor()) {
+ (void) MyCGDisplayHideCursor(MyMainDisplayID());
+ /* documentation now claims argument ignored */
+ }
+}
+
+LOCALVAR blnr HaveCursorHidden = falseblnr;
+
+LOCALPROC ForceShowCursor(void)
+{
+ if (HaveCursorHidden) {
+ HaveCursorHidden = falseblnr;
+ MyShowCursor();
+ }
+}
+
+/* --- cursor moving --- */
+
+LOCALPROC SetCursorArrow(void)
+{
+ SetThemeCursor(kThemeArrowCursor);
+}
+
+#if EnableMoveMouse
+LOCALFUNC blnr MyMoveMouse(si4b h, si4b v)
+{
+ Point CurMousePos;
+ Rect r;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ h -= ViewHStart;
+ v -= ViewVStart;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ h *= MyWindowScale;
+ v *= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ h += hOffset;
+ v += vOffset;
+ }
+#endif
+
+ GetWindowBounds(gMyMainWindow, kWindowContentRgn, &r);
+ CurMousePos.h = r.left + h;
+ CurMousePos.v = r.top + v;
+
+ /*
+ This method from SDL_QuartzWM.m, "Simple DirectMedia Layer",
+ Copyright (C) 1997-2003 Sam Lantinga
+ */
+ if (HaveMyCGSetLocalEventsSuppressionInterval()) {
+ if (noErr != MyCGSetLocalEventsSuppressionInterval(0.0)) {
+ /* don't use MacMsg which can call MyMoveMouse */
+ }
+ }
+ if (HaveMyCGWarpMouseCursorPosition()) {
+ CGPoint pt;
+ pt.x = CurMousePos.h;
+ pt.y = CurMousePos.v;
+ if (noErr != MyCGWarpMouseCursorPosition(pt)) {
+ /* don't use MacMsg which can call MyMoveMouse */
+ }
+ }
+#if 0
+ if (HaveMyCGDisplayMoveCursorToPoint()) {
+ CGPoint pt;
+ pt.x = CurMousePos.h;
+ pt.y = CurMousePos.v;
+ if (noErr != MyCGDisplayMoveCursorToPoint(
+ MyMainDisplayID(), pt))
+ {
+ /* don't use MacMsg which can call MyMoveMouse */
+ }
+ }
+#endif
+
+ return trueblnr;
+}
+#endif
+
+#if EnableFSMouseMotion
+LOCALPROC AdjustMouseMotionGrab(void)
+{
+ if (gMyMainWindow != NULL) {
+#if MayFullScreen
+ if (GrabMachine) {
+ /*
+ if magnification changes, need to reset,
+ even if HaveMouseMotion already true
+ */
+ if (MyMoveMouse(ViewHStart + (ViewHSize / 2),
+ ViewVStart + (ViewVSize / 2)))
+ {
+ SavedMouseH = ViewHStart + (ViewHSize / 2);
+ SavedMouseV = ViewVStart + (ViewVSize / 2);
+ HaveMouseMotion = trueblnr;
+ }
+ } else
+#endif
+ {
+ if (HaveMouseMotion) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ HaveMouseMotion = falseblnr;
+ }
+ }
+ }
+}
+#endif
+
+#if EnableFSMouseMotion
+LOCALPROC MyMouseConstrain(void)
+{
+ si4b shiftdh;
+ si4b shiftdv;
+
+ if (SavedMouseH < ViewHStart + (ViewHSize / 4)) {
+ shiftdh = ViewHSize / 2;
+ } else if (SavedMouseH > ViewHStart + ViewHSize - (ViewHSize / 4)) {
+ shiftdh = - ViewHSize / 2;
+ } else {
+ shiftdh = 0;
+ }
+ if (SavedMouseV < ViewVStart + (ViewVSize / 4)) {
+ shiftdv = ViewVSize / 2;
+ } else if (SavedMouseV > ViewVStart + ViewVSize - (ViewVSize / 4)) {
+ shiftdv = - ViewVSize / 2;
+ } else {
+ shiftdv = 0;
+ }
+ if ((shiftdh != 0) || (shiftdv != 0)) {
+ SavedMouseH += shiftdh;
+ SavedMouseV += shiftdv;
+ if (! MyMoveMouse(SavedMouseH, SavedMouseV)) {
+ HaveMouseMotion = falseblnr;
+ }
+ }
+}
+#endif
+
+#if 0
+LOCALFUNC blnr InitMousePosition(void)
+{
+ /*
+ Since there doesn't seem to be any nondeprecated
+ way to get initial cursor position, instead
+ start by moving cursor to known position.
+ */
+
+#if VarFullScreen
+ if (! UseFullScreen)
+#endif
+#if MayNotFullScreen
+ {
+ CurMouseH = 16;
+ CurMouseV = 16;
+ WantCursorHidden = trueblnr;
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ }
+#endif
+
+ return trueblnr;
+}
+#endif
+
+/* --- time, date, location, part 2 --- */
+
+#include "DATE2SEC.h"
+
+LOCALFUNC blnr InitLocationDat(void)
+{
+#if AutoLocation || AutoTimeZone
+ MachineLocation loc;
+
+ ReadLocation(&loc);
+#if AutoLocation
+ CurMacLatitude = (ui5b)loc.latitude;
+ CurMacLongitude = (ui5b)loc.longitude;
+#endif
+#if AutoTimeZone
+ CurMacDelta = (ui5b)loc.u.gmtDelta;
+#endif
+#endif
+
+ {
+ CFTimeZoneRef tz = CFTimeZoneCopySystem();
+ if (tz) {
+ /* CFAbsoluteTime */ ATimeBase = CFAbsoluteTimeGetCurrent();
+ /* ETimeBase = GetCurrentEventTime(); */
+ {
+ CFGregorianDate d = CFAbsoluteTimeGetGregorianDate(
+ ATimeBase, tz);
+ double floorsec = floor(d.second);
+ ATimeBase -= (d.second - floorsec);
+ /* ETimeBase -= (d.second - floorsec); */
+ TimeSecBase = Date2MacSeconds(floorsec,
+ d.minute, d.hour,
+ d.day, d.month, d.year);
+
+ (void) CheckDateTime();
+ }
+ CFRelease(tz);
+ }
+ }
+
+ OnTrueTime = TrueEmulatedTime;
+
+ return trueblnr;
+}
+
+LOCALPROC StartUpTimeAdjust(void)
+{
+ NextTickChangeTime = GetCurrentEventTime() + MyTickDuration;
+}
+
+/* --- sound --- */
+
+#if MySoundEnabled
+
+#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */
+#define kSoundBuffers (1 << kLn2SoundBuffers)
+#define kSoundBuffMask (kSoundBuffers - 1)
+
+#define DesiredMinFilledSoundBuffs 3
+ /*
+ if too big then sound lags behind emulation.
+ if too small then sound will have pauses.
+ */
+
+#define kLnOneBuffLen 9
+#define kLnAllBuffLen (kLn2SoundBuffers + kLnOneBuffLen)
+#define kOneBuffLen (1UL << kLnOneBuffLen)
+#define kAllBuffLen (1UL << kLnAllBuffLen)
+#define kLnOneBuffSz (kLnOneBuffLen + kLn2SoundSampSz - 3)
+#define kLnAllBuffSz (kLnAllBuffLen + kLn2SoundSampSz - 3)
+#define kOneBuffSz (1UL << kLnOneBuffSz)
+#define kAllBuffSz (1UL << kLnAllBuffSz)
+#define kOneBuffMask (kOneBuffLen - 1)
+#define kAllBuffMask (kAllBuffLen - 1)
+#define dbhBufferSize (kAllBuffSz + kOneBuffSz)
+
+#define dbglog_SoundStuff (0 && dbglog_HAVE)
+#define dbglog_SoundBuffStats (0 && dbglog_HAVE)
+
+LOCALVAR tpSoundSamp TheSoundBuffer = nullpr;
+volatile static ui4b ThePlayOffset;
+volatile static ui4b TheFillOffset;
+volatile static ui4b MinFilledSoundBuffs;
+#if dbglog_SoundBuffStats
+LOCALVAR ui4b MaxFilledSoundBuffs;
+#endif
+LOCALVAR ui4b TheWriteOffset;
+
+LOCALPROC MySound_Start0(void)
+{
+ /* Reset variables */
+ ThePlayOffset = 0;
+ TheFillOffset = 0;
+ TheWriteOffset = 0;
+ MinFilledSoundBuffs = kSoundBuffers + 1;
+#if dbglog_SoundBuffStats
+ MaxFilledSoundBuffs = 0;
+#endif
+}
+
+GLOBALOSGLUFUNC tpSoundSamp MySound_BeginWrite(ui4r n, ui4r *actL)
+{
+ ui4b ToFillLen = kAllBuffLen - (TheWriteOffset - ThePlayOffset);
+ ui4b WriteBuffContig =
+ kOneBuffLen - (TheWriteOffset & kOneBuffMask);
+
+ if (WriteBuffContig < n) {
+ n = WriteBuffContig;
+ }
+ if (ToFillLen < n) {
+ /* overwrite previous buffer */
+#if dbglog_SoundStuff
+ dbglog_writeln("sound buffer over flow");
+#endif
+ TheWriteOffset -= kOneBuffLen;
+ }
+
+ *actL = n;
+ return TheSoundBuffer + (TheWriteOffset & kAllBuffMask);
+}
+
+#if 4 == kLn2SoundSampSz
+LOCALPROC ConvertSoundBlockToNative(tpSoundSamp p)
+{
+ int i;
+
+ for (i = kOneBuffLen; --i >= 0; ) {
+ *p++ -= 0x8000;
+ }
+}
+#else
+#define ConvertSoundBlockToNative(p)
+#endif
+
+LOCALPROC MySound_WroteABlock(void)
+{
+#if (4 == kLn2SoundSampSz)
+ ui4b PrevWriteOffset = TheWriteOffset - kOneBuffLen;
+ tpSoundSamp p = TheSoundBuffer + (PrevWriteOffset & kAllBuffMask);
+#endif
+
+#if dbglog_SoundStuff
+ dbglog_writeln("enter MySound_WroteABlock");
+#endif
+
+ ConvertSoundBlockToNative(p);
+
+ TheFillOffset = TheWriteOffset;
+
+#if dbglog_SoundBuffStats
+ {
+ ui4b ToPlayLen = TheFillOffset
+ - ThePlayOffset;
+ ui4b ToPlayBuffs = ToPlayLen >> kLnOneBuffLen;
+
+ if (ToPlayBuffs > MaxFilledSoundBuffs) {
+ MaxFilledSoundBuffs = ToPlayBuffs;
+ }
+ }
+#endif
+}
+
+LOCALFUNC blnr MySound_EndWrite0(ui4r actL)
+{
+ blnr v;
+
+ TheWriteOffset += actL;
+
+ if (0 != (TheWriteOffset & kOneBuffMask)) {
+ v = falseblnr;
+ } else {
+ /* just finished a block */
+
+ MySound_WroteABlock();
+
+ v = trueblnr;
+ }
+
+ return v;
+}
+
+LOCALPROC MySound_SecondNotify0(void)
+{
+ if (MinFilledSoundBuffs <= kSoundBuffers) {
+ if (MinFilledSoundBuffs > DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too high");
+#endif
+ NextTickChangeTime += MyTickDuration;
+ } else if (MinFilledSoundBuffs < DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too low");
+#endif
+ ++TrueEmulatedTime;
+ }
+#if dbglog_SoundBuffStats
+ dbglog_writelnNum("MinFilledSoundBuffs",
+ MinFilledSoundBuffs);
+ dbglog_writelnNum("MaxFilledSoundBuffs",
+ MaxFilledSoundBuffs);
+ MaxFilledSoundBuffs = 0;
+#endif
+ MinFilledSoundBuffs = kSoundBuffers + 1;
+ }
+}
+
+LOCALPROC RampSound(tpSoundSamp p,
+ trSoundSamp BeginVal, trSoundSamp EndVal)
+{
+ int i;
+ ui5r v = (((ui5r)BeginVal) << kLnOneBuffLen) + (kLnOneBuffLen >> 1);
+
+ for (i = kOneBuffLen; --i >= 0; ) {
+ *p++ = v >> kLnOneBuffLen;
+ v = v + EndVal - BeginVal;
+ }
+}
+
+#if 4 == kLn2SoundSampSz
+#define ConvertSoundSampleFromNative(v) ((v) + 0x8000)
+#else
+#define ConvertSoundSampleFromNative(v) (v)
+#endif
+
+struct MySoundR {
+ tpSoundSamp fTheSoundBuffer;
+ volatile ui4b (*fPlayOffset);
+ volatile ui4b (*fFillOffset);
+ volatile ui4b (*fMinFilledSoundBuffs);
+
+ volatile blnr PlayingBuffBlock;
+ volatile trSoundSamp lastv;
+ volatile blnr wantplaying;
+ volatile blnr StartingBlocks;
+
+ CmpSoundHeader /* ExtSoundHeader */ soundHeader;
+};
+typedef struct MySoundR MySoundR;
+
+
+/*
+ Some of this code descended from CarbonSndPlayDB, an
+ example from Apple, as found being used in vMac for Mac OS.
+*/
+
+LOCALPROC InsertSndDoCommand(SndChannelPtr chan, SndCommand * newCmd)
+{
+ if (-1 == chan->qHead) {
+ chan->qHead = chan->qTail;
+ }
+
+ if (1 <= chan->qHead) {
+ chan->qHead--;
+ } else {
+ chan->qHead = chan->qTail;
+ }
+
+ chan->queue[chan->qHead] = *newCmd;
+}
+
+/* call back */ static pascal void
+MySound_CallBack(SndChannelPtr theChannel, SndCommand * theCallBackCmd)
+{
+ MySoundR *datp =
+ (MySoundR *)(theCallBackCmd->param2);
+ blnr wantplaying0 = datp->wantplaying;
+ trSoundSamp v0 = datp->lastv;
+
+#if dbglog_SoundStuff
+ dbglog_writeln("Enter MySound_CallBack");
+#endif
+
+ if (datp->PlayingBuffBlock) {
+ /* finish with last sample */
+#if dbglog_SoundStuff
+ dbglog_writeln("done with sample");
+#endif
+
+ *datp->fPlayOffset += kOneBuffLen;
+ datp->PlayingBuffBlock = falseblnr;
+ }
+
+ if ((! wantplaying0) && (kCenterSound == v0)) {
+#if dbglog_SoundStuff
+ dbglog_writeln("terminating");
+#endif
+ } else {
+ SndCommand playCmd;
+ tpSoundSamp p;
+ trSoundSamp v1 = v0;
+ blnr WantRamp = falseblnr;
+ ui4b CurPlayOffset = *datp->fPlayOffset;
+ ui4b ToPlayLen = *datp->fFillOffset - CurPlayOffset;
+ ui4b FilledSoundBuffs = ToPlayLen >> kLnOneBuffLen;
+
+ if (FilledSoundBuffs < *datp->fMinFilledSoundBuffs) {
+ *datp->fMinFilledSoundBuffs = FilledSoundBuffs;
+ }
+
+ if (! wantplaying0) {
+#if dbglog_SoundStuff
+ dbglog_writeln("playing end transistion");
+#endif
+ v1 = kCenterSound;
+
+ WantRamp = trueblnr;
+ } else
+ if (datp->StartingBlocks) {
+#if dbglog_SoundStuff
+ dbglog_writeln("playing start block");
+#endif
+
+ if ((ToPlayLen >> kLnOneBuffLen) < 12) {
+ datp->StartingBlocks = falseblnr;
+#if dbglog_SoundStuff
+ dbglog_writeln("have enough samples to start");
+#endif
+
+ p = datp->fTheSoundBuffer
+ + (CurPlayOffset & kAllBuffMask);
+ v1 = ConvertSoundSampleFromNative(*p);
+ }
+
+ WantRamp = trueblnr;
+ } else
+ if (0 == FilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("playing under run");
+#endif
+
+ WantRamp = trueblnr;
+ } else
+ {
+ /* play next sample */
+ p = datp->fTheSoundBuffer
+ + (CurPlayOffset & kAllBuffMask);
+ datp->PlayingBuffBlock = trueblnr;
+ v1 =
+ ConvertSoundSampleFromNative(*(p + kOneBuffLen - 1));
+#if dbglog_SoundStuff
+ dbglog_writeln("playing sample");
+#endif
+ }
+
+ if (WantRamp) {
+ p = datp->fTheSoundBuffer + kAllBuffLen;
+
+#if dbglog_SoundStuff
+ dbglog_writelnNum("v0", v0);
+ dbglog_writelnNum("v1", v1);
+#endif
+
+ RampSound(p, v0, v1);
+ ConvertSoundBlockToNative(p);
+ }
+
+ datp->soundHeader.samplePtr = (Ptr)p;
+ datp->soundHeader.numFrames =
+ (unsigned long)kOneBuffLen;
+
+ /* Insert our callback command */
+ InsertSndDoCommand (theChannel, theCallBackCmd);
+
+#if 0
+ {
+ int i;
+ tpSoundSamp pS =
+ (tpSoundSamp)datp->soundHeader.samplePtr;
+
+ for (i = datp->soundHeader.numFrames; --i >= 0; )
+ {
+ fprintf(stderr, "%d\n", *pS++);
+ }
+ }
+#endif
+
+ /* Play the next buffer */
+ playCmd.cmd = bufferCmd;
+ playCmd.param1 = 0;
+ playCmd.param2 = (long)&(datp->soundHeader);
+ InsertSndDoCommand (theChannel, &playCmd);
+
+ datp->lastv = v1;
+ }
+}
+
+LOCALVAR MySoundR cur_audio;
+
+LOCALVAR SndCallBackUPP gCarbonSndPlayDoubleBufferCallBackUPP = NULL;
+
+LOCALVAR SndChannelPtr sndChannel = NULL; /* our sound channel */
+
+LOCALPROC MySound_Start(void)
+{
+#if dbglog_SoundStuff
+ dbglog_writeln("MySound_Start");
+#endif
+
+ if (NULL == sndChannel) {
+ SndCommand callBack;
+ SndChannelPtr chan = NULL;
+
+ cur_audio.wantplaying = falseblnr;
+ cur_audio.StartingBlocks = falseblnr;
+
+ MySound_Start0();
+
+ SndNewChannel(&chan, sampledSynth, initMono, nil);
+ if (NULL != chan) {
+ sndChannel = chan;
+
+ cur_audio.PlayingBuffBlock = falseblnr;
+ cur_audio.lastv = kCenterSound;
+ cur_audio.StartingBlocks = trueblnr;
+ cur_audio.wantplaying = trueblnr;
+
+ callBack.cmd = callBackCmd;
+ callBack.param1 = 0; /* unused */
+ callBack.param2 = (long)&cur_audio;
+
+ sndChannel->callBack =
+ gCarbonSndPlayDoubleBufferCallBackUPP;
+
+ (void) SndDoCommand (sndChannel, &callBack, true);
+ }
+ }
+}
+
+LOCALPROC MySound_Stop(void)
+{
+#if dbglog_SoundStuff
+ dbglog_writeln("enter MySound_Stop");
+#endif
+
+ if (NULL != sndChannel) {
+ ui4r retry_limit = 50; /* half of a second */
+ SCStatus r;
+
+ cur_audio.wantplaying = falseblnr;
+#if dbglog_SoundStuff
+ dbglog_writeln("cleared wantplaying");
+#endif
+
+label_retry:
+ r.scChannelBusy = falseblnr; /* what is this for? */
+ if (noErr != SndChannelStatus(sndChannel,
+ sizeof(SCStatus), &r))
+ {
+ /* fail */
+ } else
+ if ((! r.scChannelBusy) && (kCenterSound == cur_audio.lastv)) {
+ /* done */
+
+ /*
+ observed reporting not busy unexpectedly,
+ so also check lastv.
+ */
+ } else
+ if (0 == --retry_limit) {
+#if dbglog_SoundStuff
+ dbglog_writeln("retry limit reached");
+#endif
+ /*
+ don't trust SndChannelStatus, make
+ sure don't get in infinite loop.
+ */
+
+ /* done */
+ } else
+ {
+ /*
+ give time back, particularly important
+ if got here on a suspend event.
+ */
+ struct timespec rqt;
+ struct timespec rmt;
+
+#if dbglog_SoundStuff
+ dbglog_writeln("busy, so sleep");
+#endif
+
+ rqt.tv_sec = 0;
+ rqt.tv_nsec = 10000000;
+ (void) nanosleep(&rqt, &rmt);
+
+ goto label_retry;
+ }
+
+ SndDisposeChannel(sndChannel, true);
+ sndChannel = NULL;
+ }
+
+#if dbglog_SoundStuff
+ dbglog_writeln("leave MySound_Stop");
+#endif
+}
+
+#define SOUND_SAMPLERATE rate22khz
+ /* = 0x56EE8BA3 = (7833600 * 2 / 704) << 16 */
+
+LOCALFUNC blnr MySound_Init(void)
+{
+#if dbglog_SoundStuff
+ dbglog_writeln("enter MySound_Init");
+#endif
+
+ cur_audio.fTheSoundBuffer = TheSoundBuffer;
+
+ cur_audio.fPlayOffset = &ThePlayOffset;
+ cur_audio.fFillOffset = &TheFillOffset;
+ cur_audio.fMinFilledSoundBuffs = &MinFilledSoundBuffs;
+ cur_audio.wantplaying = falseblnr;
+
+ /* Init basic per channel information */
+ cur_audio.soundHeader.sampleRate = SOUND_SAMPLERATE;
+ /* sample rate */
+ cur_audio.soundHeader.numChannels = 1; /* one channel */
+ cur_audio.soundHeader.loopStart = 0;
+ cur_audio.soundHeader.loopEnd = 0;
+ cur_audio.soundHeader.encode = cmpSH /* extSH */;
+ cur_audio.soundHeader.baseFrequency = kMiddleC;
+ cur_audio.soundHeader.numFrames =
+ (unsigned long)kOneBuffLen;
+ /* cur_audio.soundHeader.AIFFSampleRate = 0; */
+ /* unused */
+ cur_audio.soundHeader.markerChunk = nil;
+ cur_audio.soundHeader.futureUse2 = 0;
+ cur_audio.soundHeader.stateVars = nil;
+ cur_audio.soundHeader.leftOverSamples = nil;
+ cur_audio.soundHeader.compressionID = 0;
+ /* no compression */
+ cur_audio.soundHeader.packetSize = 0;
+ /* no compression */
+ cur_audio.soundHeader.snthID = 0;
+ cur_audio.soundHeader.sampleSize = (1 << kLn2SoundSampSz);
+ /* 8 or 16 bits per sample */
+ cur_audio.soundHeader.sampleArea[0] = 0;
+#if 3 == kLn2SoundSampSz
+ cur_audio.soundHeader.format = kSoundNotCompressed;
+#elif 4 == kLn2SoundSampSz
+ cur_audio.soundHeader.format = k16BitNativeEndianFormat;
+#else
+#error "unsupported kLn2SoundSampSz"
+#endif
+ cur_audio.soundHeader.samplePtr = (Ptr)TheSoundBuffer;
+
+ gCarbonSndPlayDoubleBufferCallBackUPP =
+ NewSndCallBackUPP(MySound_CallBack);
+ if (gCarbonSndPlayDoubleBufferCallBackUPP != NULL) {
+
+ MySound_Start();
+ /*
+ This should be taken care of by LeaveSpeedStopped,
+ but since takes a while to get going properly,
+ start early.
+ */
+
+ return trueblnr;
+ }
+ return falseblnr;
+}
+
+GLOBALOSGLUPROC MySound_EndWrite(ui4r actL)
+{
+ if (MySound_EndWrite0(actL)) {
+ }
+}
+
+LOCALPROC MySound_SecondNotify(void)
+{
+ if (sndChannel != NULL) {
+ MySound_SecondNotify0();
+ }
+}
+
+#endif
+
+
+LOCALPROC MyAdjustGLforSize(int h, int v)
+{
+ if (GL_TRUE != aglSetCurrentContext(ctx)) {
+ /* err = aglReportError() */
+ } else {
+
+ glClearColor (0.0, 0.0, 0.0, 1.0);
+
+#if 1
+ glViewport(0, 0, h, v);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, h, 0, v, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+#endif
+
+ glColor3f(0.0, 0.0, 0.0);
+#if EnableMagnify
+ if (UseMagnify) {
+ glPixelZoom(MyWindowScale, - MyWindowScale);
+ } else
+#endif
+ {
+ glPixelZoom(1, -1);
+ }
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, vMacScreenWidth);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ if (GL_TRUE != aglSetCurrentContext(NULL)) {
+ /* err = aglReportError() */
+ }
+
+ ScreenChangedAll();
+ }
+}
+
+LOCALVAR blnr WantScreensChangedCheck = falseblnr;
+
+LOCALPROC MyUpdateOpenGLContext(void)
+{
+ if (NULL == ctx) {
+ /* oops */
+ } else if (GL_TRUE != aglSetCurrentContext(ctx)) {
+ /* err = aglReportError() */
+ } else {
+ aglUpdateContext(ctx);
+ }
+}
+
+#if 0 /* some experiments */
+LOCALVAR CGrafPtr GrabbedPort = NULL;
+#endif
+
+#if 0
+LOCALPROC AdjustMainScreenGrab(void)
+{
+ if (GrabMachine) {
+ if (NULL == GrabbedPort) {
+ /* CGDisplayCapture(MyMainDisplayID()); */
+ CGCaptureAllDisplays();
+ /* CGDisplayHideCursor( MyMainDisplayID() ); */
+ GrabbedPort =
+ CreateNewPortForCGDisplayID((UInt32)MyMainDisplayID());
+ LockPortBits (GrabbedPort);
+ }
+ } else {
+ if (GrabbedPort != NULL) {
+ UnlockPortBits (GrabbedPort);
+ /* CGDisplayShowCursor( MyMainDisplayID() ); */
+ /* CGDisplayRelease(MyMainDisplayID()); */
+ CGReleaseAllDisplays();
+ GrabbedPort = NULL;
+ }
+ }
+}
+#endif
+
+#if 0
+typedef CGDisplayErr (*CGReleaseAllDisplaysProcPtr)
+ (void);
+
+LOCALPROC MyReleaseAllDisplays(void)
+{
+ if (HaveApplicationServicesBun()) {
+ CGReleaseAllDisplaysProcPtr ReleaseAllDisplaysProc =
+ (CGReleaseAllDisplaysProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("CGReleaseAllDisplays"));
+ if (ReleaseAllDisplaysProc != NULL) {
+ ReleaseAllDisplaysProc();
+ }
+ }
+}
+
+typedef CGDisplayErr (*CGCaptureAllDisplaysProcPtr)
+ (void);
+
+LOCALPROC MyCaptureAllDisplays(void)
+{
+ if (HaveApplicationServicesBun()) {
+ CGCaptureAllDisplaysProcPtr CaptureAllDisplaysProc =
+ (CGCaptureAllDisplaysProcPtr)
+ CFBundleGetFunctionPointerForName(
+ AppServBunRef, CFSTR("CGCaptureAllDisplays"));
+ if (CaptureAllDisplaysProc != NULL) {
+ CaptureAllDisplaysProc();
+ }
+ }
+}
+#endif
+
+LOCALVAR AGLPixelFormat window_fmt = NULL;
+LOCALVAR AGLContext window_ctx = NULL;
+
+#ifndef UseAGLfullscreen
+#define UseAGLfullscreen 0
+#endif
+
+#if UseAGLfullscreen
+LOCALVAR AGLPixelFormat fullscreen_fmt = NULL;
+LOCALVAR AGLContext fullscreen_ctx = NULL;
+#endif
+
+#if UseAGLfullscreen
+LOCALPROC MaybeFullScreen(void)
+{
+ if (
+#if VarFullScreen
+ UseFullScreen &&
+#endif
+ (NULL == fullscreen_ctx)
+ && HaveMyCGDisplayPixelsWide()
+ && HaveMyCGDisplayPixelsHigh())
+ {
+ static const GLint fullscreen_attrib[] = {AGL_RGBA,
+ AGL_NO_RECOVERY,
+ AGL_FULLSCREEN,
+ AGL_SINGLE_RENDERER, AGL_ACCELERATED,
+#if UseAGLdoublebuff
+ AGL_DOUBLEBUFFER,
+#endif
+ AGL_NONE};
+ GDHandle theDevice;
+ CGDirectDisplayID CurMainDisplayID = MyMainDisplayID();
+
+ DMGetGDeviceByDisplayID(
+ (DisplayIDType)CurMainDisplayID, &theDevice, false);
+ fullscreen_fmt = aglChoosePixelFormat(
+ &theDevice, 1, fullscreen_attrib);
+ if (NULL == fullscreen_fmt) {
+ /* err = aglReportError() */
+ } else {
+ fullscreen_ctx = aglCreateContext(fullscreen_fmt, NULL);
+ if (NULL == fullscreen_ctx) {
+ /* err = aglReportError() */
+ } else {
+ /* MyCaptureAllDisplays(); */
+ if (GL_TRUE != aglSetFullScreen(fullscreen_ctx,
+ 0, 0, 0, 0))
+ {
+ /* err = aglReportError() */
+ } else {
+ Rect r;
+
+ int h = MyCGDisplayPixelsWide(CurMainDisplayID);
+ int v = MyCGDisplayPixelsHigh(CurMainDisplayID);
+
+ GetWindowBounds(gMyMainWindow, kWindowContentRgn,
+ &r);
+
+ GLhOffset = r.left + hOffset;
+ GLvOffset = v - (r.top + vOffset);
+
+ ctx = fullscreen_ctx;
+ MyAdjustGLforSize(h, v);
+ return;
+ }
+ /* MyReleaseAllDisplays(); */
+
+ if (GL_TRUE != aglDestroyContext(fullscreen_ctx)) {
+ /* err = aglReportError() */
+ }
+ fullscreen_ctx = NULL;
+ }
+
+ aglDestroyPixelFormat (fullscreen_fmt);
+ fullscreen_fmt = NULL;
+ }
+ }
+}
+#endif
+
+#if UseAGLfullscreen
+LOCALPROC NoFullScreen(void)
+{
+ if (fullscreen_ctx != NULL) {
+ Rect r;
+ int h;
+ int v;
+
+ GetWindowBounds(gMyMainWindow, kWindowContentRgn, &r);
+
+ h = r.right - r.left;
+ v = r.bottom - r.top;
+
+ GLhOffset = hOffset;
+ GLvOffset = v - vOffset;
+
+ ctx = window_ctx;
+
+ MyAdjustGLforSize(h, v);
+
+ Update_Screen();
+
+ if (fullscreen_ctx != NULL) {
+ if (GL_TRUE != aglDestroyContext(fullscreen_ctx)) {
+ /* err = aglReportError() */
+ }
+ fullscreen_ctx = NULL;
+ }
+ if (fullscreen_fmt != NULL) {
+ aglDestroyPixelFormat(fullscreen_fmt);
+ fullscreen_fmt = NULL;
+ }
+ }
+}
+#endif
+
+#if UseAGLfullscreen
+LOCALPROC AdjustOpenGLGrab(void)
+{
+ if (GrabMachine) {
+ MaybeFullScreen();
+ } else {
+ NoFullScreen();
+ }
+}
+#endif
+
+#if MayFullScreen
+LOCALPROC AdjustMachineGrab(void)
+{
+#if EnableFSMouseMotion
+ AdjustMouseMotionGrab();
+#endif
+#if UseAGLfullscreen
+ AdjustOpenGLGrab();
+#endif
+#if 0
+ AdjustMainScreenGrab();
+#endif
+}
+#endif
+
+#if MayFullScreen
+LOCALPROC UngrabMachine(void)
+{
+ GrabMachine = falseblnr;
+ AdjustMachineGrab();
+}
+#endif
+
+LOCALPROC ClearWeAreActive(void)
+{
+ if (gWeAreActive) {
+ gWeAreActive = falseblnr;
+
+ DisconnectKeyCodes2();
+
+ SavedModifiers &= alphaLock;
+
+ MyMouseButtonSet(falseblnr);
+
+#if MayFullScreen
+ UngrabMachine();
+#endif
+
+ ForceShowCursor();
+ }
+}
+
+/* --- basic dialogs --- */
+
+LOCALFUNC CFStringRef CFStringCreateFromSubstCStr(char *s)
+{
+ int L;
+ UniChar x[ClStrMaxLength];
+
+ UniCharStrFromSubstCStr(&L, x, s);
+
+ return CFStringCreateWithCharacters(kCFAllocatorDefault, x, L);
+}
+
+#define kMyStandardAlert 128
+
+LOCALPROC CheckSavedMacMsg(void)
+{
+ /* called only on quit, if error saved but not yet reported */
+
+ if (nullpr != SavedBriefMsg) {
+ if (HaveMyCreateStandardAlert() && HaveMyRunStandardAlert()) {
+ CFStringRef briefMsgu = CFStringCreateFromSubstCStr(
+ SavedBriefMsg);
+ if (NULL != briefMsgu) {
+ CFStringRef longMsgu = CFStringCreateFromSubstCStr(
+ SavedLongMsg);
+ if (NULL != longMsgu) {
+ DialogRef TheAlert;
+ OSStatus err = MyCreateStandardAlert(
+ (SavedFatalMsg) ? kAlertStopAlert
+ : kAlertCautionAlert,
+ briefMsgu, longMsgu, NULL,
+ &TheAlert);
+ if (noErr == err) {
+ (void) MyRunStandardAlert(TheAlert, NULL, NULL);
+ }
+ CFRelease(longMsgu);
+ }
+ CFRelease(briefMsgu);
+ }
+ }
+
+ SavedBriefMsg = nullpr;
+ }
+}
+
+LOCALVAR blnr gTrueBackgroundFlag = falseblnr;
+
+LOCALPROC MyBeginDialog(void)
+{
+ ClearWeAreActive();
+}
+
+LOCALPROC MyEndDialog(void)
+{
+}
+
+/* --- hide/show menubar --- */
+
+#if MayFullScreen
+LOCALPROC My_HideMenuBar(void)
+{
+ if (HaveMySetSystemUIMode()) {
+ (void) MySetSystemUIMode(MykUIModeAllHidden,
+ MykUIOptionDisableAppleMenu
+#if GrabKeysFullScreen
+ | MykUIOptionDisableProcessSwitch
+#if GrabKeysMaxFullScreen /* dangerous !! */
+ | MykUIOptionDisableForceQuit
+ | MykUIOptionDisableSessionTerminate
+#endif
+#endif
+ );
+ } else {
+ if (IsMenuBarVisible()) {
+ HideMenuBar();
+ }
+ }
+}
+#endif
+
+#if MayFullScreen
+LOCALPROC My_ShowMenuBar(void)
+{
+ if (HaveMySetSystemUIMode()) {
+ (void) MySetSystemUIMode(MykUIModeNormal,
+ 0);
+ } else {
+ if (! IsMenuBarVisible()) {
+ ShowMenuBar();
+ }
+ }
+}
+#endif
+
+/* --- drives, part 2 --- */
+
+LOCALPROC InitDrives(void)
+{
+ /*
+ This isn't really needed, Drives[i]
+ need not have valid value when not vSonyIsInserted[i].
+ */
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ Drives[i] = NotAfileRef;
+ }
+}
+
+LOCALPROC UnInitDrives(void)
+{
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ if (vSonyIsInserted(i)) {
+ (void) vSonyEject(i);
+ }
+ }
+}
+
+LOCALFUNC tMacErr Sony_Insert0(SInt16 refnum, blnr locked)
+{
+ tDrive Drive_No;
+
+ if (! FirstFreeDisk(&Drive_No)) {
+ (void) FSCloseFork(refnum);
+ return mnvm_tmfoErr;
+ } else {
+ Drives[Drive_No] = refnum;
+ DiskInsertNotify(Drive_No, locked);
+ return mnvm_noErr;
+ }
+}
+
+LOCALPROC ReportStandardOpenDiskError(tMacErr err)
+{
+ if (mnvm_noErr != err) {
+ if (mnvm_tmfoErr == err) {
+ MacMsg(kStrTooManyImagesTitle,
+ kStrTooManyImagesMessage, falseblnr);
+ } else if (mnvm_opWrErr == err) {
+ MacMsg(kStrImageInUseTitle,
+ kStrImageInUseMessage, falseblnr);
+ } else {
+ MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
+ }
+ }
+}
+
+LOCALFUNC tMacErr InsertADiskFromFSRef(FSRef *theRef)
+{
+ tMacErr err;
+ HFSUniStr255 forkName;
+ SInt16 refnum;
+ blnr locked = falseblnr;
+
+ if (CheckSaveMacErr(FSGetDataForkName(&forkName))) {
+ err = To_tMacErr(FSOpenFork(theRef, forkName.length,
+ forkName.unicode, fsRdWrPerm, &refnum));
+ switch (err) {
+ case mnvm_permErr:
+ case mnvm_wrPermErr:
+ case mnvm_afpAccessDenied:
+ locked = trueblnr;
+ err = To_tMacErr(FSOpenFork(theRef, forkName.length,
+ forkName.unicode, fsRdPerm, &refnum));
+ break;
+ default:
+ break;
+ }
+ if (mnvm_noErr == err) {
+ err = Sony_Insert0(refnum, locked);
+ }
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr LoadMacRomFromRefNum(SInt16 refnum)
+{
+ tMacErr err;
+ ByteCount actualCount;
+
+ if (mnvm_noErr != (err = To_tMacErr(
+ FSReadFork(refnum, fsFromStart, 0,
+ kROM_Size, ROM, &actualCount))))
+ {
+ if (mnvm_eofErr == err) {
+ MacMsgOverride(kStrShortROMTitle, kStrShortROMMessage);
+ } else {
+ MacMsgOverride(kStrNoReadROMTitle, kStrNoReadROMMessage);
+ }
+ } else
+ {
+ err = ROM_IsValid();
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr LoadMacRomFromFSRef(FSRef *theRef)
+{
+ tMacErr err;
+ HFSUniStr255 forkName;
+ SInt16 refnum;
+
+ if (mnvm_noErr == (err =
+ To_tMacErr(FSGetDataForkName(&forkName))))
+ if (mnvm_noErr == (err = To_tMacErr(
+ FSOpenFork(theRef, forkName.length,
+ forkName.unicode, fsRdPerm, &refnum))))
+ {
+ err = LoadMacRomFromRefNum(refnum);
+
+ (void) FSCloseFork(refnum);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr InsertADiskFromFSRef1(FSRef *theRef)
+{
+ tMacErr err;
+
+ if (! ROM_loaded) {
+ err = LoadMacRomFromFSRef(theRef);
+ } else {
+ err = InsertADiskFromFSRef(theRef);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr InsertDisksFromDocList(AEDescList *docList)
+{
+ tMacErr err = mnvm_noErr;
+ long itemsInList;
+ long index;
+ AEKeyword keyword;
+ DescType typeCode;
+ FSRef theRef;
+ Size actualSize;
+
+ if (CheckSaveMacErr(AECountItems(docList, &itemsInList))) {
+ for (index = 1; index <= itemsInList; ++index) {
+ if (CheckSaveMacErr(AEGetNthPtr(docList, index, typeFSRef,
+ &keyword, &typeCode, (Ptr)&theRef,
+ sizeof(FSRef), &actualSize)))
+ if (CheckSavetMacErr(InsertADiskFromFSRef1(&theRef)))
+ {
+ }
+ if (mnvm_noErr != err) {
+ goto label_fail;
+ }
+ }
+ }
+
+label_fail:
+ return err;
+}
+
+LOCALFUNC tMacErr InsertADiskFromNameEtc(FSRef *ParentRef,
+ char *fileName)
+{
+ tMacErr err;
+ blnr isFolder;
+ FSRef ChildRef;
+
+ if (CheckSavetMacErr(MyMakeFSRefC(ParentRef, fileName,
+ &isFolder, &ChildRef)))
+ {
+ if (isFolder) {
+ err = mnvm_miscErr;
+ } else {
+ if (CheckSavetMacErr(InsertADiskFromFSRef(&ChildRef))) {
+ /* ok */
+ }
+ }
+ }
+
+ return err;
+}
+
+#if IncludeSonyNew
+LOCALFUNC tMacErr WriteZero(SInt16 refnum, ui5b L)
+{
+#define ZeroBufferSize 2048
+ tMacErr err = mnvm_noErr;
+ ui5b i;
+ ui3b buffer[ZeroBufferSize];
+ ByteCount actualCount;
+ ui5b offset = 0;
+
+ memset(&buffer, 0, ZeroBufferSize);
+
+ while (L > 0) {
+ i = (L > ZeroBufferSize) ? ZeroBufferSize : L;
+ if (! CheckSaveMacErr(FSWriteFork(refnum,
+ fsFromStart,
+ offset,
+ i,
+ buffer,
+ &actualCount)))
+ {
+ goto label_fail;
+ }
+ L -= i;
+ offset += i;
+ }
+
+label_fail:
+ return err;
+}
+#endif
+
+#if IncludeSonyNew
+LOCALFUNC tMacErr MyCreateFileCFStringRef(FSRef *saveFileParent,
+ CFStringRef saveFileName, FSRef *NewRef)
+{
+ tMacErr err;
+ UniChar buffer[255];
+
+ CFIndex len = CFStringGetLength(saveFileName);
+
+ if (len > 255) {
+ len = 255;
+ }
+
+ CFStringGetCharacters(saveFileName, CFRangeMake(0, len), buffer);
+
+ err = To_tMacErr(FSMakeFSRefUnicode(saveFileParent, len,
+ buffer, kTextEncodingUnknown, NewRef));
+ if (mnvm_fnfErr == err) { /* file is not there yet - create it */
+ err = To_tMacErr(FSCreateFileUnicode(saveFileParent,
+ len, buffer, 0, NULL, NewRef, NULL));
+ }
+
+ return err;
+}
+#endif
+
+#if IncludeSonyNew
+LOCALFUNC tMacErr MakeNewDisk0(FSRef *saveFileParent,
+ CFStringRef saveFileName, ui5b L)
+{
+ tMacErr err;
+ FSRef NewRef;
+ HFSUniStr255 forkName;
+ SInt16 refnum;
+
+ if (CheckSavetMacErr(
+ MyCreateFileCFStringRef(saveFileParent, saveFileName, &NewRef)))
+ {
+ if (CheckSaveMacErr(FSGetDataForkName(&forkName)))
+ if (CheckSaveMacErr(FSOpenFork(&NewRef, forkName.length,
+ forkName.unicode, fsRdWrPerm, &refnum)))
+ {
+ SInt64 forkSize = L;
+ if (CheckSaveMacErr(
+ FSSetForkSize(refnum, fsFromStart, forkSize)))
+ /*
+ zero out fork. It looks like this is already done,
+ but documentation says this isn't guaranteed.
+ */
+ if (CheckSavetMacErr(WriteZero(refnum, L)))
+ {
+ err = Sony_Insert0(refnum, falseblnr);
+ refnum = NotAfileRef;
+ }
+ if (NotAfileRef != refnum) {
+ (void) FSCloseFork(refnum);
+ }
+ }
+ if (mnvm_noErr != err) {
+ (void) FSDeleteObject(&NewRef);
+ }
+ }
+
+ return err;
+}
+#endif
+
+#if IncludeSonyNameNew
+LOCALFUNC CFStringRef CFStringCreateWithPbuf(tPbuf i)
+{
+ return CFStringCreateWithBytes(NULL,
+ (UInt8 *)PbufDat[i], PbufSize[i],
+ kCFStringEncodingMacRoman, false);
+}
+#endif
+
+pascal Boolean NavigationFilterProc(
+ AEDesc* theItem, void* info, void* NavCallBackUserData,
+ NavFilterModes theNavFilterModes);
+pascal Boolean NavigationFilterProc(
+ AEDesc* theItem, void* info, void* NavCallBackUserData,
+ NavFilterModes theNavFilterModes)
+{
+ /* NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*)info; */
+ UnusedParam(theItem);
+ UnusedParam(info);
+ UnusedParam(theNavFilterModes);
+ UnusedParam(NavCallBackUserData);
+
+ return true; /* display all items */
+}
+
+
+pascal void NavigationEventProc(
+ NavEventCallbackMessage callBackSelector,
+ NavCBRecPtr callBackParms, void *NavCallBackUserData);
+pascal void NavigationEventProc(
+ NavEventCallbackMessage callBackSelector,
+ NavCBRecPtr callBackParms, void *NavCallBackUserData)
+{
+ UnusedParam(NavCallBackUserData);
+
+ switch (callBackSelector) {
+ case kNavCBEvent: /* probably not needed in os x */
+ switch (callBackParms->eventData.eventDataParms.event->what)
+ {
+ case updateEvt:
+ {
+ WindowPtr which =
+ (WindowPtr)callBackParms
+ ->eventData.eventDataParms.event
+ ->message;
+
+ BeginUpdate(which);
+
+ if (which == gMyMainWindow) {
+ Update_Screen();
+ }
+
+ EndUpdate(which);
+ }
+ break;
+ }
+ break;
+#if 0
+ case kNavCBUserAction:
+ {
+ NavUserAction userAction = NavDialogGetUserAction(
+ callBackParms->context);
+ switch (userAction) {
+ case kNavUserActionOpen: {
+ /* got something to open */
+ break;
+ }
+ }
+ }
+ break;
+ case kNavCBTerminate:
+ break;
+#endif
+ }
+}
+
+LOCALPROC InsertADisk0(void)
+{
+ NavDialogRef theOpenDialog;
+ NavDialogCreationOptions dialogOptions;
+ NavReplyRecord theReply;
+ NavTypeListHandle openList = NULL;
+ NavEventUPP gEventProc = NewNavEventUPP(NavigationEventProc);
+ NavObjectFilterUPP filterUPP =
+ NewNavObjectFilterUPP(NavigationFilterProc);
+
+ if (noErr == NavGetDefaultDialogCreationOptions(&dialogOptions)) {
+ dialogOptions.modality = kWindowModalityAppModal;
+ dialogOptions.optionFlags |= kNavDontAutoTranslate;
+ dialogOptions.optionFlags &= ~ kNavAllowPreviews;
+ if (noErr == NavCreateGetFileDialog(&dialogOptions,
+ (NavTypeListHandle)openList,
+ gEventProc, NULL,
+ filterUPP, NULL, &theOpenDialog))
+ {
+ MyBeginDialog();
+ (void) NavDialogRun(theOpenDialog);
+ MyEndDialog();
+ if (noErr == NavDialogGetReply(theOpenDialog,
+ &theReply))
+ {
+ if (theReply.validRecord) {
+ ReportStandardOpenDiskError(
+ InsertDisksFromDocList(&theReply.selection));
+ }
+ (void) NavDisposeReply(&theReply);
+ }
+ NavDialogDispose(theOpenDialog);
+ }
+ }
+
+ DisposeNavEventUPP(gEventProc);
+ DisposeNavObjectFilterUPP(filterUPP);
+}
+
+#if IncludeSonyNew
+LOCALPROC MakeNewDisk(ui5b L, CFStringRef NewDiskName)
+{
+#if SaveDialogEnable
+ NavDialogRef theSaveDialog;
+ NavDialogCreationOptions dialogOptions;
+ NavReplyRecord theReply;
+ NavEventUPP gEventProc = NewNavEventUPP(NavigationEventProc);
+
+ if (noErr == NavGetDefaultDialogCreationOptions(&dialogOptions)) {
+ dialogOptions.modality = kWindowModalityAppModal;
+ dialogOptions.saveFileName = NewDiskName;
+ if (noErr == NavCreatePutFileDialog(&dialogOptions,
+ 'TEXT', 'MPS ',
+ gEventProc, NULL,
+ &theSaveDialog))
+ {
+ MyBeginDialog();
+ (void) NavDialogRun(theSaveDialog);
+ MyEndDialog();
+ if (noErr == NavDialogGetReply(theSaveDialog,
+ &theReply))
+ {
+ if (theReply.validRecord) {
+ long itemsInList;
+ AEKeyword keyword;
+ DescType typeCode;
+ FSRef theRef;
+ Size actualSize;
+
+ if (noErr == AECountItems(
+ &theReply.selection, &itemsInList))
+ {
+ if (itemsInList == 1) {
+ if (noErr == AEGetNthPtr(
+ &theReply.selection, 1, typeFSRef,
+ &keyword, &typeCode, (Ptr)&theRef,
+ sizeof(FSRef), &actualSize))
+ {
+ ReportStandardOpenDiskError(
+ MakeNewDisk0(&theRef,
+ theReply.saveFileName, L));
+ }
+ }
+ }
+ }
+ (void) NavDisposeReply(&theReply);
+ }
+ NavDialogDispose(theSaveDialog);
+ }
+ }
+
+ DisposeNavEventUPP(gEventProc);
+#else /* SaveDialogEnable */
+ FSRef OutRef;
+
+ if (mnvm_noErr == FindOrMakeNamedChildRef(&MyDatDirRef,
+ "out", &OutRef))
+ {
+ MakeNewDisk0(&OutRef, NewDiskName, L);
+ }
+#endif /* SaveDialogEnable */
+}
+#endif
+
+LOCALFUNC tMacErr LoadMacRomFromNameFolder(FSRef *ParentRef,
+ char *fileName)
+{
+ tMacErr err;
+ blnr isFolder;
+ FSRef ChildRef;
+
+ if (mnvm_noErr == (err =
+ MyMakeFSRefC(ParentRef, fileName, &isFolder, &ChildRef)))
+ if (mnvm_noErr == (err =
+ LoadMacRomFromFSRef(&ChildRef)))
+ {
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr LoadMacRomFromPrefDir(void)
+{
+ tMacErr err;
+ FSRef PrefRef;
+ FSRef GryphelRef;
+ FSRef ROMsRef;
+
+ if (mnvm_noErr == (err = To_tMacErr(FSFindFolder(kUserDomain,
+ kPreferencesFolderType, kDontCreateFolder, &PrefRef))))
+ if (mnvm_noErr == (err = FindNamedChildRef(&PrefRef,
+ "Gryphel", &GryphelRef)))
+ if (mnvm_noErr == (err = FindNamedChildRef(&GryphelRef,
+ "mnvm_rom", &ROMsRef)))
+ if (mnvm_noErr == (err = LoadMacRomFromNameFolder(&ROMsRef,
+ RomFileName)))
+ {
+ /* ok */
+ }
+
+ return err;
+}
+
+LOCALFUNC blnr LoadMacRom(void)
+{
+ tMacErr err;
+
+ if (mnvm_fnfErr == (err =
+ LoadMacRomFromNameFolder(&MyDatDirRef, RomFileName)))
+ if (mnvm_fnfErr == (err =
+ LoadMacRomFromPrefDir()))
+ {
+ }
+
+ return trueblnr; /* keep launching Mini vMac, regardless */
+}
+
+LOCALFUNC blnr Sony_InsertIth(int i)
+{
+ tMacErr err = mnvm_noErr;
+
+ if ((i > 9) || ! FirstFreeDisk(nullpr)) {
+ return falseblnr;
+ } else {
+ char s[16] = "disk?.dsk";
+
+ s[4] = '0' + i;
+
+ if (! CheckSavetMacErr(InsertADiskFromNameEtc(&MyDatDirRef, s)))
+ {
+ if (mnvm_fnfErr != err) {
+ ReportStandardOpenDiskError(err);
+ }
+ /* stop on first error (including file not found) */
+ return falseblnr;
+ }
+ }
+
+ return trueblnr;
+}
+
+LOCALFUNC blnr LoadInitialImages(void)
+{
+ int i;
+
+ for (i = 1; Sony_InsertIth(i); ++i) {
+ /* stop on first error (including file not found) */
+ }
+
+ return trueblnr;
+}
+
+#if UseActvFile
+
+#define ActvCodeFileName "act_1"
+
+LOCALFUNC tMacErr OpenActvCodeFile(SInt16 *refnum)
+{
+ tMacErr err;
+ FSRef PrefRef;
+ FSRef GryphelRef;
+ FSRef ActRef;
+
+ if (CheckSaveMacErr(FSFindFolder(kUserDomain,
+ kPreferencesFolderType, kDontCreateFolder, &PrefRef)))
+ if (CheckSavetMacErr(FindNamedChildRef(&PrefRef,
+ "Gryphel", &GryphelRef)))
+ if (CheckSavetMacErr(FindNamedChildRef(&GryphelRef,
+ "mnvm_act", &ActRef)))
+ if (CheckSavetMacErr(OpenNamedFileInFolderRef(&ActRef,
+ ActvCodeFileName, refnum)))
+ {
+ /* ok */
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr ActvCodeFileLoad(ui3p p)
+{
+ tMacErr err;
+ SInt16 refnum;
+
+ if (CheckSavetMacErr(OpenActvCodeFile(&refnum))) {
+ ByteCount actualCount;
+ err = To_tMacErr(FSReadFork(refnum, fsFromStart, 0,
+ ActvCodeFileLen, p, &actualCount));
+ (void) FSCloseFork(refnum);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr ActvCodeFileSave(ui3p p)
+{
+ tMacErr err;
+ SInt16 refnum;
+ FSRef PrefRef;
+ FSRef GryphelRef;
+ FSRef ActRef;
+ ByteCount count = ActvCodeFileLen;
+
+ if (CheckSaveMacErr(FSFindFolder(kUserDomain,
+ kPreferencesFolderType, kDontCreateFolder, &PrefRef)))
+ if (CheckSavetMacErr(FindOrMakeNamedChildRef(&PrefRef,
+ "Gryphel", &GryphelRef)))
+ if (CheckSavetMacErr(FindOrMakeNamedChildRef(&GryphelRef,
+ "mnvm_act", &ActRef)))
+ if (CheckSavetMacErr(OpenWriteNamedFileInFolderRef(&ActRef,
+ ActvCodeFileName, &refnum)))
+ {
+ ByteCount actualCount;
+ err = To_tMacErr(FSWriteFork(refnum, fsFromStart, 0,
+ count, p, &actualCount));
+ (void) FSCloseFork(refnum);
+ }
+
+ return err;
+}
+
+#endif /* UseActvFile */
+
+/* --- utilities for adapting to the environment --- */
+
+LOCALPROC MyGetScreenBitsBounds(Rect *r)
+{
+ if (HaveMyCGDisplayBounds()) {
+ CGRect cgr = MyCGDisplayBounds(MyMainDisplayID());
+
+ r->left = cgr.origin.x;
+ r->top = cgr.origin.y;
+ r->right = cgr.origin.x + cgr.size.width;
+ r->bottom = cgr.origin.y + cgr.size.height;
+ }
+}
+
+#if MayNotFullScreen
+LOCALPROC InvalWholeWindow(WindowRef mw)
+{
+ Rect bounds;
+
+ GetWindowPortBounds(mw, &bounds);
+ InvalWindowRect(mw, &bounds);
+}
+#endif
+
+#if MayNotFullScreen
+LOCALPROC MySetMacWindContRect(WindowRef mw, Rect *r)
+{
+ (void) SetWindowBounds (mw, kWindowContentRgn, r);
+ InvalWholeWindow(mw);
+}
+#endif
+
+#if MayNotFullScreen
+LOCALFUNC blnr MyGetWindowTitleBounds(WindowRef mw, Rect *r)
+{
+ return (noErr == GetWindowBounds(mw, kWindowTitleBarRgn, r));
+}
+#endif
+
+#if EnableRecreateW && MayNotFullScreen
+LOCALFUNC blnr MyGetWindowContBounds(WindowRef mw, Rect *r)
+{
+ return (noErr == GetWindowBounds(mw, kWindowContentRgn, r));
+}
+#endif
+
+LOCALPROC MyGetGrayRgnBounds(Rect *r)
+{
+ GetRegionBounds(GetGrayRgn(), (Rect *)r);
+}
+
+#define openOnly 1
+#define openPrint 2
+
+LOCALFUNC blnr GotRequiredParams(AppleEvent *theAppleEvent)
+{
+ DescType typeCode;
+ Size actualSize;
+ OSErr theErr;
+
+ theErr = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr,
+ typeWildCard, &typeCode, NULL, 0, &actualSize);
+ if (errAEDescNotFound == theErr) { /* No more required params. */
+ return trueblnr;
+ } else if (noErr == theErr) { /* More required params! */
+ return /* CheckSysCode(errAEEventNotHandled) */ falseblnr;
+ } else { /* Unexpected Error! */
+ return /* CheckSysCode(theErr) */ falseblnr;
+ }
+}
+
+LOCALFUNC blnr GotRequiredParams0(AppleEvent *theAppleEvent)
+{
+ DescType typeCode;
+ Size actualSize;
+ OSErr theErr;
+
+ theErr = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr,
+ typeWildCard, &typeCode, NULL, 0, &actualSize);
+ if (errAEDescNotFound == theErr) { /* No more required params. */
+ return trueblnr;
+ } else if (noErr == theErr) { /* More required params! */
+ return trueblnr; /* errAEEventNotHandled; */ /*^*/
+ } else { /* Unexpected Error! */
+ return /* CheckSysCode(theErr) */ falseblnr;
+ }
+}
+
+/* call back */ static pascal OSErr OpenOrPrintFiles(
+ AppleEvent *theAppleEvent, AppleEvent *reply, long aRefCon)
+{
+ /*
+ Adapted from IM VI: AppleEvent Manager:
+ Handling Required AppleEvents
+ */
+ AEDescList docList;
+
+ UnusedParam(reply);
+ UnusedParam(aRefCon);
+ /* put the direct parameter (a list of descriptors) into docList */
+ if (noErr == (AEGetParamDesc(theAppleEvent, keyDirectObject,
+ typeAEList, &docList)))
+ {
+ if (GotRequiredParams0(theAppleEvent)) {
+ /* Check for missing required parameters */
+ /* printIt = (openPrint == aRefCon) */
+ ReportStandardOpenDiskError(
+ InsertDisksFromDocList(&docList));
+ }
+ /* vCheckSysCode */ (void) (AEDisposeDesc(&docList));
+ }
+
+ return /* GetASysResultCode() */ 0;
+}
+
+/* call back */ static pascal OSErr DoOpenEvent(
+ AppleEvent *theAppleEvent, AppleEvent *reply, long aRefCon)
+/*
+ This is the alternative to getting an
+ open document event on startup.
+*/
+{
+ UnusedParam(reply);
+ UnusedParam(aRefCon);
+ if (GotRequiredParams0(theAppleEvent)) {
+ }
+ return /* GetASysResultCode() */ 0;
+ /* Make sure there are no additional "required" parameters. */
+}
+
+
+/* call back */ static pascal OSErr DoQuitEvent(
+ AppleEvent *theAppleEvent, AppleEvent *reply, long aRefCon)
+{
+ UnusedParam(reply);
+ UnusedParam(aRefCon);
+ if (GotRequiredParams(theAppleEvent)) {
+ RequestMacOff = trueblnr;
+ }
+
+ return /* GetASysResultCode() */ 0;
+}
+
+LOCALFUNC blnr MyInstallEventHandler(AEEventClass theAEEventClass,
+ AEEventID theAEEventID, ProcPtr p,
+ long handlerRefcon, blnr isSysHandler)
+{
+ return noErr == (AEInstallEventHandler(theAEEventClass,
+ theAEEventID, NewAEEventHandlerUPP((AEEventHandlerProcPtr)p),
+ handlerRefcon, isSysHandler));
+}
+
+LOCALPROC InstallAppleEventHandlers(void)
+{
+ if (noErr == AESetInteractionAllowed(kAEInteractWithLocal))
+ if (MyInstallEventHandler(kCoreEventClass, kAEOpenApplication,
+ (ProcPtr)DoOpenEvent, 0, falseblnr))
+ if (MyInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
+ (ProcPtr)OpenOrPrintFiles, openOnly, falseblnr))
+ if (MyInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
+ (ProcPtr)OpenOrPrintFiles, openPrint, falseblnr))
+ if (MyInstallEventHandler(kCoreEventClass, kAEQuitApplication,
+ (ProcPtr)DoQuitEvent, 0, falseblnr))
+ {
+ }
+}
+
+static pascal OSErr GlobalTrackingHandler(DragTrackingMessage message,
+ WindowRef theWindow, void *handlerRefCon, DragReference theDragRef)
+{
+ RgnHandle hilightRgn;
+ Rect Bounds;
+
+ UnusedParam(theWindow);
+ UnusedParam(handlerRefCon);
+ switch(message) {
+ case kDragTrackingEnterWindow:
+ hilightRgn = NewRgn();
+ if (hilightRgn != NULL) {
+ SetScrnRectFromCoords(&Bounds,
+ 0, 0, vMacScreenHeight, vMacScreenWidth);
+ RectRgn(hilightRgn, &Bounds);
+ ShowDragHilite(theDragRef, hilightRgn, true);
+ DisposeRgn(hilightRgn);
+ }
+ break;
+ case kDragTrackingLeaveWindow:
+ HideDragHilite(theDragRef);
+ break;
+ }
+
+ return noErr;
+}
+
+LOCALFUNC tMacErr InsertADiskOrAliasFromFSRef(FSRef *theRef)
+{
+ tMacErr err;
+ Boolean isFolder;
+ Boolean isAlias;
+
+ if (CheckSaveMacErr(FSResolveAliasFile(theRef, true,
+ &isFolder, &isAlias)))
+ {
+ err = InsertADiskFromFSRef1(theRef);
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr InsertADiskOrAliasFromSpec(FSSpec *spec)
+{
+ tMacErr err;
+ FSRef newRef;
+
+ if (CheckSaveMacErr(FSpMakeFSRef(spec, &newRef)))
+ if (CheckSavetMacErr(InsertADiskOrAliasFromFSRef(&newRef)))
+ {
+ /* ok */
+ }
+
+ return err;
+}
+
+static pascal OSErr GlobalReceiveHandler(WindowRef pWindow,
+ void *handlerRefCon, DragReference theDragRef)
+{
+ SInt16 mouseUpModifiers;
+ unsigned short items;
+ unsigned short index;
+ ItemReference theItem;
+ Size SentSize;
+ HFSFlavor r;
+
+ UnusedParam(pWindow);
+ UnusedParam(handlerRefCon);
+
+ if (noErr == GetDragModifiers(theDragRef,
+ NULL, NULL, &mouseUpModifiers))
+ {
+ MyUpdateKeyboardModifiers(mouseUpModifiers);
+ }
+
+ if (noErr == CountDragItems(theDragRef, &items)) {
+ for (index = 1; index <= items; ++index) {
+ if (noErr == GetDragItemReferenceNumber(theDragRef,
+ index, &theItem))
+ if (noErr == GetFlavorDataSize(theDragRef,
+ theItem, flavorTypeHFS, &SentSize))
+ /*
+ On very old macs SentSize might only be big enough
+ to hold the actual file name. Have not seen this
+ in OS X, but still leave the check
+ as '<=' instead of '=='.
+ */
+ if (SentSize <= sizeof(HFSFlavor))
+ if (noErr == GetFlavorData(theDragRef, theItem,
+ flavorTypeHFS, (Ptr)&r, &SentSize, 0))
+ {
+ ReportStandardOpenDiskError(
+ InsertADiskOrAliasFromSpec(&r.fileSpec));
+ }
+ }
+
+#if 1
+ if (gTrueBackgroundFlag) {
+ ProcessSerialNumber currentProcess = {0, kCurrentProcess};
+
+ (void) SetFrontProcess(¤tProcess);
+ }
+#endif
+ }
+
+ return noErr;
+}
+
+LOCALVAR DragTrackingHandlerUPP gGlobalTrackingHandler = NULL;
+LOCALVAR DragReceiveHandlerUPP gGlobalReceiveHandler = NULL;
+
+LOCALPROC UnPrepareForDragging(void)
+{
+ if (NULL != gGlobalReceiveHandler) {
+ RemoveReceiveHandler(gGlobalReceiveHandler, gMyMainWindow);
+ DisposeDragReceiveHandlerUPP(gGlobalReceiveHandler);
+ gGlobalReceiveHandler = NULL;
+ }
+ if (NULL != gGlobalTrackingHandler) {
+ RemoveTrackingHandler(gGlobalTrackingHandler, gMyMainWindow);
+ DisposeDragTrackingHandlerUPP(gGlobalTrackingHandler);
+ gGlobalTrackingHandler = NULL;
+ }
+}
+
+LOCALFUNC blnr PrepareForDragging(void)
+{
+ blnr IsOk = falseblnr;
+
+ gGlobalTrackingHandler = NewDragTrackingHandlerUPP(
+ GlobalTrackingHandler);
+ if (gGlobalTrackingHandler != NULL) {
+ gGlobalReceiveHandler = NewDragReceiveHandlerUPP(
+ GlobalReceiveHandler);
+ if (gGlobalReceiveHandler != NULL) {
+ if (noErr == InstallTrackingHandler(gGlobalTrackingHandler,
+ gMyMainWindow, nil))
+ {
+ if (noErr == InstallReceiveHandler(
+ gGlobalReceiveHandler, gMyMainWindow, nil))
+ {
+ IsOk = trueblnr;
+ }
+ }
+ }
+ }
+
+ return IsOk;
+}
+
+LOCALPROC HandleEventLocation(EventRef theEvent)
+{
+ Point NewMousePos;
+
+ if (! gWeAreActive) {
+ return;
+ }
+
+ if (noErr == GetEventParameter(theEvent,
+ kEventParamMouseLocation,
+ typeQDPoint,
+ NULL,
+ sizeof(NewMousePos),
+ NULL,
+ &NewMousePos))
+ {
+ MousePositionNotify(NewMousePos);
+ }
+}
+
+LOCALPROC HandleEventModifiers(EventRef theEvent)
+{
+ UInt32 theModifiers;
+
+ if (gWeAreActive) {
+ GetEventParameter(theEvent, kEventParamKeyModifiers,
+ typeUInt32, NULL, sizeof(typeUInt32), NULL, &theModifiers);
+
+ MyUpdateKeyboardModifiers(theModifiers);
+ }
+}
+
+LOCALVAR blnr IsOurMouseMove;
+
+static pascal OSStatus windowEventHandler(
+ EventHandlerCallRef nextHandler, EventRef theEvent,
+ void* userData)
+{
+ OSStatus result = eventNotHandledErr;
+ UInt32 eventClass = GetEventClass(theEvent);
+ UInt32 eventKind = GetEventKind(theEvent);
+
+ UnusedParam(nextHandler);
+ UnusedParam(userData);
+ switch(eventClass) {
+ case kEventClassWindow:
+ switch(eventKind) {
+ case kEventWindowClose:
+ RequestMacOff = trueblnr;
+ result = noErr;
+ break;
+ case kEventWindowDrawContent:
+ Update_Screen();
+ result = noErr;
+ break;
+ case kEventWindowClickContentRgn:
+ MouseIsOutside = falseblnr;
+ HandleEventLocation(theEvent);
+ HandleEventModifiers(theEvent);
+ MyMouseButtonSet(trueblnr);
+ result = noErr;
+ break;
+ case kEventWindowFocusAcquired:
+ gLackFocusFlag = falseblnr;
+ result = noErr;
+ break;
+ case kEventWindowFocusRelinquish:
+ {
+ WindowRef window;
+
+ (void) GetEventParameter(theEvent,
+ kEventParamDirectObject, typeWindowRef,
+ NULL, sizeof(WindowRef), NULL, &window);
+ if ((window == gMyMainWindow)
+ && (window != gMyOldWindow))
+ {
+ ClearWeAreActive();
+ gLackFocusFlag = trueblnr;
+ }
+ }
+ result = noErr;
+ break;
+ }
+ break;
+ case kEventClassMouse:
+ switch(eventKind) {
+ case kEventMouseMoved:
+ case kEventMouseDragged:
+ MouseIsOutside = falseblnr;
+#if 0 /* don't bother, CheckMouseState will take care of it, better */
+ HandleEventLocation(theEvent);
+ HandleEventModifiers(theEvent);
+#endif
+ IsOurMouseMove = trueblnr;
+ result = noErr;
+ break;
+ }
+ break;
+ }
+
+ return result;
+}
+
+LOCALFUNC blnr MyCreateNewWindow(Rect *Bounds, WindowPtr *theWindow)
+{
+ WindowPtr ResultWin;
+ blnr IsOk = falseblnr;
+
+ if (noErr == CreateNewWindow(
+
+#if VarFullScreen
+ UseFullScreen ?
+#endif
+#if MayFullScreen
+ /*
+ appears not to work properly with aglSetWindowRef
+ at least in OS X 10.5.5
+ also doesn't seem to be needed. maybe dates from when
+ didn't cover all screens in full screen mode.
+ */
+ /*
+ Oops, no, kDocumentWindowClass doesn't seem to
+ work quite right if made immediately after
+ launch, title bar gets moved onscreen. At least
+ in Intel 10.5.6, doesn't happen in PowerPC 10.4.11.
+ Oddly, this problem doesn't happen if icon
+ already in dock before launch, but perhaps
+ that is just a timing issue.
+ So use kPlainWindowClass after all.
+ */
+ kPlainWindowClass
+#endif
+#if VarFullScreen
+ :
+#endif
+#if MayNotFullScreen
+ kDocumentWindowClass
+#endif
+ ,
+
+#if VarFullScreen
+ UseFullScreen ?
+#endif
+#if MayFullScreen
+ /* kWindowStandardHandlerAttribute */ 0
+#endif
+#if VarFullScreen
+ :
+#endif
+#if MayNotFullScreen
+ kWindowCloseBoxAttribute
+ | kWindowCollapseBoxAttribute
+#endif
+ ,
+
+ Bounds, &ResultWin
+ ))
+ {
+#if VarFullScreen
+ if (! UseFullScreen)
+#endif
+#if MayNotFullScreen
+ {
+ SetWindowTitleWithCFString(ResultWin,
+ MyAppName /* CFSTR("Mini vMac") */);
+ }
+#endif
+ InstallStandardEventHandler(GetWindowEventTarget(ResultWin));
+ {
+ static const EventTypeSpec windowEvents[] =
+ {
+ {kEventClassWindow, kEventWindowClose},
+ {kEventClassWindow, kEventWindowDrawContent},
+ {kEventClassWindow, kEventWindowClickContentRgn},
+ {kEventClassMouse, kEventMouseMoved},
+ {kEventClassMouse, kEventMouseDragged},
+ {kEventClassWindow, kEventWindowFocusAcquired},
+ {kEventClassWindow, kEventWindowFocusRelinquish}
+ };
+ InstallWindowEventHandler(ResultWin,
+ NewEventHandlerUPP(windowEventHandler),
+ GetEventTypeCount(windowEvents),
+ windowEvents, 0, NULL);
+ }
+
+ *theWindow = ResultWin;
+
+ IsOk = trueblnr;
+ }
+
+ return IsOk;
+}
+
+LOCALPROC CloseAglCurrentContext(void)
+{
+ if (ctx != NULL) {
+ /*
+ Only because MyDrawWithOpenGL doesn't
+ bother to do this. No one
+ uses the CurrentContext
+ without settting it first.
+ */
+ if (GL_TRUE != aglSetCurrentContext(NULL)) {
+ /* err = aglReportError() */
+ }
+ ctx = NULL;
+ }
+}
+
+LOCALPROC CloseMainWindow(void)
+{
+ UnPrepareForDragging();
+
+ if (window_ctx != NULL) {
+ if (GL_TRUE != aglDestroyContext(window_ctx)) {
+ /* err = aglReportError() */
+ }
+ window_ctx = NULL;
+ }
+
+ if (window_fmt != NULL) {
+ aglDestroyPixelFormat(window_fmt);
+ window_fmt = NULL;
+ }
+
+ if (gMyMainWindow != NULL) {
+ DisposeWindow(gMyMainWindow);
+ gMyMainWindow = NULL;
+ }
+}
+
+enum {
+ kMagStateNormal,
+#if EnableMagnify
+ kMagStateMagnifgy,
+#endif
+ kNumMagStates
+};
+
+#define kMagStateAuto kNumMagStates
+
+#if MayNotFullScreen
+LOCALVAR int CurWinIndx;
+LOCALVAR blnr HavePositionWins[kNumMagStates];
+LOCALVAR Point WinPositionWins[kNumMagStates];
+#endif
+
+LOCALFUNC blnr CreateMainWindow(void)
+{
+#if MayNotFullScreen
+ int WinIndx;
+#endif
+ Rect MainScrnBounds;
+ Rect AllScrnBounds;
+ Rect NewWinRect;
+ short leftPos;
+ short topPos;
+ short NewWindowHeight = vMacScreenHeight;
+ short NewWindowWidth = vMacScreenWidth;
+ blnr IsOk = falseblnr;
+
+#if VarFullScreen
+ if (UseFullScreen) {
+ My_HideMenuBar();
+ } else {
+ My_ShowMenuBar();
+ }
+#else
+#if MayFullScreen
+ My_HideMenuBar();
+#endif
+#endif
+
+ MyGetGrayRgnBounds(&AllScrnBounds);
+ MyGetScreenBitsBounds(&MainScrnBounds);
+
+#if EnableMagnify
+ if (UseMagnify) {
+ NewWindowHeight *= MyWindowScale;
+ NewWindowWidth *= MyWindowScale;
+ }
+#endif
+
+ leftPos = MainScrnBounds.left
+ + ((MainScrnBounds.right - MainScrnBounds.left)
+ - NewWindowWidth) / 2;
+ topPos = MainScrnBounds.top
+ + ((MainScrnBounds.bottom - MainScrnBounds.top)
+ - NewWindowHeight) / 2;
+ if (leftPos < MainScrnBounds.left) {
+ leftPos = MainScrnBounds.left;
+ }
+ if (topPos < MainScrnBounds.top) {
+ topPos = MainScrnBounds.top;
+ }
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ ViewHSize = MainScrnBounds.right - MainScrnBounds.left;
+ ViewVSize = MainScrnBounds.bottom - MainScrnBounds.top;
+#if EnableMagnify
+ if (UseMagnify) {
+ ViewHSize /= MyWindowScale;
+ ViewVSize /= MyWindowScale;
+ }
+#endif
+ if (ViewHSize >= vMacScreenWidth) {
+ ViewHStart = 0;
+ ViewHSize = vMacScreenWidth;
+ } else {
+ ViewHSize &= ~ 1;
+ }
+ if (ViewVSize >= vMacScreenHeight) {
+ ViewVStart = 0;
+ ViewVSize = vMacScreenHeight;
+ } else {
+ ViewVSize &= ~ 1;
+ }
+ }
+#endif
+
+ /* Create window rectangle and centre it on the screen */
+ SetRect(&MainScrnBounds, 0, 0, NewWindowWidth, NewWindowHeight);
+ OffsetRect(&MainScrnBounds, leftPos, topPos);
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewWinRect = AllScrnBounds;
+ }
+#endif
+#if VarFullScreen
+ else
+#endif
+#if MayNotFullScreen
+ {
+#if EnableMagnify
+ if (UseMagnify) {
+ WinIndx = kMagStateMagnifgy;
+ } else
+#endif
+ {
+ WinIndx = kMagStateNormal;
+ }
+
+ if (! HavePositionWins[WinIndx]) {
+ WinPositionWins[WinIndx].h = leftPos;
+ WinPositionWins[WinIndx].v = topPos;
+ HavePositionWins[WinIndx] = trueblnr;
+ NewWinRect = MainScrnBounds;
+ } else {
+ SetRect(&NewWinRect, 0, 0, NewWindowWidth, NewWindowHeight);
+ OffsetRect(&NewWinRect,
+ WinPositionWins[WinIndx].h, WinPositionWins[WinIndx].v);
+ }
+ }
+#endif
+
+#if MayNotFullScreen
+ CurWinIndx = WinIndx;
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ hOffset = MainScrnBounds.left - AllScrnBounds.left;
+ vOffset = MainScrnBounds.top - AllScrnBounds.top;
+ }
+#endif
+
+ if (MyCreateNewWindow(&NewWinRect, &gMyMainWindow)) {
+ static const GLint window_attrib[] = {AGL_RGBA,
+#if UseAGLdoublebuff
+ AGL_DOUBLEBUFFER,
+#endif
+ /* AGL_DEPTH_SIZE, 16, */
+ AGL_NONE};
+
+#if 0 != vMacScreenDepth
+ ColorModeWorks = trueblnr;
+#endif
+
+ window_fmt = aglChoosePixelFormat(NULL, 0, window_attrib);
+ if (NULL == window_fmt) {
+ /* err = aglReportError() */
+ } else {
+ window_ctx = aglCreateContext(window_fmt, NULL);
+ if (NULL == window_ctx) {
+ /* err = aglReportError() */
+ } else {
+
+ ShowWindow(gMyMainWindow);
+
+ if (GL_TRUE != (
+ /*
+ aglSetDrawable is deprecated, but use it anyway
+ if at all possible, because aglSetWindowRef
+ doesn't seeem to work properly on a
+ kPlainWindowClass window.
+ Should move to Cocoa.
+ */
+ HaveMyaglSetDrawable()
+ ? MyaglSetDrawable(window_ctx,
+ GetWindowPort(gMyMainWindow))
+ :
+ HaveMyaglSetWindowRef()
+ ? MyaglSetWindowRef(window_ctx, gMyMainWindow)
+ :
+ GL_FALSE))
+ {
+ /* err = aglReportError() */
+ } else {
+ ctx = window_ctx;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ int h = NewWinRect.right - NewWinRect.left;
+ int v = NewWinRect.bottom - NewWinRect.top;
+
+ GLhOffset = hOffset;
+ GLvOffset = v - vOffset;
+ MyAdjustGLforSize(h, v);
+ }
+#endif
+#if VarFullScreen
+ else
+#endif
+#if MayNotFullScreen
+ {
+ GLhOffset = 0;
+ GLvOffset = NewWindowHeight;
+ MyAdjustGLforSize(NewWindowWidth,
+ NewWindowHeight);
+ }
+#endif
+
+#if UseAGLdoublebuff && 1
+ {
+ GLint agSwapInterval = 1;
+ if (GL_TRUE != aglSetInteger(
+ window_ctx, AGL_SWAP_INTERVAL,
+ &agSwapInterval))
+ {
+ MacMsg("oops", "aglSetInteger failed",
+ falseblnr);
+ } else {
+ /*
+ MacMsg("good", "aglSetInteger ok",
+ falseblnr);
+ */
+ }
+ }
+#endif
+
+#if VarFullScreen
+ if (! UseFullScreen)
+#endif
+#if MayNotFullScreen
+ {
+ /* check if window rect valid */
+ Rect tr;
+
+ if (MyGetWindowTitleBounds(gMyMainWindow, &tr))
+ {
+ if (! RectInRgn(&tr, GetGrayRgn())) {
+ MySetMacWindContRect(gMyMainWindow,
+ &MainScrnBounds);
+ if (MyGetWindowTitleBounds(
+ gMyMainWindow, &tr))
+ {
+ if (! RectInRgn(&tr, GetGrayRgn()))
+ {
+ OffsetRect(&MainScrnBounds, 0,
+ AllScrnBounds.top - tr.top);
+ MySetMacWindContRect(
+ gMyMainWindow,
+ &MainScrnBounds);
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ (void) PrepareForDragging();
+
+ IsOk = trueblnr;
+ }
+ }
+ }
+ }
+
+ return IsOk;
+}
+
+#if EnableRecreateW
+LOCALPROC ZapMyWState(void)
+{
+ gMyMainWindow = NULL;
+ window_fmt = NULL;
+ window_ctx = NULL;
+ gGlobalReceiveHandler = NULL;
+ gGlobalTrackingHandler = NULL;
+}
+#endif
+
+#if EnableRecreateW
+struct MyWState {
+ WindowPtr f_MainWindow;
+ AGLPixelFormat f_fmt;
+ AGLContext f_ctx;
+#if MayFullScreen
+ short f_hOffset;
+ short f_vOffset;
+ ui4r f_ViewHSize;
+ ui4r f_ViewVSize;
+ ui4r f_ViewHStart;
+ ui4r f_ViewVStart;
+#endif
+#if VarFullScreen
+ blnr f_UseFullScreen;
+#endif
+#if EnableMagnify
+ blnr f_UseMagnify;
+#endif
+#if MayNotFullScreen
+ int f_CurWinIndx;
+#endif
+ short f_GLhOffset;
+ short f_GLvOffset;
+ DragTrackingHandlerUPP f_gGlobalTrackingHandler;
+ DragReceiveHandlerUPP f_gGlobalReceiveHandler;
+};
+typedef struct MyWState MyWState;
+#endif
+
+#if EnableRecreateW
+LOCALPROC GetMyWState(MyWState *r)
+{
+ r->f_MainWindow = gMyMainWindow;
+ r->f_fmt = window_fmt;
+ r->f_ctx = window_ctx;
+#if MayFullScreen
+ r->f_hOffset = hOffset;
+ r->f_vOffset = vOffset;
+ r->f_ViewHSize = ViewHSize;
+ r->f_ViewVSize = ViewVSize;
+ r->f_ViewHStart = ViewHStart;
+ r->f_ViewVStart = ViewVStart;
+#endif
+#if VarFullScreen
+ r->f_UseFullScreen = UseFullScreen;
+#endif
+#if EnableMagnify
+ r->f_UseMagnify = UseMagnify;
+#endif
+#if MayNotFullScreen
+ r->f_CurWinIndx = CurWinIndx;
+#endif
+ r->f_GLhOffset = GLhOffset;
+ r->f_GLvOffset = GLvOffset;
+ r->f_gGlobalTrackingHandler = gGlobalTrackingHandler;
+ r->f_gGlobalReceiveHandler = gGlobalReceiveHandler;
+}
+#endif
+
+#if EnableRecreateW
+LOCALPROC SetMyWState(MyWState *r)
+{
+ gMyMainWindow = r->f_MainWindow;
+ window_fmt = r->f_fmt;
+ window_ctx = r->f_ctx;
+#if MayFullScreen
+ hOffset = r->f_hOffset;
+ vOffset = r->f_vOffset;
+ ViewHSize = r->f_ViewHSize;
+ ViewVSize = r->f_ViewVSize;
+ ViewHStart = r->f_ViewHStart;
+ ViewVStart = r->f_ViewVStart;
+#endif
+#if VarFullScreen
+ UseFullScreen = r->f_UseFullScreen;
+#endif
+#if EnableMagnify
+ UseMagnify = r->f_UseMagnify;
+#endif
+#if MayNotFullScreen
+ CurWinIndx = r->f_CurWinIndx;
+#endif
+ GLhOffset = r->f_GLhOffset;
+ GLvOffset = r->f_GLvOffset;
+ gGlobalTrackingHandler = r->f_gGlobalTrackingHandler;
+ gGlobalReceiveHandler = r->f_gGlobalReceiveHandler;
+
+ ctx = window_ctx;
+}
+#endif
+
+#if EnableRecreateW
+LOCALFUNC blnr ReCreateMainWindow(void)
+{
+ MyWState old_state;
+ MyWState new_state;
+
+#if VarFullScreen
+ if (! UseFullScreen)
+#endif
+#if MayNotFullScreen
+ {
+ /* save old position */
+ if (gMyMainWindow != NULL) {
+ Rect r;
+
+ if (MyGetWindowContBounds(gMyMainWindow, &r)) {
+ WinPositionWins[CurWinIndx].h = r.left;
+ WinPositionWins[CurWinIndx].v = r.top;
+ }
+ }
+ }
+#endif
+
+#if MayFullScreen
+ UngrabMachine();
+#endif
+
+ CloseAglCurrentContext();
+
+ gMyOldWindow = gMyMainWindow;
+
+ GetMyWState(&old_state);
+
+ ZapMyWState();
+
+#if VarFullScreen
+ UseFullScreen = WantFullScreen;
+#endif
+#if EnableMagnify
+ UseMagnify = WantMagnify;
+#endif
+
+ if (! CreateMainWindow()) {
+ gMyOldWindow = NULL;
+ CloseMainWindow();
+ SetMyWState(&old_state);
+
+#if VarFullScreen
+ if (UseFullScreen) {
+ My_HideMenuBar();
+ } else {
+ My_ShowMenuBar();
+ }
+#endif
+
+ /* avoid retry */
+#if VarFullScreen
+ WantFullScreen = UseFullScreen;
+#endif
+#if EnableMagnify
+ WantMagnify = UseMagnify;
+#endif
+
+ return falseblnr;
+ } else {
+ GetMyWState(&new_state);
+ SetMyWState(&old_state);
+ CloseMainWindow();
+ gMyOldWindow = NULL;
+ SetMyWState(&new_state);
+
+ if (HaveCursorHidden) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ WantCursorHidden = trueblnr;
+ } else {
+ MouseIsOutside = falseblnr; /* don't know */
+ }
+
+ return trueblnr;
+ }
+}
+#endif
+
+#if VarFullScreen && EnableMagnify
+enum {
+ kWinStateWindowed,
+#if EnableMagnify
+ kWinStateFullScreen,
+#endif
+ kNumWinStates
+};
+#endif
+
+#if VarFullScreen && EnableMagnify
+LOCALVAR int WinMagStates[kNumWinStates];
+#endif
+
+LOCALPROC ZapWinStateVars(void)
+{
+#if MayNotFullScreen
+ {
+ int i;
+
+ for (i = 0; i < kNumMagStates; ++i) {
+ HavePositionWins[i] = falseblnr;
+ }
+ }
+#endif
+#if VarFullScreen && EnableMagnify
+ {
+ int i;
+
+ for (i = 0; i < kNumWinStates; ++i) {
+ WinMagStates[i] = kMagStateAuto;
+ }
+ }
+#endif
+}
+
+#if VarFullScreen
+LOCALPROC ToggleWantFullScreen(void)
+{
+ WantFullScreen = ! WantFullScreen;
+
+#if EnableMagnify
+ {
+ int OldWinState =
+ UseFullScreen ? kWinStateFullScreen : kWinStateWindowed;
+ int OldMagState =
+ UseMagnify ? kMagStateMagnifgy : kMagStateNormal;
+ int NewWinState =
+ WantFullScreen ? kWinStateFullScreen : kWinStateWindowed;
+ int NewMagState = WinMagStates[NewWinState];
+
+ WinMagStates[OldWinState] = OldMagState;
+ if (kMagStateAuto != NewMagState) {
+ WantMagnify = (kMagStateMagnifgy == NewMagState);
+ } else {
+ WantMagnify = falseblnr;
+ if (WantFullScreen
+ && HaveMyCGDisplayPixelsWide()
+ && HaveMyCGDisplayPixelsHigh())
+ {
+ CGDirectDisplayID CurMainDisplayID = MyMainDisplayID();
+
+ if ((MyCGDisplayPixelsWide(CurMainDisplayID)
+ >= vMacScreenWidth * MyWindowScale)
+ && (MyCGDisplayPixelsHigh(CurMainDisplayID)
+ >= vMacScreenHeight * MyWindowScale)
+ )
+ {
+ WantMagnify = trueblnr;
+ }
+ }
+ }
+ }
+#endif
+}
+#endif
+
+LOCALPROC LeaveSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Start();
+#endif
+
+ StartUpTimeAdjust();
+}
+
+LOCALPROC EnterSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+}
+
+LOCALPROC DoNotInBackgroundTasks(void)
+{
+#if 0
+ if (HaveMyCGCursorIsVisible()) {
+ HaveCursorHidden = ! MyCGCursorIsVisible();
+
+ /*
+ This shouldn't be needed, but have seen
+ cursor state get messed up in 10.4.
+ If the os x hide count gets off, this
+ should fix it within a few ticks.
+
+ oops, no, doesn't seem to be accurate,
+ and makes things worse. particularly if
+ cursor in obscured state after typing
+ into dialog.
+ */
+ /* trying a different approach further below */
+ }
+#endif
+
+ if (HaveCursorHidden != (
+#if MayNotFullScreen
+ (WantCursorHidden
+#if VarFullScreen
+ || UseFullScreen
+#endif
+ ) &&
+#endif
+ gWeAreActive && ! CurSpeedStopped))
+ {
+ HaveCursorHidden = ! HaveCursorHidden;
+ if (HaveCursorHidden) {
+ MyHideCursor();
+ } else {
+ /*
+ kludge for OS X, where mouse over Dock devider
+ changes cursor, and never sets it back.
+ */
+ SetCursorArrow();
+
+ MyShowCursor();
+ }
+ }
+
+ /* check if actual cursor visibility is what it should be */
+ if (HaveMyCGCursorIsVisible()) {
+ /* but only in OS X 10.3 and later */
+ if (MyCGCursorIsVisible()) {
+ if (HaveCursorHidden) {
+ MyHideCursor();
+ if (MyCGCursorIsVisible()) {
+ /*
+ didn't work, attempt undo so that
+ hide cursor count won't get large
+ */
+ MyShowCursor();
+ }
+ }
+ } else {
+ if (! HaveCursorHidden) {
+ MyShowCursor();
+ /*
+ don't check if worked, assume can't decrement
+ hide cursor count below 0
+ */
+ }
+ }
+ }
+}
+
+LOCALPROC CheckForSavedTasks(void)
+{
+ if (MyEvtQNeedRecover) {
+ MyEvtQNeedRecover = falseblnr;
+
+ /* attempt cleanup, MyEvtQNeedRecover may get set again */
+ MyEvtQTryRecoverFromFull();
+ }
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMouseConstrain();
+ }
+#endif
+
+ if (RequestMacOff) {
+ RequestMacOff = falseblnr;
+ if (AnyDiskInserted()) {
+ MacMsgOverride(kStrQuitWarningTitle,
+ kStrQuitWarningMessage);
+ } else {
+ ForceMacOff = trueblnr;
+ }
+ }
+
+ if (! gWeAreActive) {
+ if (! (gTrueBackgroundFlag || gLackFocusFlag)) {
+ gWeAreActive = trueblnr;
+ ReconnectKeyCodes3();
+ SetCursorArrow();
+ }
+ }
+
+#if VarFullScreen
+ if (gTrueBackgroundFlag && WantFullScreen) {
+ ToggleWantFullScreen();
+ }
+#endif
+
+ if (CurSpeedStopped != (SpeedStopped ||
+ (gTrueBackgroundFlag && ! RunInBackground
+#if EnableAutoSlow && 0
+ && (QuietSubTicks >= 4092)
+#endif
+ )))
+ {
+ CurSpeedStopped = ! CurSpeedStopped;
+ if (CurSpeedStopped) {
+ EnterSpeedStopped();
+ } else {
+ LeaveSpeedStopped();
+ }
+ }
+
+#if EnableRecreateW
+ if (gWeAreActive) {
+ if (0
+#if EnableMagnify
+ || (UseMagnify != WantMagnify)
+#endif
+#if VarFullScreen
+ || (UseFullScreen != WantFullScreen)
+#endif
+ )
+ {
+ (void) ReCreateMainWindow();
+ }
+ }
+#endif
+
+#if MayFullScreen
+ if (GrabMachine != (
+#if VarFullScreen
+ UseFullScreen &&
+#endif
+ gWeAreActive && ! CurSpeedStopped))
+ {
+ GrabMachine = ! GrabMachine;
+ AdjustMachineGrab();
+ }
+#endif
+
+ if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) {
+ MacMsgDisplayOn();
+ }
+
+ if (WantScreensChangedCheck) {
+ WantScreensChangedCheck = falseblnr;
+ MyUpdateOpenGLContext();
+ }
+
+ if (NeedWholeScreenDraw) {
+ NeedWholeScreenDraw = falseblnr;
+ ScreenChangedAll();
+ }
+
+ if (! gWeAreActive) {
+ /*
+ dialog during drag and drop hangs if in background
+ and don't want recursive dialogs
+ so wait til later to display dialog
+ */
+ } else {
+#if IncludeSonyNew
+ if (vSonyNewDiskWanted) {
+#if IncludeSonyNameNew
+ if (vSonyNewDiskName != NotAPbuf) {
+ CFStringRef NewDiskName =
+ CFStringCreateWithPbuf(vSonyNewDiskName);
+ MakeNewDisk(vSonyNewDiskSize, NewDiskName);
+ if (NewDiskName != NULL) {
+ CFRelease(NewDiskName);
+ }
+ PbufDispose(vSonyNewDiskName);
+ vSonyNewDiskName = NotAPbuf;
+ } else
+#endif
+ {
+ MakeNewDisk(vSonyNewDiskSize, NULL);
+ }
+ vSonyNewDiskWanted = falseblnr;
+ /* must be done after may have gotten disk */
+ }
+#endif
+ if (RequestInsertDisk) {
+ RequestInsertDisk = falseblnr;
+ InsertADisk0();
+ }
+ }
+
+#if NeedRequestIthDisk
+ if (0 != RequestIthDisk) {
+ Sony_InsertIth(RequestIthDisk);
+ RequestIthDisk = 0;
+ }
+#endif
+
+ if (gWeAreActive) {
+ DoNotInBackgroundTasks();
+ }
+}
+
+#define CheckItem CheckMenuItem
+
+/* Menu Constants */
+
+#define kAppleMenu 128
+#define kFileMenu 129
+#define kSpecialMenu 130
+
+enum {
+ kCmdIdNull,
+ kCmdIdMoreCommands,
+
+ kNumCmdIds
+};
+
+LOCALFUNC OSStatus MyProcessCommand(MenuCommand inCommandID)
+{
+ OSStatus result = noErr;
+
+ switch (inCommandID) {
+ case kHICommandAbout:
+ DoAboutMsg();
+ break;
+ case kHICommandQuit:
+ RequestMacOff = trueblnr;
+ break;
+ case kHICommandOpen:
+ RequestInsertDisk = trueblnr;
+ break;
+ case kCmdIdMoreCommands:
+ DoMoreCommandsMsg();
+ break;
+ default:
+ result = eventNotHandledErr;
+ break;
+ }
+
+ return result;
+}
+
+LOCALFUNC OSStatus Keyboard_UpdateKeyMap3(EventRef theEvent, blnr down)
+{
+ UInt32 uiKeyCode;
+
+ HandleEventModifiers(theEvent);
+ GetEventParameter(theEvent, kEventParamKeyCode, typeUInt32, NULL,
+ sizeof(uiKeyCode), NULL, &uiKeyCode);
+ Keyboard_UpdateKeyMap2(Keyboard_RemapMac(uiKeyCode & 0x000000FF),
+ down);
+ return noErr;
+}
+
+static pascal OSStatus MyEventHandler(EventHandlerCallRef nextHandler,
+ EventRef theEvent, void * userData)
+{
+ OSStatus result = eventNotHandledErr;
+ UInt32 eventClass = GetEventClass(theEvent);
+ UInt32 eventKind = GetEventKind(theEvent);
+
+ UnusedParam(userData);
+
+ switch (eventClass) {
+ case kEventClassMouse:
+ switch (eventKind) {
+ case kEventMouseDown:
+#if MayFullScreen
+ if (GrabMachine) {
+ HandleEventLocation(theEvent);
+ HandleEventModifiers(theEvent);
+ MyMouseButtonSet(trueblnr);
+ result = noErr;
+ } else
+#endif
+ {
+ result = CallNextEventHandler(
+ nextHandler, theEvent);
+ }
+ break;
+ case kEventMouseUp:
+ HandleEventLocation(theEvent);
+ HandleEventModifiers(theEvent);
+ MyMouseButtonSet(falseblnr);
+#if MayFullScreen
+ if (GrabMachine) {
+ result = noErr;
+ } else
+#endif
+ {
+ result = CallNextEventHandler(
+ nextHandler, theEvent);
+ }
+ break;
+ case kEventMouseMoved:
+ case kEventMouseDragged:
+ IsOurMouseMove = falseblnr;
+ result = CallNextEventHandler(
+ nextHandler, theEvent);
+ /*
+ Actually, mousing over window does't seem
+ to go through here, it goes directly to
+ the window routine. But since not documented
+ either way, leave the check in case this
+ changes.
+ */
+ if (! IsOurMouseMove) {
+ MouseIsOutside = trueblnr;
+#if 0 /* don't bother, CheckMouseState will take care of it, better */
+ HandleEventLocation(theEvent);
+ HandleEventModifiers(theEvent);
+#endif
+ }
+ break;
+ }
+ break;
+ case kEventClassApplication:
+ switch (eventKind) {
+ case kEventAppActivated:
+ gTrueBackgroundFlag = falseblnr;
+ result = noErr;
+ break;
+ case kEventAppDeactivated:
+ gTrueBackgroundFlag = trueblnr;
+ result = noErr;
+ ClearWeAreActive();
+ break;
+ }
+ break;
+ case kEventClassCommand:
+ switch (eventKind) {
+ case kEventProcessCommand:
+ {
+ HICommand hiCommand;
+
+ GetEventParameter(theEvent,
+ kEventParamDirectObject, typeHICommand,
+ NULL, sizeof(HICommand), NULL, &hiCommand);
+ result = MyProcessCommand(hiCommand.commandID);
+ }
+ break;
+ }
+ break;
+ case kEventClassKeyboard:
+ if (! gWeAreActive) {
+ return CallNextEventHandler(nextHandler, theEvent);
+ } else {
+ switch (eventKind) {
+ case kEventRawKeyDown:
+ result = Keyboard_UpdateKeyMap3(
+ theEvent, trueblnr);
+ break;
+ case kEventRawKeyUp:
+ result = Keyboard_UpdateKeyMap3(
+ theEvent, falseblnr);
+ break;
+ case kEventRawKeyModifiersChanged:
+ HandleEventModifiers(theEvent);
+ result = noErr;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return result;
+}
+
+LOCALPROC AppendMenuConvertCStr(
+ MenuRef menu,
+ MenuCommand inCommandID,
+ char *s)
+{
+ CFStringRef cfStr = CFStringCreateFromSubstCStr(s);
+ if (NULL != cfStr) {
+ AppendMenuItemTextWithCFString(menu, cfStr,
+ 0, inCommandID, NULL);
+ CFRelease(cfStr);
+ }
+}
+
+LOCALPROC AppendMenuSep(MenuRef menu)
+{
+ AppendMenuItemTextWithCFString(menu, NULL,
+ kMenuItemAttrSeparator, 0, NULL);
+}
+
+LOCALFUNC MenuRef NewMenuFromConvertCStr(short menuID, char *s)
+{
+ MenuRef menu = NULL;
+
+ CFStringRef cfStr = CFStringCreateFromSubstCStr(s);
+ if (NULL != cfStr) {
+ OSStatus err = CreateNewMenu(menuID, 0, &menu);
+ if (err != noErr) {
+ menu = NULL;
+ } else {
+ (void) SetMenuTitleWithCFString(menu, cfStr);
+ }
+ CFRelease(cfStr);
+ }
+
+ return menu;
+}
+
+LOCALPROC RemoveCommandKeysInMenu(MenuRef theMenu)
+{
+ MenuRef outHierMenu;
+ int i;
+ UInt16 n = CountMenuItems(theMenu);
+
+ for (i = 1; i <= n; ++i) {
+ SetItemCmd(theMenu, i, 0);
+ if (noErr == GetMenuItemHierarchicalMenu(
+ theMenu, i, &outHierMenu)
+ && (NULL != outHierMenu))
+ {
+ RemoveCommandKeysInMenu(outHierMenu);
+ }
+ }
+}
+
+LOCALFUNC blnr InstallOurMenus(void)
+{
+ MenuRef menu;
+ Str255 s;
+
+ PStrFromChar(s, (char)20);
+ menu = NewMenu(kAppleMenu, s);
+ if (menu != NULL) {
+ AppendMenuConvertCStr(menu,
+ kHICommandAbout,
+ kStrMenuItemAbout);
+ AppendMenuSep(menu);
+ InsertMenu(menu, 0);
+ }
+
+ menu = NewMenuFromConvertCStr(kFileMenu, kStrMenuFile);
+ if (menu != NULL) {
+ AppendMenuConvertCStr(menu,
+ kHICommandOpen,
+ kStrMenuItemOpen ";ll");
+ InsertMenu(menu, 0);
+ }
+
+ menu = NewMenuFromConvertCStr(kSpecialMenu, kStrMenuSpecial);
+ if (menu != NULL) {
+ AppendMenuConvertCStr(menu,
+ kCmdIdMoreCommands,
+ kStrMenuItemMore ";ll");
+ InsertMenu(menu, 0);
+ }
+
+ {
+ MenuRef outMenu;
+ MenuItemIndex outIndex;
+
+ if (noErr == GetIndMenuItemWithCommandID(
+ NULL, kHICommandQuit, 1, &outMenu, &outIndex))
+ {
+ RemoveCommandKeysInMenu(outMenu);
+ }
+ }
+
+ DrawMenuBar();
+
+ return trueblnr;
+}
+
+LOCALFUNC blnr InstallOurAppearanceClient(void)
+{
+ RegisterAppearanceClient(); /* maybe not needed ? */
+ return trueblnr;
+}
+
+LOCALVAR blnr DisplayRegistrationCallBackSuccessful = falseblnr;
+
+static void DisplayRegisterReconfigurationCallback(
+ CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags,
+ void *userInfo)
+{
+ UnusedParam(display);
+ UnusedParam(userInfo);
+
+ if (0 != (flags & kCGDisplayBeginConfigurationFlag)) {
+ /* fprintf(stderr, "kCGDisplayBeginConfigurationFlag\n"); */
+ } else {
+#if 0
+ if (0 != (flags & kCGDisplayMovedFlag)) {
+ fprintf(stderr, "kCGDisplayMovedFlag\n");
+ }
+ if (0 != (flags & kCGDisplaySetMainFlag)) {
+ fprintf(stderr, "kCGDisplaySetMainFlag\n");
+ }
+ if (0 != (flags & kCGDisplaySetModeFlag)) {
+ fprintf(stderr, "kCGDisplaySetModeFlag\n");
+ }
+
+ if (0 != (flags & kCGDisplayAddFlag)) {
+ fprintf(stderr, "kCGDisplayAddFlag\n");
+ }
+ if (0 != (flags & kCGDisplayRemoveFlag)) {
+ fprintf(stderr, "kCGDisplayRemoveFlag\n");
+ }
+
+ if (0 != (flags & kCGDisplayEnabledFlag)) {
+ fprintf(stderr, "kCGDisplayEnabledFlag\n");
+ }
+ if (0 != (flags & kCGDisplayDisabledFlag)) {
+ fprintf(stderr, "kCGDisplayDisabledFlag\n");
+ }
+
+ if (0 != (flags & kCGDisplayMirrorFlag)) {
+ fprintf(stderr, "kCGDisplayMirrorFlag\n");
+ }
+ if (0 != (flags & kCGDisplayUnMirrorFlag)) {
+ fprintf(stderr, "kCGDisplayMirrorFlag\n");
+ }
+#endif
+
+ WantScreensChangedCheck = trueblnr;
+
+#if VarFullScreen
+ if (WantFullScreen) {
+ ToggleWantFullScreen();
+ }
+#endif
+ }
+}
+
+LOCALFUNC blnr InstallOurEventHandlers(void)
+{
+ EventTypeSpec eventTypes[] = {
+ {kEventClassMouse, kEventMouseDown},
+ {kEventClassMouse, kEventMouseUp},
+ {kEventClassMouse, kEventMouseMoved},
+ {kEventClassMouse, kEventMouseDragged},
+ {kEventClassKeyboard, kEventRawKeyModifiersChanged},
+ {kEventClassKeyboard, kEventRawKeyDown},
+ {kEventClassKeyboard, kEventRawKeyUp},
+ {kEventClassApplication, kEventAppActivated},
+ {kEventClassApplication, kEventAppDeactivated},
+ {kEventClassCommand, kEventProcessCommand}
+ };
+
+ InstallApplicationEventHandler(
+ NewEventHandlerUPP(MyEventHandler),
+ GetEventTypeCount(eventTypes),
+ eventTypes, NULL, NULL);
+
+ InitKeyCodes();
+
+ InstallAppleEventHandlers();
+
+ if (HaveMyCGDisplayRegisterReconfigurationCallback()) {
+ if (kCGErrorSuccess ==
+ MyCGDisplayRegisterReconfigurationCallback(
+ DisplayRegisterReconfigurationCallback, NULL))
+ {
+ DisplayRegistrationCallBackSuccessful = trueblnr;
+ }
+ }
+
+ /* (void) SetMouseCoalescingEnabled(false, NULL); */
+
+ return trueblnr;
+}
+
+LOCALPROC UnInstallOurEventHandlers(void)
+{
+ if (DisplayRegistrationCallBackSuccessful) {
+ if (HaveMyCGDisplayRemoveReconfigurationCallback()) {
+ MyCGDisplayRemoveReconfigurationCallback(
+ DisplayRegisterReconfigurationCallback, NULL);
+ }
+ }
+}
+
+GLOBALOSGLUPROC WaitForNextTick(void)
+{
+ OSStatus err;
+ EventRef theEvent;
+ ui3r NumChecks;
+ EventTimeout inTimeout;
+ EventTargetRef theTarget = GetEventDispatcherTarget();
+
+ inTimeout = kEventDurationNoWait;
+
+label_retry:
+ NumChecks = 0;
+ while ((NumChecks < 32) && (noErr == (err =
+ ReceiveNextEvent(0, NULL, inTimeout,
+ true, &theEvent))))
+ {
+ (void) SendEventToEventTarget(theEvent, theTarget);
+ ReleaseEvent(theEvent);
+ inTimeout = kEventDurationNoWait;
+ ++NumChecks;
+ }
+
+ CheckForSavedTasks();
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (CurSpeedStopped) {
+ DoneWithDrawingForTick();
+ inTimeout = kEventDurationForever;
+ goto label_retry;
+ }
+
+ if (ExtraTimeNotOver()) {
+ inTimeout =
+ NextTickChangeTime - GetCurrentEventTime();
+ if (inTimeout > 0.0) {
+#if 1
+ struct timespec rqt;
+ struct timespec rmt;
+
+ rqt.tv_sec = 0;
+ rqt.tv_nsec = inTimeout / kEventDurationNanosecond;
+ (void) nanosleep(&rqt, &rmt);
+ inTimeout = kEventDurationNoWait;
+ goto label_retry;
+#elif 1
+ usleep(inTimeout / kEventDurationMicrosecond);
+ inTimeout = kEventDurationNoWait;
+ goto label_retry;
+#else
+ /*
+ This has higher overhead.
+ */
+ goto label_retry;
+#endif
+ }
+ }
+
+ if (CheckDateTime()) {
+#if MySoundEnabled
+ MySound_SecondNotify();
+#endif
+#if EnableDemoMsg
+ DemoModeSecondNotify();
+#endif
+ }
+
+ if (gWeAreActive) {
+ CheckMouseState();
+ }
+
+ OnTrueTime = TrueEmulatedTime;
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("WaitForNextTick, OnTrueTime", OnTrueTime);
+#endif
+}
+
+/* --- platform independent code can be thought of as going here --- */
+
+#include "PROGMAIN.h"
+
+LOCALPROC ReserveAllocAll(void)
+{
+#if dbglog_HAVE
+ dbglog_ReserveAlloc();
+#endif
+ ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr);
+ ReserveAllocOneBlock(&screencomparebuff,
+ vMacScreenNumBytes, 5, trueblnr);
+ ReserveAllocOneBlock(&CntrlDisplayBuff,
+ vMacScreenNumBytes, 5, falseblnr);
+ ReserveAllocOneBlock(&ScalingBuff, vMacScreenNumPixels
+#if 0 != vMacScreenDepth
+ * 4
+#endif
+ , 5, falseblnr);
+ ReserveAllocOneBlock(&CLUT_final, CLUT_finalsz, 5, falseblnr);
+#if MySoundEnabled
+ ReserveAllocOneBlock((ui3p *)&TheSoundBuffer,
+ dbhBufferSize, 5, falseblnr);
+#endif
+
+ EmulationReserveAlloc();
+}
+
+LOCALFUNC blnr AllocMyMemory(void)
+{
+ uimr n;
+ blnr IsOk = falseblnr;
+
+ ReserveAllocOffset = 0;
+ ReserveAllocBigBlock = nullpr;
+ ReserveAllocAll();
+ n = ReserveAllocOffset;
+ ReserveAllocBigBlock = (ui3p)calloc(1, n);
+ if (NULL == ReserveAllocBigBlock) {
+ MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr);
+ } else {
+ ReserveAllocOffset = 0;
+ ReserveAllocAll();
+ if (n != ReserveAllocOffset) {
+ /* oops, program error */
+ } else {
+ IsOk = trueblnr;
+ }
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr InitOSGLU(void)
+{
+ if (AllocMyMemory())
+ if (InitMyApplInfo())
+#if dbglog_HAVE
+ if (dbglog_open())
+#endif
+#if MySoundEnabled
+ if (MySound_Init())
+#endif
+ if (InstallOurAppearanceClient())
+ if (InstallOurEventHandlers())
+ if (InstallOurMenus())
+ if (CreateMainWindow())
+ if (LoadMacRom())
+ if (LoadInitialImages())
+#if UseActvCode
+ if (ActvCodeInit())
+#endif
+#if EmLocalTalk
+ if (InitLocalTalk())
+#endif
+ if (InitLocationDat())
+ if (WaitForRom())
+ {
+ return trueblnr;
+ }
+ return falseblnr;
+}
+
+#if dbglog_HAVE && 0
+IMPORTPROC DoDumpTable(void);
+#endif
+#if dbglog_HAVE && 0
+IMPORTPROC DumpRTC(void);
+#endif
+
+LOCALPROC UnInitOSGLU(void)
+{
+#if dbglog_HAVE && 0
+ DoDumpTable();
+#endif
+#if dbglog_HAVE && 0
+ DumpRTC();
+#endif
+
+ if (MacMsgDisplayed) {
+ MacMsgDisplayOff();
+ }
+
+#if MayFullScreen
+ UngrabMachine();
+#endif
+
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+
+ CloseAglCurrentContext();
+ CloseMainWindow();
+
+#if MayFullScreen
+ My_ShowMenuBar();
+#endif
+
+#if IncludePbufs
+ UnInitPbufs();
+#endif
+ UnInitDrives();
+
+ if (! gTrueBackgroundFlag) {
+ CheckSavedMacMsg();
+ }
+
+ UnInstallOurEventHandlers();
+
+#if dbglog_HAVE
+ dbglog_close();
+#endif
+
+ UnInitMyApplInfo();
+
+ ForceShowCursor();
+}
+
+LOCALPROC ZapOSGLUVars(void)
+{
+ InitDrives();
+ ZapWinStateVars();
+}
+
+/* adapted from Apple "Technical Q&A QA1061" */
+
+static pascal OSStatus EventLoopEventHandler(
+ EventHandlerCallRef inHandlerCallRef, EventRef inEvent,
+ void *inUserData)
+/*
+ This code contains the standard Carbon event dispatch loop,
+ as per "Inside Macintosh: Handling Carbon Events", Listing 3-10,
+ except:
+
+ o this loop supports yielding to cooperative threads based on the
+ application maintaining the gNumberOfRunningThreads global
+ variable, and
+
+ o it also works around a problem with the Inside Macintosh code
+ which unexpectedly quits when run on traditional Mac OS 9.
+
+ See RunApplicationEventLoopWithCooperativeThreadSupport for
+ an explanation of why this is inside a Carbon event handler.
+
+ The code in Inside Mac has a problem in that it quits the
+ event loop when ReceiveNextEvent returns an error. This is
+ wrong because ReceiveNextEvent can return eventLoopQuitErr
+ when you call WakeUpProcess on traditional Mac OS. So, rather
+ than relying on an error from ReceiveNextEvent, this routine tracks
+ whether the application is really quitting by installing a
+ customer handler for the kEventClassApplication/kEventAppQuit
+ Carbon event. All the custom handler does is call through
+ to the previous handler and, if it returns noErr (which indicates
+ the application is quitting, it sets quitNow so that our event
+ loop quits.
+
+ Note that this approach continues to support
+ QuitApplicationEventLoop, which is a simple wrapper that just posts
+ a kEventClassApplication/kEventAppQuit event to the event loop.
+*/
+{
+ UnusedParam(inHandlerCallRef);
+ UnusedParam(inEvent);
+ UnusedParam(inUserData);
+
+ ProgramMain();
+ QuitApplicationEventLoop();
+
+ return noErr;
+}
+
+LOCALPROC RunApplicationEventLoopWithCooperativeThreadSupport(void)
+/*
+ A reimplementation of RunApplicationEventLoop that supports
+ yielding time to cooperative threads.
+*/
+{
+ static const EventTypeSpec eventSpec = {'KWIN', 'KWIN'};
+ EventHandlerUPP theEventLoopEventHandlerUPP = nil;
+ EventHandlerRef installedHandler = NULL;
+ EventRef dummyEvent = nil;
+
+/*
+ Install EventLoopEventHandler, create a dummy event and post it,
+ and then call RunApplicationEventLoop. The rationale for this
+ is as follows: We want to unravel RunApplicationEventLoop so
+ that we can can yield to cooperative threads. In fact, the
+ core code for RunApplicationEventLoop is pretty easy (you
+ can see it above in EventLoopEventHandler). However, if you
+ just execute this code you miss out on all the standard event
+ handlers. These are relatively easy to reproduce (handling
+ the quit event and so on), but doing so is a pain because
+ a) it requires a bunch boilerplate code, and b) if Apple
+ extends the list of standard event handlers, your application
+ wouldn't benefit. So, we execute our event loop from within
+ a Carbon event handler that we cause to be executed by
+ explicitly posting an event to our event loop. Thus, the
+ standard event handlers are installed while our event loop runs.
+*/
+ if (nil == (theEventLoopEventHandlerUPP
+ = NewEventHandlerUPP(EventLoopEventHandler)))
+ {
+ /* fail */
+ } else
+ if (noErr != InstallEventHandler(GetApplicationEventTarget(),
+ theEventLoopEventHandlerUPP, 1, &eventSpec, nil,
+ &installedHandler))
+ {
+ /* fail */
+ } else
+ if (noErr != MacCreateEvent(nil, 'KWIN', 'KWIN',
+ GetCurrentEventTime(), kEventAttributeNone,
+ &dummyEvent))
+ {
+ /* fail */
+ } else
+ if (noErr != PostEventToQueue(GetMainEventQueue(),
+ dummyEvent, kEventPriorityHigh))
+ {
+ /* fail */
+ } else
+ {
+ RunApplicationEventLoop();
+ }
+
+ if (nil != dummyEvent) {
+ ReleaseEvent(dummyEvent);
+ }
+
+ if (NULL != installedHandler) {
+ (void) RemoveEventHandler(installedHandler);
+ }
+}
+
+int main(void)
+{
+ ZapOSGLUVars();
+ if (InitOSGLU()) {
+ RunApplicationEventLoopWithCooperativeThreadSupport();
+ }
+ UnInitOSGLU();
+
+ return 0;
+}
--- /dev/null
+++ b/src/OSGLUSD2.c
@@ -1,0 +1,4217 @@
+/*
+ OSGLUSD2.c
+
+ Copyright (C) 2012 Paul C. Pratt, Manuel Alfayate
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Operating System GLUe for SDl 2.0 library
+
+ All operating system dependent code for the
+ SDL Library should go here.
+*/
+
+#include "CNFGRAPI.h"
+#include "SYSDEPNS.h"
+#include "ENDIANAC.h"
+
+#include "MYOSGLUE.h"
+
+#include "STRCONST.h"
+
+/* --- some simple utilities --- */
+
+GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount)
+{
+ (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount);
+}
+
+/* --- control mode and internationalization --- */
+
+#define NeedCell2PlainAsciiMap 1
+
+#include "INTLCHAR.h"
+
+#ifndef CanGetAppPath
+#define CanGetAppPath 1
+#endif
+
+LOCALVAR char *d_arg = NULL;
+LOCALVAR char *n_arg = NULL;
+
+#if CanGetAppPath
+LOCALVAR char *app_parent = NULL;
+LOCALVAR char *pref_dir = NULL;
+#endif
+
+#ifdef _WIN32
+#define MyPathSep '\\'
+#else
+#define MyPathSep '/'
+#endif
+
+LOCALFUNC tMacErr ChildPath(char *x, char *y, char **r)
+{
+ tMacErr err = mnvm_miscErr;
+ int nx = strlen(x);
+ int ny = strlen(y);
+ {
+ if ((nx > 0) && (MyPathSep == x[nx - 1])) {
+ --nx;
+ }
+ {
+ int nr = nx + 1 + ny;
+ char *p = malloc(nr + 1);
+ if (p != NULL) {
+ char *p2 = p;
+ (void) memcpy(p2, x, nx);
+ p2 += nx;
+ *p2++ = MyPathSep;
+ (void) memcpy(p2, y, ny);
+ p2 += ny;
+ *p2 = 0;
+ *r = p;
+ err = mnvm_noErr;
+ }
+ }
+ }
+
+ return err;
+}
+
+LOCALPROC MyMayFree(char *p)
+{
+ if (NULL != p) {
+ free(p);
+ }
+}
+
+/* --- sending debugging info to file --- */
+
+#if dbglog_HAVE
+
+#ifndef dbglog_ToStdErr
+#define dbglog_ToStdErr 0
+#endif
+#ifndef dbglog_ToSDL_Log
+#define dbglog_ToSDL_Log 0
+#endif
+
+#if ! dbglog_ToStdErr
+LOCALVAR FILE *dbglog_File = NULL;
+#endif
+
+LOCALFUNC blnr dbglog_open0(void)
+{
+#if dbglog_ToStdErr || dbglog_ToSDL_Log
+ return trueblnr;
+#else
+ if (NULL == app_parent) {
+ dbglog_File = fopen("dbglog.txt", "w");
+ } else {
+ char *t;
+
+ if (mnvm_noErr == ChildPath(app_parent, "dbglog.txt", &t)) {
+ dbglog_File = fopen(t, "w");
+ free(t);
+ }
+ }
+
+ return (NULL != dbglog_File);
+#endif
+}
+
+LOCALPROC dbglog_write0(char *s, uimr L)
+{
+#if dbglog_ToStdErr
+ (void) fwrite(s, 1, L, stderr);
+#elif dbglog_ToSDL_Log
+ char t[256 + 1];
+
+ if (L > 256) {
+ L = 256;
+ }
+ (void) memcpy(t, s, L);
+ t[L] = 1;
+
+ SDL_Log("%s", t);
+#else
+ if (dbglog_File != NULL) {
+ (void) fwrite(s, 1, L, dbglog_File);
+ }
+#endif
+}
+
+LOCALPROC dbglog_close0(void)
+{
+#if ! dbglog_ToStdErr
+ if (dbglog_File != NULL) {
+ fclose(dbglog_File);
+ dbglog_File = NULL;
+ }
+#endif
+}
+
+#endif
+
+/* --- information about the environment --- */
+
+#define WantColorTransValid 0
+
+#include "COMOSGLU.h"
+
+#include "PBUFSTDC.h"
+
+#include "CONTROLM.h"
+
+/* --- text translation --- */
+
+LOCALPROC NativeStrFromCStr(char *r, char *s)
+{
+ ui3b ps[ClStrMaxLength];
+ int i;
+ int L;
+
+ ClStrFromSubstCStr(&L, ps, s);
+
+ for (i = 0; i < L; ++i) {
+ r[i] = Cell2PlainAsciiMap[ps[i]];
+ }
+
+ r[L] = 0;
+}
+
+/* --- drives --- */
+
+#define NotAfileRef NULL
+
+#ifndef UseRWops
+#define UseRWops 0
+#endif
+
+#if UseRWops
+#define MyFilePtr SDL_RWops *
+#define MySeek SDL_RWseek
+#define MySeekSet RW_SEEK_SET
+#define MySeekCur RW_SEEK_CUR
+#define MySeekEnd RW_SEEK_END
+#define MyFileRead(ptr, size, nmemb, stream) \
+ SDL_RWread(stream, ptr, size, nmemb)
+#define MyFileWrite(ptr, size, nmemb, stream) \
+ SDL_RWwrite(stream, ptr, size, nmemb)
+#define MyFileTell SDL_RWtell
+#define MyFileClose SDL_RWclose
+#define MyFileOpen SDL_RWFromFile
+#else
+#define MyFilePtr FILE *
+#define MySeek fseek
+#define MySeekSet SEEK_SET
+#define MySeekCur SEEK_CUR
+#define MySeekEnd SEEK_END
+#define MyFileRead fread
+#define MyFileWrite fwrite
+#define MyFileTell ftell
+#define MyFileClose fclose
+#define MyFileOpen fopen
+#define MyFileEof feof
+#endif
+
+LOCALVAR MyFilePtr Drives[NumDrives]; /* open disk image files */
+
+LOCALPROC InitDrives(void)
+{
+ /*
+ This isn't really needed, Drives[i] and DriveNames[i]
+ need not have valid values when not vSonyIsInserted[i].
+ */
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ Drives[i] = NotAfileRef;
+ }
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer,
+ tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
+ ui5r *Sony_ActCount)
+{
+ tMacErr err = mnvm_miscErr;
+ MyFilePtr refnum = Drives[Drive_No];
+ ui5r NewSony_Count = 0;
+
+ if (MySeek(refnum, Sony_Start, MySeekSet) >= 0) {
+ if (IsWrite) {
+ NewSony_Count = MyFileWrite(Buffer, 1, Sony_Count, refnum);
+ } else {
+ NewSony_Count = MyFileRead(Buffer, 1, Sony_Count, refnum);
+ }
+
+ if (NewSony_Count == Sony_Count) {
+ err = mnvm_noErr;
+ }
+ }
+
+ if (nullpr != Sony_ActCount) {
+ *Sony_ActCount = NewSony_Count;
+ }
+
+ return err; /*& figure out what really to return &*/
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count)
+{
+ tMacErr err = mnvm_miscErr;
+ MyFilePtr refnum = Drives[Drive_No];
+ long v;
+
+ if (MySeek(refnum, 0, MySeekEnd) >= 0) {
+ v = MyFileTell(refnum);
+ if (v >= 0) {
+ *Sony_Count = v;
+ err = mnvm_noErr;
+ }
+ }
+
+ return err; /*& figure out what really to return &*/
+}
+
+LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit)
+{
+ MyFilePtr refnum = Drives[Drive_No];
+
+ DiskEjectedNotify(Drive_No);
+
+ MyFileClose(refnum);
+ Drives[Drive_No] = NotAfileRef; /* not really needed */
+
+ return mnvm_noErr;
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No)
+{
+ return vSonyEject0(Drive_No, falseblnr);
+}
+
+LOCALPROC UnInitDrives(void)
+{
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ if (vSonyIsInserted(i)) {
+ (void) vSonyEject(i);
+ }
+ }
+}
+
+LOCALFUNC blnr Sony_Insert0(MyFilePtr refnum, blnr locked,
+ char *drivepath)
+{
+ tDrive Drive_No;
+ blnr IsOk = falseblnr;
+
+ if (! FirstFreeDisk(&Drive_No)) {
+ MacMsg(kStrTooManyImagesTitle, kStrTooManyImagesMessage,
+ falseblnr);
+ } else {
+ /* printf("Sony_Insert0 %d\n", (int)Drive_No); */
+
+ {
+ Drives[Drive_No] = refnum;
+ DiskInsertNotify(Drive_No, locked);
+
+ IsOk = trueblnr;
+ }
+ }
+
+ if (! IsOk) {
+ MyFileClose(refnum);
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr Sony_Insert1(char *drivepath, blnr silentfail)
+{
+ blnr locked = falseblnr;
+ /* printf("Sony_Insert1 %s\n", drivepath); */
+ MyFilePtr refnum = MyFileOpen(drivepath, "rb+");
+ if (NULL == refnum) {
+ locked = trueblnr;
+ refnum = MyFileOpen(drivepath, "rb");
+ }
+ if (NULL == refnum) {
+ if (! silentfail) {
+ MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
+ }
+ } else {
+ return Sony_Insert0(refnum, locked, drivepath);
+ }
+ return falseblnr;
+}
+
+LOCALFUNC tMacErr LoadMacRomFrom(char *path)
+{
+ tMacErr err;
+ MyFilePtr ROM_File;
+ int File_Size;
+
+ ROM_File = MyFileOpen(path, "rb");
+ if (NULL == ROM_File) {
+ err = mnvm_fnfErr;
+ } else {
+ File_Size = MyFileRead(ROM, 1, kROM_Size, ROM_File);
+ if (File_Size != kROM_Size) {
+#ifdef MyFileEof
+ if (MyFileEof(ROM_File))
+#else
+ if (File_Size > 0)
+#endif
+ {
+ MacMsgOverride(kStrShortROMTitle,
+ kStrShortROMMessage);
+ err = mnvm_eofErr;
+ } else {
+ MacMsgOverride(kStrNoReadROMTitle,
+ kStrNoReadROMMessage);
+ err = mnvm_miscErr;
+ }
+ } else {
+ err = ROM_IsValid();
+ }
+ MyFileClose(ROM_File);
+ }
+
+ return err;
+}
+
+LOCALFUNC blnr Sony_Insert1a(char *drivepath, blnr silentfail)
+{
+ blnr v;
+
+ if (! ROM_loaded) {
+ v = (mnvm_noErr == LoadMacRomFrom(drivepath));
+ } else {
+ v = Sony_Insert1(drivepath, silentfail);
+ }
+
+ return v;
+}
+
+LOCALFUNC blnr Sony_Insert2(char *s)
+{
+ char *d =
+#if CanGetAppPath
+ (NULL == d_arg) ? app_parent :
+#endif
+ d_arg;
+ blnr IsOk = falseblnr;
+
+ if (NULL == d) {
+ IsOk = Sony_Insert1(s, trueblnr);
+ } else {
+ char *t;
+
+ if (mnvm_noErr == ChildPath(d, s, &t)) {
+ IsOk = Sony_Insert1(t, trueblnr);
+ free(t);
+ }
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr Sony_InsertIth(int i)
+{
+ blnr v;
+
+ if ((i > 9) || ! FirstFreeDisk(nullpr)) {
+ v = falseblnr;
+ } else {
+ char s[] = "disk?.dsk";
+
+ s[4] = '0' + i;
+
+ v = Sony_Insert2(s);
+ }
+
+ return v;
+}
+
+LOCALFUNC blnr LoadInitialImages(void)
+{
+ if (! AnyDiskInserted()) {
+ int i;
+
+ for (i = 1; Sony_InsertIth(i); ++i) {
+ /* stop on first error (including file not found) */
+ }
+ }
+
+ return trueblnr;
+}
+
+/* --- ROM --- */
+
+LOCALVAR char *rom_path = NULL;
+
+#if CanGetAppPath
+LOCALFUNC tMacErr LoadMacRomFromPrefDir(void)
+{
+ tMacErr err;
+ char *t = NULL;
+ char *t2 = NULL;
+
+ if (NULL == pref_dir) {
+ err = mnvm_fnfErr;
+ } else
+ if (mnvm_noErr != (err =
+ ChildPath(pref_dir, "mnvm_rom", &t)))
+ {
+ /* fail */
+ } else
+ if (mnvm_noErr != (err =
+ ChildPath(t, RomFileName, &t2)))
+ {
+ /* fail */
+ } else
+ {
+ err = LoadMacRomFrom(t2);
+ }
+
+ MyMayFree(t2);
+ MyMayFree(t);
+
+ return err;
+}
+#endif
+
+#if CanGetAppPath
+LOCALFUNC tMacErr LoadMacRomFromAppPar(void)
+{
+ tMacErr err;
+ char *d = (NULL == d_arg) ? app_parent : d_arg;
+ char *t = NULL;
+
+ if (NULL == d) {
+ err = mnvm_fnfErr;
+ } else
+ if (mnvm_noErr != (err =
+ ChildPath(d, RomFileName, &t)))
+ {
+ /* fail */
+ } else
+ {
+ err = LoadMacRomFrom(t);
+ }
+
+ MyMayFree(t);
+
+ return err;
+}
+#endif
+
+LOCALFUNC blnr LoadMacRom(void)
+{
+ tMacErr err;
+
+ if ((NULL == rom_path)
+ || (mnvm_fnfErr == (err = LoadMacRomFrom(rom_path))))
+#if CanGetAppPath
+ if (mnvm_fnfErr == (err = LoadMacRomFromAppPar()))
+ if (mnvm_fnfErr == (err = LoadMacRomFromPrefDir()))
+#endif
+ if (mnvm_fnfErr == (err = LoadMacRomFrom(RomFileName)))
+ {
+ }
+
+ return trueblnr; /* keep launching Mini vMac, regardless */
+}
+
+/* --- video out --- */
+
+#if MayFullScreen
+LOCALVAR int hOffset;
+LOCALVAR int vOffset;
+#endif
+
+#if VarFullScreen
+LOCALVAR blnr UseFullScreen = (WantInitFullScreen != 0);
+#endif
+
+#if EnableMagnify
+LOCALVAR blnr UseMagnify = (WantInitMagnify != 0);
+#endif
+
+#ifndef UseSDLscaling
+#define UseSDLscaling 0
+#endif
+
+LOCALVAR blnr gBackgroundFlag = falseblnr;
+LOCALVAR blnr gTrueBackgroundFlag = falseblnr;
+LOCALVAR blnr CurSpeedStopped = trueblnr;
+
+#if EnableMagnify && ! UseSDLscaling
+#define MaxScale MyWindowScale
+#else
+#define MaxScale 1
+#endif
+
+
+LOCALVAR SDL_Window *my_main_wind = NULL;
+LOCALVAR SDL_Renderer *my_renderer = NULL;
+LOCALVAR SDL_Texture *my_texture = NULL;
+LOCALVAR SDL_PixelFormat *my_format = NULL;
+
+LOCALVAR ui3p ScalingBuff = nullpr;
+
+LOCALVAR ui3p CLUT_final;
+
+#define CLUT_finalsz (256 * 8 * 4 * MaxScale)
+ /*
+ 256 possible values of one byte
+ 8 pixels per byte maximum (when black and white)
+ 4 bytes per destination pixel maximum
+ multiplied by MyWindowScale if EnableMagnify
+ */
+
+#define ScrnMapr_DoMap UpdateBWDepth3Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth4Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 4
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth5Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#if EnableMagnify && ! UseSDLscaling
+
+#define ScrnMapr_DoMap UpdateBWDepth3ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth4ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 4
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth5ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#endif /* EnableMagnify && ! UseSDLscaling */
+
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+
+#define ScrnMapr_DoMap UpdateColorDepth3Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth4Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 4
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth5Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#if EnableMagnify && ! UseSDLscaling
+
+#define ScrnMapr_DoMap UpdateColorDepth3ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth4ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 4
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth5ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#endif /* EnableMagnify && ! UseSDLscaling */
+
+#endif
+
+
+LOCALPROC HaveChangedScreenBuff(ui4r top, ui4r left,
+ ui4r bottom, ui4r right)
+{
+ int i;
+ int j;
+ ui3b *p;
+ Uint32 pixel;
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ Uint32 CLUT_pixel[CLUT_size];
+#endif
+ Uint32 BWLUT_pixel[2];
+ ui5r top2;
+ ui5r left2;
+ ui5r bottom2;
+ ui5r right2;
+ void *pixels;
+ int pitch;
+ SDL_Rect src_rect;
+ SDL_Rect dst_rect;
+ int XDest;
+ int YDest;
+ int DestWidth;
+ int DestHeight;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ if (top < ViewVStart) {
+ top = ViewVStart;
+ }
+ if (left < ViewHStart) {
+ left = ViewHStart;
+ }
+ if (bottom > ViewVStart + ViewVSize) {
+ bottom = ViewVStart + ViewVSize;
+ }
+ if (right > ViewHStart + ViewHSize) {
+ right = ViewHStart + ViewHSize;
+ }
+
+ if ((top >= bottom) || (left >= right)) {
+ goto label_exit;
+ }
+ }
+#endif
+
+ XDest = left;
+ YDest = top;
+ DestWidth = (right - left);
+ DestHeight = (bottom - top);
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ XDest -= ViewHStart;
+ YDest -= ViewVStart;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ XDest *= MyWindowScale;
+ YDest *= MyWindowScale;
+ DestWidth *= MyWindowScale;
+ DestHeight *= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ XDest += hOffset;
+ YDest += vOffset;
+ }
+#endif
+
+ top2 = top;
+ left2 = left;
+ bottom2 = bottom;
+ right2 = right;
+
+#if EnableMagnify && ! UseSDLscaling
+ if (UseMagnify) {
+ top2 *= MyWindowScale;
+ left2 *= MyWindowScale;
+ bottom2 *= MyWindowScale;
+ right2 *= MyWindowScale;
+ }
+#endif
+
+ if (0 != SDL_LockTexture(my_texture, NULL, &pixels, &pitch)) {
+ return;
+ }
+
+ {
+
+ int bpp = my_format->BytesPerPixel;
+ ui5r ExpectedPitch = vMacScreenWidth * bpp;
+
+#if EnableMagnify && ! UseSDLscaling
+ if (UseMagnify) {
+ ExpectedPitch *= MyWindowScale;
+ }
+#endif
+
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+#if vMacScreenDepth < 4
+ for (i = 0; i < CLUT_size; ++i) {
+ CLUT_pixel[i] = SDL_MapRGB(my_format,
+ CLUT_reds[i] >> 8,
+ CLUT_greens[i] >> 8,
+ CLUT_blues[i] >> 8);
+ }
+#endif
+ } else
+#endif
+ {
+ BWLUT_pixel[1] = SDL_MapRGB(my_format, 0, 0, 0);
+ /* black */
+ BWLUT_pixel[0] = SDL_MapRGB(my_format, 255, 255, 255);
+ /* white */
+ }
+
+ if ((0 == ((bpp - 1) & bpp)) /* a power of 2 */
+ && (pitch == ExpectedPitch)
+#if (vMacScreenDepth > 3)
+ && ! UseColorMode
+#endif
+ )
+ {
+ int k;
+ Uint32 v;
+#if EnableMagnify && ! UseSDLscaling
+ int a;
+#endif
+ int PixPerByte =
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ UseColorMode ? (1 << (3 - vMacScreenDepth)) :
+#endif
+ 8;
+ Uint8 *p4 = (Uint8 *)CLUT_final;
+
+ for (i = 0; i < 256; ++i) {
+ for (k = PixPerByte; --k >= 0; ) {
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ if (UseColorMode) {
+ v = CLUT_pixel[
+#if 3 == vMacScreenDepth
+ i
+#else
+ (i >> (k << vMacScreenDepth))
+ & (CLUT_size - 1)
+#endif
+ ];
+ } else
+#endif
+ {
+ v = BWLUT_pixel[(i >> k) & 1];
+ }
+
+#if EnableMagnify && ! UseSDLscaling
+ for (a = UseMagnify ? MyWindowScale : 1; --a >= 0; )
+#endif
+ {
+ switch (bpp) {
+ case 1: /* Assuming 8-bpp */
+ *p4++ = v;
+ break;
+ case 2: /* Probably 15-bpp or 16-bpp */
+ *(Uint16 *)p4 = v;
+ p4 += 2;
+ break;
+ case 4: /* Probably 32-bpp */
+ *(Uint32 *)p4 = v;
+ p4 += 4;
+ break;
+ }
+ }
+ }
+ }
+
+ ScalingBuff = (ui3p)pixels;
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ if (UseColorMode) {
+#if EnableMagnify && ! UseSDLscaling
+ if (UseMagnify) {
+ switch (bpp) {
+ case 1:
+ UpdateColorDepth3ScaledCopy(
+ top, left, bottom, right);
+ break;
+ case 2:
+ UpdateColorDepth4ScaledCopy(
+ top, left, bottom, right);
+ break;
+ case 4:
+ UpdateColorDepth5ScaledCopy(
+ top, left, bottom, right);
+ break;
+ }
+ } else
+#endif
+ {
+ switch (bpp) {
+ case 1:
+ UpdateColorDepth3Copy(top, left, bottom, right);
+ break;
+ case 2:
+ UpdateColorDepth4Copy(top, left, bottom, right);
+ break;
+ case 4:
+ UpdateColorDepth5Copy(top, left, bottom, right);
+ break;
+ }
+ }
+ } else
+#endif
+ {
+#if EnableMagnify && ! UseSDLscaling
+ if (UseMagnify) {
+ switch (bpp) {
+ case 1:
+ UpdateBWDepth3ScaledCopy(
+ top, left, bottom, right);
+ break;
+ case 2:
+ UpdateBWDepth4ScaledCopy(
+ top, left, bottom, right);
+ break;
+ case 4:
+ UpdateBWDepth5ScaledCopy(
+ top, left, bottom, right);
+ break;
+ }
+ } else
+#endif
+ {
+ switch (bpp) {
+ case 1:
+ UpdateBWDepth3Copy(top, left, bottom, right);
+ break;
+ case 2:
+ UpdateBWDepth4Copy(top, left, bottom, right);
+ break;
+ case 4:
+ UpdateBWDepth5Copy(top, left, bottom, right);
+ break;
+ }
+ }
+ }
+
+ } else {
+ ui3b *the_data = (ui3b *)GetCurDrawBuff();
+
+ /* adapted from putpixel in SDL documentation */
+
+ for (i = top2; i < bottom2; ++i) {
+ for (j = left2; j < right2; ++j) {
+ int i0 = i;
+ int j0 = j;
+ Uint8 *bufp = (Uint8 *)pixels
+ + i * pitch + j * bpp;
+
+#if EnableMagnify && ! UseSDLscaling
+ if (UseMagnify) {
+ i0 /= MyWindowScale;
+ j0 /= MyWindowScale;
+ }
+#endif
+
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+#if vMacScreenDepth < 4
+ p = the_data + ((i0 * vMacScreenWidth + j0)
+ >> (3 - vMacScreenDepth));
+ {
+ ui3r k = (*p >> (((~ j0)
+ & ((1 << (3 - vMacScreenDepth)) - 1))
+ << vMacScreenDepth))
+ & (CLUT_size - 1);
+ pixel = CLUT_pixel[k];
+ }
+#elif 4 == vMacScreenDepth
+ p = the_data + ((i0 * vMacScreenWidth + j0) << 1);
+ {
+ ui4r t0 = do_get_mem_word(p);
+ pixel = SDL_MapRGB(my_format,
+ ((t0 & 0x7C00) >> 7)
+ | ((t0 & 0x7000) >> 12),
+ ((t0 & 0x03E0) >> 2)
+ | ((t0 & 0x0380) >> 7),
+ ((t0 & 0x001F) << 3)
+ | ((t0 & 0x001C) >> 2));
+ }
+#elif 5 == vMacScreenDepth
+ p = the_data + ((i0 * vMacScreenWidth + j0) << 2);
+ pixel = SDL_MapRGB(my_format,
+ p[1],
+ p[2],
+ p[3]);
+#endif
+ } else
+#endif
+ {
+ p = the_data + ((i0 * vMacScreenWidth + j0) / 8);
+ pixel = BWLUT_pixel[(*p >> ((~ j0) & 0x7)) & 1];
+ }
+
+ switch (bpp) {
+ case 1: /* Assuming 8-bpp */
+ *bufp = pixel;
+ break;
+ case 2: /* Probably 15-bpp or 16-bpp */
+ *(Uint16 *)bufp = pixel;
+ break;
+ case 3:
+ /* Slow 24-bpp mode, usually not used */
+ if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+ bufp[0] = (pixel >> 16) & 0xff;
+ bufp[1] = (pixel >> 8) & 0xff;
+ bufp[2] = pixel & 0xff;
+ } else {
+ bufp[0] = pixel & 0xff;
+ bufp[1] = (pixel >> 8) & 0xff;
+ bufp[2] = (pixel >> 16) & 0xff;
+ }
+ break;
+ case 4: /* Probably 32-bpp */
+ *(Uint32 *)bufp = pixel;
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ SDL_UnlockTexture(my_texture);
+
+ src_rect.x = left2;
+ src_rect.y = top2;
+ src_rect.w = right2 - left2;
+ src_rect.h = bottom2 - top2;
+
+ dst_rect.x = XDest;
+ dst_rect.y = YDest;
+ dst_rect.w = DestWidth;
+ dst_rect.h = DestHeight;
+
+ /* SDL_RenderClear(my_renderer); */
+ SDL_RenderCopy(my_renderer, my_texture, &src_rect, &dst_rect);
+ SDL_RenderPresent(my_renderer);
+
+#if MayFullScreen
+label_exit:
+ ;
+#endif
+}
+
+LOCALPROC MyDrawChangesAndClear(void)
+{
+ if (ScreenChangedBottom > ScreenChangedTop) {
+ HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft,
+ ScreenChangedBottom, ScreenChangedRight);
+ ScreenClearChanges();
+ }
+}
+
+GLOBALOSGLUPROC DoneWithDrawingForTick(void)
+{
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ AutoScrollScreen();
+ }
+#endif
+ MyDrawChangesAndClear();
+}
+
+/* --- mouse --- */
+
+/* cursor hiding */
+
+LOCALVAR blnr HaveCursorHidden = falseblnr;
+LOCALVAR blnr WantCursorHidden = falseblnr;
+
+LOCALPROC ForceShowCursor(void)
+{
+ if (HaveCursorHidden) {
+ HaveCursorHidden = falseblnr;
+ (void) SDL_ShowCursor(SDL_ENABLE);
+ }
+}
+
+/* cursor moving */
+
+#ifndef HaveWorkingWarp
+#define HaveWorkingWarp 1
+#endif
+
+#if EnableMoveMouse && HaveWorkingWarp
+LOCALFUNC blnr MyMoveMouse(si4b h, si4b v)
+{
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ h -= ViewHStart;
+ v -= ViewVStart;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ h *= MyWindowScale;
+ v *= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ h += hOffset;
+ v += vOffset;
+ }
+#endif
+
+ SDL_WarpMouseInWindow(my_main_wind, h, v);
+
+ return trueblnr;
+}
+#endif
+
+/* cursor state */
+
+LOCALPROC MousePositionNotify(int NewMousePosh, int NewMousePosv)
+{
+ blnr ShouldHaveCursorHidden = trueblnr;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewMousePosh -= hOffset;
+ NewMousePosv -= vOffset;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ NewMousePosh /= MyWindowScale;
+ NewMousePosv /= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewMousePosh += ViewHStart;
+ NewMousePosv += ViewVStart;
+ }
+#endif
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMousePositionSetDelta(NewMousePosh - SavedMouseH,
+ NewMousePosv - SavedMouseV);
+ SavedMouseH = NewMousePosh;
+ SavedMouseV = NewMousePosv;
+ } else
+#endif
+ {
+ if (NewMousePosh < 0) {
+ NewMousePosh = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosh >= vMacScreenWidth) {
+ NewMousePosh = vMacScreenWidth - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+ if (NewMousePosv < 0) {
+ NewMousePosv = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosv >= vMacScreenHeight) {
+ NewMousePosv = vMacScreenHeight - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ ShouldHaveCursorHidden = trueblnr;
+ }
+#endif
+
+ /* if (ShouldHaveCursorHidden || CurMouseButton) */
+ /*
+ for a game like arkanoid, would like mouse to still
+ move even when outside window in one direction
+ */
+ MyMousePositionSet(NewMousePosh, NewMousePosv);
+ }
+
+ WantCursorHidden = ShouldHaveCursorHidden;
+}
+
+#if EnableFSMouseMotion && ! HaveWorkingWarp
+LOCALPROC MousePositionNotifyRelative(int deltah, int deltav)
+{
+ blnr ShouldHaveCursorHidden = trueblnr;
+
+#if EnableMagnify
+ if (UseMagnify) {
+ /*
+ This is not really right. If only move one pixel
+ each time, emulated mouse doesn't move at all.
+ */
+ deltah /= MyWindowScale;
+ deltav /= MyWindowScale;
+ }
+#endif
+
+ MyMousePositionSetDelta(deltah,
+ deltav);
+
+ WantCursorHidden = ShouldHaveCursorHidden;
+}
+#endif
+
+LOCALPROC CheckMouseState(void)
+{
+ /*
+ this doesn't work as desired, doesn't get mouse movements
+ when outside of our window.
+ */
+ int x;
+ int y;
+
+ (void) SDL_GetMouseState(&x, &y);
+ MousePositionNotify(x, y);
+}
+
+/* --- keyboard input --- */
+
+LOCALFUNC ui3r SDLScan2MacKeyCode(SDL_Scancode i)
+{
+ ui3r v = MKC_None;
+
+ switch (i) {
+ case SDL_SCANCODE_BACKSPACE: v = MKC_BackSpace; break;
+ case SDL_SCANCODE_TAB: v = MKC_Tab; break;
+ case SDL_SCANCODE_CLEAR: v = MKC_Clear; break;
+ case SDL_SCANCODE_RETURN: v = MKC_Return; break;
+ case SDL_SCANCODE_PAUSE: v = MKC_Pause; break;
+ case SDL_SCANCODE_ESCAPE: v = MKC_formac_Escape; break;
+ case SDL_SCANCODE_SPACE: v = MKC_Space; break;
+ case SDL_SCANCODE_APOSTROPHE: v = MKC_SingleQuote; break;
+ case SDL_SCANCODE_COMMA: v = MKC_Comma; break;
+ case SDL_SCANCODE_MINUS: v = MKC_Minus; break;
+ case SDL_SCANCODE_PERIOD: v = MKC_Period; break;
+ case SDL_SCANCODE_SLASH: v = MKC_formac_Slash; break;
+ case SDL_SCANCODE_0: v = MKC_0; break;
+ case SDL_SCANCODE_1: v = MKC_1; break;
+ case SDL_SCANCODE_2: v = MKC_2; break;
+ case SDL_SCANCODE_3: v = MKC_3; break;
+ case SDL_SCANCODE_4: v = MKC_4; break;
+ case SDL_SCANCODE_5: v = MKC_5; break;
+ case SDL_SCANCODE_6: v = MKC_6; break;
+ case SDL_SCANCODE_7: v = MKC_7; break;
+ case SDL_SCANCODE_8: v = MKC_8; break;
+ case SDL_SCANCODE_9: v = MKC_9; break;
+ case SDL_SCANCODE_SEMICOLON: v = MKC_SemiColon; break;
+ case SDL_SCANCODE_EQUALS: v = MKC_Equal; break;
+
+ case SDL_SCANCODE_LEFTBRACKET: v = MKC_LeftBracket; break;
+ case SDL_SCANCODE_BACKSLASH: v = MKC_formac_BackSlash; break;
+ case SDL_SCANCODE_RIGHTBRACKET: v = MKC_RightBracket; break;
+ case SDL_SCANCODE_GRAVE: v = MKC_formac_Grave; break;
+
+ case SDL_SCANCODE_A: v = MKC_A; break;
+ case SDL_SCANCODE_B: v = MKC_B; break;
+ case SDL_SCANCODE_C: v = MKC_C; break;
+ case SDL_SCANCODE_D: v = MKC_D; break;
+ case SDL_SCANCODE_E: v = MKC_E; break;
+ case SDL_SCANCODE_F: v = MKC_F; break;
+ case SDL_SCANCODE_G: v = MKC_G; break;
+ case SDL_SCANCODE_H: v = MKC_H; break;
+ case SDL_SCANCODE_I: v = MKC_I; break;
+ case SDL_SCANCODE_J: v = MKC_J; break;
+ case SDL_SCANCODE_K: v = MKC_K; break;
+ case SDL_SCANCODE_L: v = MKC_L; break;
+ case SDL_SCANCODE_M: v = MKC_M; break;
+ case SDL_SCANCODE_N: v = MKC_N; break;
+ case SDL_SCANCODE_O: v = MKC_O; break;
+ case SDL_SCANCODE_P: v = MKC_P; break;
+ case SDL_SCANCODE_Q: v = MKC_Q; break;
+ case SDL_SCANCODE_R: v = MKC_R; break;
+ case SDL_SCANCODE_S: v = MKC_S; break;
+ case SDL_SCANCODE_T: v = MKC_T; break;
+ case SDL_SCANCODE_U: v = MKC_U; break;
+ case SDL_SCANCODE_V: v = MKC_V; break;
+ case SDL_SCANCODE_W: v = MKC_W; break;
+ case SDL_SCANCODE_X: v = MKC_X; break;
+ case SDL_SCANCODE_Y: v = MKC_Y; break;
+ case SDL_SCANCODE_Z: v = MKC_Z; break;
+
+ case SDL_SCANCODE_KP_0: v = MKC_KP0; break;
+ case SDL_SCANCODE_KP_1: v = MKC_KP1; break;
+ case SDL_SCANCODE_KP_2: v = MKC_KP2; break;
+ case SDL_SCANCODE_KP_3: v = MKC_KP3; break;
+ case SDL_SCANCODE_KP_4: v = MKC_KP4; break;
+ case SDL_SCANCODE_KP_5: v = MKC_KP5; break;
+ case SDL_SCANCODE_KP_6: v = MKC_KP6; break;
+ case SDL_SCANCODE_KP_7: v = MKC_KP7; break;
+ case SDL_SCANCODE_KP_8: v = MKC_KP8; break;
+ case SDL_SCANCODE_KP_9: v = MKC_KP9; break;
+
+ case SDL_SCANCODE_KP_PERIOD: v = MKC_Decimal; break;
+ case SDL_SCANCODE_KP_DIVIDE: v = MKC_KPDevide; break;
+ case SDL_SCANCODE_KP_MULTIPLY: v = MKC_KPMultiply; break;
+ case SDL_SCANCODE_KP_MINUS: v = MKC_KPSubtract; break;
+ case SDL_SCANCODE_KP_PLUS: v = MKC_KPAdd; break;
+ case SDL_SCANCODE_KP_ENTER: v = MKC_formac_Enter; break;
+ case SDL_SCANCODE_KP_EQUALS: v = MKC_KPEqual; break;
+
+ case SDL_SCANCODE_UP: v = MKC_Up; break;
+ case SDL_SCANCODE_DOWN: v = MKC_Down; break;
+ case SDL_SCANCODE_RIGHT: v = MKC_Right; break;
+ case SDL_SCANCODE_LEFT: v = MKC_Left; break;
+ case SDL_SCANCODE_INSERT: v = MKC_formac_Help; break;
+ case SDL_SCANCODE_HOME: v = MKC_formac_Home; break;
+ case SDL_SCANCODE_END: v = MKC_formac_End; break;
+ case SDL_SCANCODE_PAGEUP: v = MKC_formac_PageUp; break;
+ case SDL_SCANCODE_PAGEDOWN: v = MKC_formac_PageDown; break;
+
+ case SDL_SCANCODE_F1: v = MKC_formac_F1; break;
+ case SDL_SCANCODE_F2: v = MKC_formac_F2; break;
+ case SDL_SCANCODE_F3: v = MKC_formac_F3; break;
+ case SDL_SCANCODE_F4: v = MKC_formac_F4; break;
+ case SDL_SCANCODE_F5: v = MKC_formac_F5; break;
+ case SDL_SCANCODE_F6: v = MKC_F6; break;
+ case SDL_SCANCODE_F7: v = MKC_F7; break;
+ case SDL_SCANCODE_F8: v = MKC_F8; break;
+ case SDL_SCANCODE_F9: v = MKC_F9; break;
+ case SDL_SCANCODE_F10: v = MKC_F10; break;
+ case SDL_SCANCODE_F11: v = MKC_F11; break;
+ case SDL_SCANCODE_F12: v = MKC_F12; break;
+
+ case SDL_SCANCODE_NUMLOCKCLEAR:
+ v = MKC_formac_ForwardDel; break;
+ case SDL_SCANCODE_CAPSLOCK: v = MKC_formac_CapsLock; break;
+ case SDL_SCANCODE_SCROLLLOCK: v = MKC_ScrollLock; break;
+ case SDL_SCANCODE_RSHIFT: v = MKC_formac_RShift; break;
+ case SDL_SCANCODE_LSHIFT: v = MKC_formac_Shift; break;
+ case SDL_SCANCODE_RCTRL: v = MKC_formac_RControl; break;
+ case SDL_SCANCODE_LCTRL: v = MKC_formac_Control; break;
+ case SDL_SCANCODE_RALT: v = MKC_formac_ROption; break;
+ case SDL_SCANCODE_LALT: v = MKC_formac_Option; break;
+ case SDL_SCANCODE_RGUI: v = MKC_formac_RCommand; break;
+ case SDL_SCANCODE_LGUI: v = MKC_formac_Command; break;
+ /* case SDLK_LSUPER: v = MKC_formac_Option; break; */
+ /* case SDLK_RSUPER: v = MKC_formac_ROption; break; */
+
+ case SDL_SCANCODE_HELP: v = MKC_formac_Help; break;
+ case SDL_SCANCODE_PRINTSCREEN: v = MKC_Print; break;
+
+ case SDL_SCANCODE_UNDO: v = MKC_formac_F1; break;
+ case SDL_SCANCODE_CUT: v = MKC_formac_F2; break;
+ case SDL_SCANCODE_COPY: v = MKC_formac_F3; break;
+ case SDL_SCANCODE_PASTE: v = MKC_formac_F4; break;
+
+ case SDL_SCANCODE_AC_HOME: v = MKC_formac_Home; break;
+
+ case SDL_SCANCODE_KP_A: v = MKC_A; break;
+ case SDL_SCANCODE_KP_B: v = MKC_B; break;
+ case SDL_SCANCODE_KP_C: v = MKC_C; break;
+ case SDL_SCANCODE_KP_D: v = MKC_D; break;
+ case SDL_SCANCODE_KP_E: v = MKC_E; break;
+ case SDL_SCANCODE_KP_F: v = MKC_F; break;
+
+ case SDL_SCANCODE_KP_BACKSPACE: v = MKC_BackSpace; break;
+ case SDL_SCANCODE_KP_CLEAR: v = MKC_Clear; break;
+ case SDL_SCANCODE_KP_COMMA: v = MKC_Comma; break;
+ case SDL_SCANCODE_KP_DECIMAL: v = MKC_Decimal; break;
+
+ default:
+ break;
+ }
+
+ return v;
+}
+
+LOCALPROC DoKeyCode(SDL_Keysym *r, blnr down)
+{
+ ui3r v = SDLScan2MacKeyCode(r->scancode);
+ if (MKC_None != v) {
+ Keyboard_UpdateKeyMap2(v, down);
+ }
+}
+
+LOCALPROC DisableKeyRepeat(void)
+{
+}
+
+LOCALPROC RestoreKeyRepeat(void)
+{
+}
+
+LOCALPROC ReconnectKeyCodes3(void)
+{
+}
+
+LOCALPROC DisconnectKeyCodes3(void)
+{
+ DisconnectKeyCodes2();
+ MyMouseButtonSet(falseblnr);
+}
+
+/* --- time, date, location --- */
+
+#define dbglog_TimeStuff (0 && dbglog_HAVE)
+
+LOCALVAR ui5b TrueEmulatedTime = 0;
+
+#define MyInvTimeDivPow 16
+#define MyInvTimeDiv (1 << MyInvTimeDivPow)
+#define MyInvTimeDivMask (MyInvTimeDiv - 1)
+#define MyInvTimeStep 1089590 /* 1000 / 60.14742 * MyInvTimeDiv */
+
+LOCALVAR Uint32 LastTime;
+
+LOCALVAR Uint32 NextIntTime;
+LOCALVAR ui5b NextFracTime;
+
+LOCALPROC IncrNextTime(void)
+{
+ NextFracTime += MyInvTimeStep;
+ NextIntTime += (NextFracTime >> MyInvTimeDivPow);
+ NextFracTime &= MyInvTimeDivMask;
+}
+
+LOCALPROC InitNextTime(void)
+{
+ NextIntTime = LastTime;
+ NextFracTime = 0;
+ IncrNextTime();
+}
+
+LOCALVAR ui5b NewMacDateInSeconds;
+
+LOCALFUNC blnr UpdateTrueEmulatedTime(void)
+{
+ Uint32 LatestTime;
+ si5b TimeDiff;
+
+ LatestTime = SDL_GetTicks();
+ if (LatestTime != LastTime) {
+
+ NewMacDateInSeconds = LatestTime / 1000;
+ /* no date and time api in SDL */
+
+ LastTime = LatestTime;
+ TimeDiff = (LatestTime - NextIntTime);
+ /* this should work even when time wraps */
+ if (TimeDiff >= 0) {
+ if (TimeDiff > 256) {
+ /* emulation interrupted, forget it */
+ ++TrueEmulatedTime;
+ InitNextTime();
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("emulation interrupted",
+ TrueEmulatedTime);
+#endif
+ } else {
+ do {
+ ++TrueEmulatedTime;
+ IncrNextTime();
+ TimeDiff = (LatestTime - NextIntTime);
+ } while (TimeDiff >= 0);
+ }
+ return trueblnr;
+ } else {
+ if (TimeDiff < -256) {
+#if dbglog_TimeStuff
+ dbglog_writeln("clock set back");
+#endif
+ /* clock goofed if ever get here, reset */
+ InitNextTime();
+ }
+ }
+ }
+ return falseblnr;
+}
+
+
+LOCALFUNC blnr CheckDateTime(void)
+{
+ if (CurMacDateInSeconds != NewMacDateInSeconds) {
+ CurMacDateInSeconds = NewMacDateInSeconds;
+ return trueblnr;
+ } else {
+ return falseblnr;
+ }
+}
+
+LOCALPROC StartUpTimeAdjust(void)
+{
+ LastTime = SDL_GetTicks();
+ InitNextTime();
+}
+
+LOCALFUNC blnr InitLocationDat(void)
+{
+ LastTime = SDL_GetTicks();
+ InitNextTime();
+ NewMacDateInSeconds = LastTime / 1000;
+ CurMacDateInSeconds = NewMacDateInSeconds;
+
+ return trueblnr;
+}
+
+/* --- sound --- */
+
+#if MySoundEnabled
+
+#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */
+#define kSoundBuffers (1 << kLn2SoundBuffers)
+#define kSoundBuffMask (kSoundBuffers - 1)
+
+#define DesiredMinFilledSoundBuffs 3
+ /*
+ if too big then sound lags behind emulation.
+ if too small then sound will have pauses.
+ */
+
+#define kLnOneBuffLen 9
+#define kLnAllBuffLen (kLn2SoundBuffers + kLnOneBuffLen)
+#define kOneBuffLen (1UL << kLnOneBuffLen)
+#define kAllBuffLen (1UL << kLnAllBuffLen)
+#define kLnOneBuffSz (kLnOneBuffLen + kLn2SoundSampSz - 3)
+#define kLnAllBuffSz (kLnAllBuffLen + kLn2SoundSampSz - 3)
+#define kOneBuffSz (1UL << kLnOneBuffSz)
+#define kAllBuffSz (1UL << kLnAllBuffSz)
+#define kOneBuffMask (kOneBuffLen - 1)
+#define kAllBuffMask (kAllBuffLen - 1)
+#define dbhBufferSize (kAllBuffSz + kOneBuffSz)
+
+#define dbglog_SoundStuff (0 && dbglog_HAVE)
+#define dbglog_SoundBuffStats (0 && dbglog_HAVE)
+
+LOCALVAR tpSoundSamp TheSoundBuffer = nullpr;
+volatile static ui4b ThePlayOffset;
+volatile static ui4b TheFillOffset;
+volatile static ui4b MinFilledSoundBuffs;
+#if dbglog_SoundBuffStats
+LOCALVAR ui4b MaxFilledSoundBuffs;
+#endif
+LOCALVAR ui4b TheWriteOffset;
+
+LOCALPROC MySound_Init0(void)
+{
+ ThePlayOffset = 0;
+ TheFillOffset = 0;
+ TheWriteOffset = 0;
+}
+
+LOCALPROC MySound_Start0(void)
+{
+ /* Reset variables */
+ MinFilledSoundBuffs = kSoundBuffers + 1;
+#if dbglog_SoundBuffStats
+ MaxFilledSoundBuffs = 0;
+#endif
+}
+
+GLOBALOSGLUFUNC tpSoundSamp MySound_BeginWrite(ui4r n, ui4r *actL)
+{
+ ui4b ToFillLen = kAllBuffLen - (TheWriteOffset - ThePlayOffset);
+ ui4b WriteBuffContig =
+ kOneBuffLen - (TheWriteOffset & kOneBuffMask);
+
+ if (WriteBuffContig < n) {
+ n = WriteBuffContig;
+ }
+ if (ToFillLen < n) {
+ /* overwrite previous buffer */
+#if dbglog_SoundStuff
+ dbglog_writeln("sound buffer over flow");
+#endif
+ TheWriteOffset -= kOneBuffLen;
+ }
+
+ *actL = n;
+ return TheSoundBuffer + (TheWriteOffset & kAllBuffMask);
+}
+
+#if 4 == kLn2SoundSampSz
+LOCALPROC ConvertSoundBlockToNative(tpSoundSamp p)
+{
+ int i;
+
+ for (i = kOneBuffLen; --i >= 0; ) {
+ *p++ -= 0x8000;
+ }
+}
+#else
+#define ConvertSoundBlockToNative(p)
+#endif
+
+LOCALPROC MySound_WroteABlock(void)
+{
+#if (4 == kLn2SoundSampSz)
+ ui4b PrevWriteOffset = TheWriteOffset - kOneBuffLen;
+ tpSoundSamp p = TheSoundBuffer + (PrevWriteOffset & kAllBuffMask);
+#endif
+
+#if dbglog_SoundStuff
+ dbglog_writeln("enter MySound_WroteABlock");
+#endif
+
+ ConvertSoundBlockToNative(p);
+
+ TheFillOffset = TheWriteOffset;
+
+#if dbglog_SoundBuffStats
+ {
+ ui4b ToPlayLen = TheFillOffset
+ - ThePlayOffset;
+ ui4b ToPlayBuffs = ToPlayLen >> kLnOneBuffLen;
+
+ if (ToPlayBuffs > MaxFilledSoundBuffs) {
+ MaxFilledSoundBuffs = ToPlayBuffs;
+ }
+ }
+#endif
+}
+
+LOCALFUNC blnr MySound_EndWrite0(ui4r actL)
+{
+ blnr v;
+
+ TheWriteOffset += actL;
+
+ if (0 != (TheWriteOffset & kOneBuffMask)) {
+ v = falseblnr;
+ } else {
+ /* just finished a block */
+
+ MySound_WroteABlock();
+
+ v = trueblnr;
+ }
+
+ return v;
+}
+
+LOCALPROC MySound_SecondNotify0(void)
+{
+ if (MinFilledSoundBuffs <= kSoundBuffers) {
+ if (MinFilledSoundBuffs > DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too high");
+#endif
+ IncrNextTime();
+ } else if (MinFilledSoundBuffs < DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too low");
+#endif
+ ++TrueEmulatedTime;
+ }
+#if dbglog_SoundBuffStats
+ dbglog_writelnNum("MinFilledSoundBuffs",
+ MinFilledSoundBuffs);
+ dbglog_writelnNum("MaxFilledSoundBuffs",
+ MaxFilledSoundBuffs);
+ MaxFilledSoundBuffs = 0;
+#endif
+ MinFilledSoundBuffs = kSoundBuffers + 1;
+ }
+}
+
+typedef ui4r trSoundTemp;
+
+#define kCenterTempSound 0x8000
+
+#define AudioStepVal 0x0040
+
+#if 3 == kLn2SoundSampSz
+#define ConvertTempSoundSampleFromNative(v) ((v) << 8)
+#elif 4 == kLn2SoundSampSz
+#define ConvertTempSoundSampleFromNative(v) ((v) + kCenterSound)
+#else
+#error "unsupported kLn2SoundSampSz"
+#endif
+
+#if 3 == kLn2SoundSampSz
+#define ConvertTempSoundSampleToNative(v) ((v) >> 8)
+#elif 4 == kLn2SoundSampSz
+#define ConvertTempSoundSampleToNative(v) ((v) - kCenterSound)
+#else
+#error "unsupported kLn2SoundSampSz"
+#endif
+
+LOCALPROC SoundRampTo(trSoundTemp *last_val, trSoundTemp dst_val,
+ tpSoundSamp *stream, int *len)
+{
+ trSoundTemp diff;
+ tpSoundSamp p = *stream;
+ int n = *len;
+ trSoundTemp v1 = *last_val;
+
+ while ((v1 != dst_val) && (0 != n)) {
+ if (v1 > dst_val) {
+ diff = v1 - dst_val;
+ if (diff > AudioStepVal) {
+ v1 -= AudioStepVal;
+ } else {
+ v1 = dst_val;
+ }
+ } else {
+ diff = dst_val - v1;
+ if (diff > AudioStepVal) {
+ v1 += AudioStepVal;
+ } else {
+ v1 = dst_val;
+ }
+ }
+
+ --n;
+ *p++ = ConvertTempSoundSampleToNative(v1);
+ }
+
+ *stream = p;
+ *len = n;
+ *last_val = v1;
+}
+
+struct MySoundR {
+ tpSoundSamp fTheSoundBuffer;
+ volatile ui4b (*fPlayOffset);
+ volatile ui4b (*fFillOffset);
+ volatile ui4b (*fMinFilledSoundBuffs);
+
+ volatile trSoundTemp lastv;
+
+ blnr wantplaying;
+ blnr HaveStartedPlaying;
+};
+typedef struct MySoundR MySoundR;
+
+static void my_audio_callback(void *udata, Uint8 *stream, int len)
+{
+ ui4b ToPlayLen;
+ ui4b FilledSoundBuffs;
+ int i;
+ MySoundR *datp = (MySoundR *)udata;
+ tpSoundSamp CurSoundBuffer = datp->fTheSoundBuffer;
+ ui4b CurPlayOffset = *datp->fPlayOffset;
+ trSoundTemp v0 = datp->lastv;
+ trSoundTemp v1 = v0;
+ tpSoundSamp dst = (tpSoundSamp)stream;
+
+#if kLn2SoundSampSz > 3
+ len >>= (kLn2SoundSampSz - 3);
+#endif
+
+#if dbglog_SoundStuff
+ dbglog_writeln("Enter my_audio_callback");
+ dbglog_writelnNum("len", len);
+#endif
+
+label_retry:
+ ToPlayLen = *datp->fFillOffset - CurPlayOffset;
+ FilledSoundBuffs = ToPlayLen >> kLnOneBuffLen;
+
+ if (! datp->wantplaying) {
+#if dbglog_SoundStuff
+ dbglog_writeln("playing end transistion");
+#endif
+
+ SoundRampTo(&v1, kCenterTempSound, &dst, &len);
+
+ ToPlayLen = 0;
+ } else if (! datp->HaveStartedPlaying) {
+#if dbglog_SoundStuff
+ dbglog_writeln("playing start block");
+#endif
+
+ if ((ToPlayLen >> kLnOneBuffLen) < 8) {
+ ToPlayLen = 0;
+ } else {
+ tpSoundSamp p = datp->fTheSoundBuffer
+ + (CurPlayOffset & kAllBuffMask);
+ trSoundTemp v2 = ConvertTempSoundSampleFromNative(*p);
+
+#if dbglog_SoundStuff
+ dbglog_writeln("have enough samples to start");
+#endif
+
+ SoundRampTo(&v1, v2, &dst, &len);
+
+ if (v1 == v2) {
+#if dbglog_SoundStuff
+ dbglog_writeln("finished start transition");
+#endif
+
+ datp->HaveStartedPlaying = trueblnr;
+ }
+ }
+ }
+
+ if (0 == len) {
+ /* done */
+
+ if (FilledSoundBuffs < *datp->fMinFilledSoundBuffs) {
+ *datp->fMinFilledSoundBuffs = FilledSoundBuffs;
+ }
+ } else if (0 == ToPlayLen) {
+
+#if dbglog_SoundStuff
+ dbglog_writeln("under run");
+#endif
+
+ for (i = 0; i < len; ++i) {
+ *dst++ = ConvertTempSoundSampleToNative(v1);
+ }
+ *datp->fMinFilledSoundBuffs = 0;
+ } else {
+ ui4b PlayBuffContig = kAllBuffLen
+ - (CurPlayOffset & kAllBuffMask);
+ tpSoundSamp p = CurSoundBuffer
+ + (CurPlayOffset & kAllBuffMask);
+
+ if (ToPlayLen > PlayBuffContig) {
+ ToPlayLen = PlayBuffContig;
+ }
+ if (ToPlayLen > len) {
+ ToPlayLen = len;
+ }
+
+ for (i = 0; i < ToPlayLen; ++i) {
+ *dst++ = *p++;
+ }
+ v1 = ConvertTempSoundSampleFromNative(p[-1]);
+
+ CurPlayOffset += ToPlayLen;
+ len -= ToPlayLen;
+
+ *datp->fPlayOffset = CurPlayOffset;
+
+ goto label_retry;
+ }
+
+ datp->lastv = v1;
+}
+
+LOCALVAR MySoundR cur_audio;
+
+LOCALVAR blnr HaveSoundOut = falseblnr;
+
+LOCALPROC MySound_Stop(void)
+{
+#if dbglog_SoundStuff
+ dbglog_writeln("enter MySound_Stop");
+#endif
+
+ if (cur_audio.wantplaying && HaveSoundOut) {
+ ui4r retry_limit = 50; /* half of a second */
+
+ cur_audio.wantplaying = falseblnr;
+
+label_retry:
+ if (kCenterTempSound == cur_audio.lastv) {
+#if dbglog_SoundStuff
+ dbglog_writeln("reached kCenterTempSound");
+#endif
+
+ /* done */
+ } else if (0 == --retry_limit) {
+#if dbglog_SoundStuff
+ dbglog_writeln("retry limit reached");
+#endif
+ /* done */
+ } else
+ {
+ /*
+ give time back, particularly important
+ if got here on a suspend event.
+ */
+
+#if dbglog_SoundStuff
+ dbglog_writeln("busy, so sleep");
+#endif
+
+ (void) SDL_Delay(10);
+
+ goto label_retry;
+ }
+
+ SDL_PauseAudio(1);
+ }
+
+#if dbglog_SoundStuff
+ dbglog_writeln("leave MySound_Stop");
+#endif
+}
+
+LOCALPROC MySound_Start(void)
+{
+ if ((! cur_audio.wantplaying) && HaveSoundOut) {
+ MySound_Start0();
+ cur_audio.lastv = kCenterTempSound;
+ cur_audio.HaveStartedPlaying = falseblnr;
+ cur_audio.wantplaying = trueblnr;
+
+ SDL_PauseAudio(0);
+ }
+}
+
+LOCALPROC MySound_UnInit(void)
+{
+ if (HaveSoundOut) {
+ SDL_CloseAudio();
+ }
+}
+
+#define SOUND_SAMPLERATE 22255 /* = round(7833600 * 2 / 704) */
+
+LOCALFUNC blnr MySound_Init(void)
+{
+ SDL_AudioSpec desired;
+
+ MySound_Init0();
+
+ cur_audio.fTheSoundBuffer = TheSoundBuffer;
+ cur_audio.fPlayOffset = &ThePlayOffset;
+ cur_audio.fFillOffset = &TheFillOffset;
+ cur_audio.fMinFilledSoundBuffs = &MinFilledSoundBuffs;
+ cur_audio.wantplaying = falseblnr;
+
+ desired.freq = SOUND_SAMPLERATE;
+
+#if 3 == kLn2SoundSampSz
+ desired.format = AUDIO_U8;
+#elif 4 == kLn2SoundSampSz
+ desired.format = AUDIO_S16SYS;
+#else
+#error "unsupported audio format"
+#endif
+
+ desired.channels = 1;
+ desired.samples = 1024;
+ desired.callback = my_audio_callback;
+ desired.userdata = (void *)&cur_audio;
+
+ /* Open the audio device */
+ if (SDL_OpenAudio(&desired, NULL) < 0) {
+ fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
+ } else {
+ HaveSoundOut = trueblnr;
+
+ MySound_Start();
+ /*
+ This should be taken care of by LeaveSpeedStopped,
+ but since takes a while to get going properly,
+ start early.
+ */
+ }
+
+ return trueblnr; /* keep going, even if no sound */
+}
+
+GLOBALOSGLUPROC MySound_EndWrite(ui4r actL)
+{
+ if (MySound_EndWrite0(actL)) {
+ }
+}
+
+LOCALPROC MySound_SecondNotify(void)
+{
+ if (HaveSoundOut) {
+ MySound_SecondNotify0();
+ }
+}
+
+#endif
+
+/* --- basic dialogs --- */
+
+LOCALPROC CheckSavedMacMsg(void)
+{
+ /* called only on quit, if error saved but not yet reported */
+
+ if (nullpr != SavedBriefMsg) {
+ char briefMsg0[ClStrMaxLength + 1];
+ char longMsg0[ClStrMaxLength + 1];
+
+ NativeStrFromCStr(briefMsg0, SavedBriefMsg);
+ NativeStrFromCStr(longMsg0, SavedLongMsg);
+
+ if (0 != SDL_ShowSimpleMessageBox(
+ SDL_MESSAGEBOX_ERROR,
+ SavedBriefMsg,
+ SavedLongMsg,
+ my_main_wind
+ ))
+ {
+ fprintf(stderr, "%s\n", briefMsg0);
+ fprintf(stderr, "%s\n", longMsg0);
+ }
+
+ SavedBriefMsg = nullpr;
+ }
+}
+
+/* --- clipboard --- */
+
+#if IncludeHostTextClipExchange
+LOCALFUNC uimr MacRoman2UniCodeSize(ui3b *s, uimr L)
+{
+ uimr i;
+ ui3r x;
+ uimr n;
+ uimr v = 0;
+
+ for (i = 0; i < L; ++i) {
+ x = *s++;
+ if (x < 128) {
+ n = 1;
+ } else {
+ switch (x) {
+ case 0x80: n = 2; break;
+ /* LATIN CAPITAL LETTER A WITH DIAERESIS */
+ case 0x81: n = 2; break;
+ /* LATIN CAPITAL LETTER A WITH RING ABOVE */
+ case 0x82: n = 2; break;
+ /* LATIN CAPITAL LETTER C WITH CEDILLA */
+ case 0x83: n = 2; break;
+ /* LATIN CAPITAL LETTER E WITH ACUTE */
+ case 0x84: n = 2; break;
+ /* LATIN CAPITAL LETTER N WITH TILDE */
+ case 0x85: n = 2; break;
+ /* LATIN CAPITAL LETTER O WITH DIAERESIS */
+ case 0x86: n = 2; break;
+ /* LATIN CAPITAL LETTER U WITH DIAERESIS */
+ case 0x87: n = 2; break;
+ /* LATIN SMALL LETTER A WITH ACUTE */
+ case 0x88: n = 2; break;
+ /* LATIN SMALL LETTER A WITH GRAVE */
+ case 0x89: n = 2; break;
+ /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
+ case 0x8A: n = 2; break;
+ /* LATIN SMALL LETTER A WITH DIAERESIS */
+ case 0x8B: n = 2; break;
+ /* LATIN SMALL LETTER A WITH TILDE */
+ case 0x8C: n = 2; break;
+ /* LATIN SMALL LETTER A WITH RING ABOVE */
+ case 0x8D: n = 2; break;
+ /* LATIN SMALL LETTER C WITH CEDILLA */
+ case 0x8E: n = 2; break;
+ /* LATIN SMALL LETTER E WITH ACUTE */
+ case 0x8F: n = 2; break;
+ /* LATIN SMALL LETTER E WITH GRAVE */
+ case 0x90: n = 2; break;
+ /* LATIN SMALL LETTER E WITH CIRCUMFLEX */
+ case 0x91: n = 2; break;
+ /* LATIN SMALL LETTER E WITH DIAERESIS */
+ case 0x92: n = 2; break;
+ /* LATIN SMALL LETTER I WITH ACUTE */
+ case 0x93: n = 2; break;
+ /* LATIN SMALL LETTER I WITH GRAVE */
+ case 0x94: n = 2; break;
+ /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
+ case 0x95: n = 2; break;
+ /* LATIN SMALL LETTER I WITH DIAERESIS */
+ case 0x96: n = 2; break;
+ /* LATIN SMALL LETTER N WITH TILDE */
+ case 0x97: n = 2; break;
+ /* LATIN SMALL LETTER O WITH ACUTE */
+ case 0x98: n = 2; break;
+ /* LATIN SMALL LETTER O WITH GRAVE */
+ case 0x99: n = 2; break;
+ /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
+ case 0x9A: n = 2; break;
+ /* LATIN SMALL LETTER O WITH DIAERESIS */
+ case 0x9B: n = 2; break;
+ /* LATIN SMALL LETTER O WITH TILDE */
+ case 0x9C: n = 2; break;
+ /* LATIN SMALL LETTER U WITH ACUTE */
+ case 0x9D: n = 2; break;
+ /* LATIN SMALL LETTER U WITH GRAVE */
+ case 0x9E: n = 2; break;
+ /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
+ case 0x9F: n = 2; break;
+ /* LATIN SMALL LETTER U WITH DIAERESIS */
+ case 0xA0: n = 3; break;
+ /* DAGGER */
+ case 0xA1: n = 2; break;
+ /* DEGREE SIGN */
+ case 0xA2: n = 2; break;
+ /* CENT SIGN */
+ case 0xA3: n = 2; break;
+ /* POUND SIGN */
+ case 0xA4: n = 2; break;
+ /* SECTION SIGN */
+ case 0xA5: n = 3; break;
+ /* BULLET */
+ case 0xA6: n = 2; break;
+ /* PILCROW SIGN */
+ case 0xA7: n = 2; break;
+ /* LATIN SMALL LETTER SHARP S */
+ case 0xA8: n = 2; break;
+ /* REGISTERED SIGN */
+ case 0xA9: n = 2; break;
+ /* COPYRIGHT SIGN */
+ case 0xAA: n = 3; break;
+ /* TRADE MARK SIGN */
+ case 0xAB: n = 2; break;
+ /* ACUTE ACCENT */
+ case 0xAC: n = 2; break;
+ /* DIAERESIS */
+ case 0xAD: n = 3; break;
+ /* NOT EQUAL TO */
+ case 0xAE: n = 2; break;
+ /* LATIN CAPITAL LETTER AE */
+ case 0xAF: n = 2; break;
+ /* LATIN CAPITAL LETTER O WITH STROKE */
+ case 0xB0: n = 3; break;
+ /* INFINITY */
+ case 0xB1: n = 2; break;
+ /* PLUS-MINUS SIGN */
+ case 0xB2: n = 3; break;
+ /* LESS-THAN OR EQUAL TO */
+ case 0xB3: n = 3; break;
+ /* GREATER-THAN OR EQUAL TO */
+ case 0xB4: n = 2; break;
+ /* YEN SIGN */
+ case 0xB5: n = 2; break;
+ /* MICRO SIGN */
+ case 0xB6: n = 3; break;
+ /* PARTIAL DIFFERENTIAL */
+ case 0xB7: n = 3; break;
+ /* N-ARY SUMMATION */
+ case 0xB8: n = 3; break;
+ /* N-ARY PRODUCT */
+ case 0xB9: n = 2; break;
+ /* GREEK SMALL LETTER PI */
+ case 0xBA: n = 3; break;
+ /* INTEGRAL */
+ case 0xBB: n = 2; break;
+ /* FEMININE ORDINAL INDICATOR */
+ case 0xBC: n = 2; break;
+ /* MASCULINE ORDINAL INDICATOR */
+ case 0xBD: n = 2; break;
+ /* GREEK CAPITAL LETTER OMEGA */
+ case 0xBE: n = 2; break;
+ /* LATIN SMALL LETTER AE */
+ case 0xBF: n = 2; break;
+ /* LATIN SMALL LETTER O WITH STROKE */
+ case 0xC0: n = 2; break;
+ /* INVERTED QUESTION MARK */
+ case 0xC1: n = 2; break;
+ /* INVERTED EXCLAMATION MARK */
+ case 0xC2: n = 2; break;
+ /* NOT SIGN */
+ case 0xC3: n = 3; break;
+ /* SQUARE ROOT */
+ case 0xC4: n = 2; break;
+ /* LATIN SMALL LETTER F WITH HOOK */
+ case 0xC5: n = 3; break;
+ /* ALMOST EQUAL TO */
+ case 0xC6: n = 3; break;
+ /* INCREMENT */
+ case 0xC7: n = 2; break;
+ /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
+ case 0xC8: n = 2; break;
+ /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
+ case 0xC9: n = 3; break;
+ /* HORIZONTAL ELLIPSIS */
+ case 0xCA: n = 2; break;
+ /* NO-BREAK SPACE */
+ case 0xCB: n = 2; break;
+ /* LATIN CAPITAL LETTER A WITH GRAVE */
+ case 0xCC: n = 2; break;
+ /* LATIN CAPITAL LETTER A WITH TILDE */
+ case 0xCD: n = 2; break;
+ /* LATIN CAPITAL LETTER O WITH TILDE */
+ case 0xCE: n = 2; break;
+ /* LATIN CAPITAL LIGATURE OE */
+ case 0xCF: n = 2; break;
+ /* LATIN SMALL LIGATURE OE */
+ case 0xD0: n = 3; break;
+ /* EN DASH */
+ case 0xD1: n = 3; break;
+ /* EM DASH */
+ case 0xD2: n = 3; break;
+ /* LEFT DOUBLE QUOTATION MARK */
+ case 0xD3: n = 3; break;
+ /* RIGHT DOUBLE QUOTATION MARK */
+ case 0xD4: n = 3; break;
+ /* LEFT SINGLE QUOTATION MARK */
+ case 0xD5: n = 3; break;
+ /* RIGHT SINGLE QUOTATION MARK */
+ case 0xD6: n = 2; break;
+ /* DIVISION SIGN */
+ case 0xD7: n = 3; break;
+ /* LOZENGE */
+ case 0xD8: n = 2; break;
+ /* LATIN SMALL LETTER Y WITH DIAERESIS */
+ case 0xD9: n = 2; break;
+ /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
+ case 0xDA: n = 3; break;
+ /* FRACTION SLASH */
+ case 0xDB: n = 3; break;
+ /* EURO SIGN */
+ case 0xDC: n = 3; break;
+ /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */
+ case 0xDD: n = 3; break;
+ /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */
+ case 0xDE: n = 3; break;
+ /* LATIN SMALL LIGATURE FI */
+ case 0xDF: n = 3; break;
+ /* LATIN SMALL LIGATURE FL */
+ case 0xE0: n = 3; break;
+ /* DOUBLE DAGGER */
+ case 0xE1: n = 2; break;
+ /* MIDDLE DOT */
+ case 0xE2: n = 3; break;
+ /* SINGLE LOW-9 QUOTATION MARK */
+ case 0xE3: n = 3; break;
+ /* DOUBLE LOW-9 QUOTATION MARK */
+ case 0xE4: n = 3; break;
+ /* PER MILLE SIGN */
+ case 0xE5: n = 2; break;
+ /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
+ case 0xE6: n = 2; break;
+ /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
+ case 0xE7: n = 2; break;
+ /* LATIN CAPITAL LETTER A WITH ACUTE */
+ case 0xE8: n = 2; break;
+ /* LATIN CAPITAL LETTER E WITH DIAERESIS */
+ case 0xE9: n = 2; break;
+ /* LATIN CAPITAL LETTER E WITH GRAVE */
+ case 0xEA: n = 2; break;
+ /* LATIN CAPITAL LETTER I WITH ACUTE */
+ case 0xEB: n = 2; break;
+ /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
+ case 0xEC: n = 2; break;
+ /* LATIN CAPITAL LETTER I WITH DIAERESIS */
+ case 0xED: n = 2; break;
+ /* LATIN CAPITAL LETTER I WITH GRAVE */
+ case 0xEE: n = 2; break;
+ /* LATIN CAPITAL LETTER O WITH ACUTE */
+ case 0xEF: n = 2; break;
+ /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
+ case 0xF0: n = 3; break;
+ /* Apple logo */
+ case 0xF1: n = 2; break;
+ /* LATIN CAPITAL LETTER O WITH GRAVE */
+ case 0xF2: n = 2; break;
+ /* LATIN CAPITAL LETTER U WITH ACUTE */
+ case 0xF3: n = 2; break;
+ /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
+ case 0xF4: n = 2; break;
+ /* LATIN CAPITAL LETTER U WITH GRAVE */
+ case 0xF5: n = 2; break;
+ /* LATIN SMALL LETTER DOTLESS I */
+ case 0xF6: n = 2; break;
+ /* MODIFIER LETTER CIRCUMFLEX ACCENT */
+ case 0xF7: n = 2; break;
+ /* SMALL TILDE */
+ case 0xF8: n = 2; break;
+ /* MACRON */
+ case 0xF9: n = 2; break;
+ /* BREVE */
+ case 0xFA: n = 2; break;
+ /* DOT ABOVE */
+ case 0xFB: n = 2; break;
+ /* RING ABOVE */
+ case 0xFC: n = 2; break;
+ /* CEDILLA */
+ case 0xFD: n = 2; break;
+ /* DOUBLE ACUTE ACCENT */
+ case 0xFE: n = 2; break;
+ /* OGONEK */
+ case 0xFF: n = 2; break;
+ /* CARON */
+ default: n = 1; break;
+ /* shouldn't get here */
+ }
+ }
+ v += n;
+ }
+
+ return v;
+}
+#endif
+
+#if IncludeHostTextClipExchange
+LOCALPROC MacRoman2UniCodeData(ui3b *s, uimr L, char *t)
+{
+ uimr i;
+ ui3r x;
+
+ for (i = 0; i < L; ++i) {
+ x = *s++;
+ if (x < 128) {
+ *t++ = x;
+ } else {
+ switch (x) {
+ case 0x80: *t++ = 0xC3; *t++ = 0x84; break;
+ /* LATIN CAPITAL LETTER A WITH DIAERESIS */
+ case 0x81: *t++ = 0xC3; *t++ = 0x85; break;
+ /* LATIN CAPITAL LETTER A WITH RING ABOVE */
+ case 0x82: *t++ = 0xC3; *t++ = 0x87; break;
+ /* LATIN CAPITAL LETTER C WITH CEDILLA */
+ case 0x83: *t++ = 0xC3; *t++ = 0x89; break;
+ /* LATIN CAPITAL LETTER E WITH ACUTE */
+ case 0x84: *t++ = 0xC3; *t++ = 0x91; break;
+ /* LATIN CAPITAL LETTER N WITH TILDE */
+ case 0x85: *t++ = 0xC3; *t++ = 0x96; break;
+ /* LATIN CAPITAL LETTER O WITH DIAERESIS */
+ case 0x86: *t++ = 0xC3; *t++ = 0x9C; break;
+ /* LATIN CAPITAL LETTER U WITH DIAERESIS */
+ case 0x87: *t++ = 0xC3; *t++ = 0xA1; break;
+ /* LATIN SMALL LETTER A WITH ACUTE */
+ case 0x88: *t++ = 0xC3; *t++ = 0xA0; break;
+ /* LATIN SMALL LETTER A WITH GRAVE */
+ case 0x89: *t++ = 0xC3; *t++ = 0xA2; break;
+ /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
+ case 0x8A: *t++ = 0xC3; *t++ = 0xA4; break;
+ /* LATIN SMALL LETTER A WITH DIAERESIS */
+ case 0x8B: *t++ = 0xC3; *t++ = 0xA3; break;
+ /* LATIN SMALL LETTER A WITH TILDE */
+ case 0x8C: *t++ = 0xC3; *t++ = 0xA5; break;
+ /* LATIN SMALL LETTER A WITH RING ABOVE */
+ case 0x8D: *t++ = 0xC3; *t++ = 0xA7; break;
+ /* LATIN SMALL LETTER C WITH CEDILLA */
+ case 0x8E: *t++ = 0xC3; *t++ = 0xA9; break;
+ /* LATIN SMALL LETTER E WITH ACUTE */
+ case 0x8F: *t++ = 0xC3; *t++ = 0xA8; break;
+ /* LATIN SMALL LETTER E WITH GRAVE */
+ case 0x90: *t++ = 0xC3; *t++ = 0xAA; break;
+ /* LATIN SMALL LETTER E WITH CIRCUMFLEX */
+ case 0x91: *t++ = 0xC3; *t++ = 0xAB; break;
+ /* LATIN SMALL LETTER E WITH DIAERESIS */
+ case 0x92: *t++ = 0xC3; *t++ = 0xAD; break;
+ /* LATIN SMALL LETTER I WITH ACUTE */
+ case 0x93: *t++ = 0xC3; *t++ = 0xAC; break;
+ /* LATIN SMALL LETTER I WITH GRAVE */
+ case 0x94: *t++ = 0xC3; *t++ = 0xAE; break;
+ /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
+ case 0x95: *t++ = 0xC3; *t++ = 0xAF; break;
+ /* LATIN SMALL LETTER I WITH DIAERESIS */
+ case 0x96: *t++ = 0xC3; *t++ = 0xB1; break;
+ /* LATIN SMALL LETTER N WITH TILDE */
+ case 0x97: *t++ = 0xC3; *t++ = 0xB3; break;
+ /* LATIN SMALL LETTER O WITH ACUTE */
+ case 0x98: *t++ = 0xC3; *t++ = 0xB2; break;
+ /* LATIN SMALL LETTER O WITH GRAVE */
+ case 0x99: *t++ = 0xC3; *t++ = 0xB4; break;
+ /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
+ case 0x9A: *t++ = 0xC3; *t++ = 0xB6; break;
+ /* LATIN SMALL LETTER O WITH DIAERESIS */
+ case 0x9B: *t++ = 0xC3; *t++ = 0xB5; break;
+ /* LATIN SMALL LETTER O WITH TILDE */
+ case 0x9C: *t++ = 0xC3; *t++ = 0xBA; break;
+ /* LATIN SMALL LETTER U WITH ACUTE */
+ case 0x9D: *t++ = 0xC3; *t++ = 0xB9; break;
+ /* LATIN SMALL LETTER U WITH GRAVE */
+ case 0x9E: *t++ = 0xC3; *t++ = 0xBB; break;
+ /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
+ case 0x9F: *t++ = 0xC3; *t++ = 0xBC; break;
+ /* LATIN SMALL LETTER U WITH DIAERESIS */
+ case 0xA0: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xA0; break;
+ /* DAGGER */
+ case 0xA1: *t++ = 0xC2; *t++ = 0xB0; break;
+ /* DEGREE SIGN */
+ case 0xA2: *t++ = 0xC2; *t++ = 0xA2; break;
+ /* CENT SIGN */
+ case 0xA3: *t++ = 0xC2; *t++ = 0xA3; break;
+ /* POUND SIGN */
+ case 0xA4: *t++ = 0xC2; *t++ = 0xA7; break;
+ /* SECTION SIGN */
+ case 0xA5: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xA2; break;
+ /* BULLET */
+ case 0xA6: *t++ = 0xC2; *t++ = 0xB6; break;
+ /* PILCROW SIGN */
+ case 0xA7: *t++ = 0xC3; *t++ = 0x9F; break;
+ /* LATIN SMALL LETTER SHARP S */
+ case 0xA8: *t++ = 0xC2; *t++ = 0xAE; break;
+ /* REGISTERED SIGN */
+ case 0xA9: *t++ = 0xC2; *t++ = 0xA9; break;
+ /* COPYRIGHT SIGN */
+ case 0xAA: *t++ = 0xE2; *t++ = 0x84; *t++ = 0xA2; break;
+ /* TRADE MARK SIGN */
+ case 0xAB: *t++ = 0xC2; *t++ = 0xB4; break;
+ /* ACUTE ACCENT */
+ case 0xAC: *t++ = 0xC2; *t++ = 0xA8; break;
+ /* DIAERESIS */
+ case 0xAD: *t++ = 0xE2; *t++ = 0x89; *t++ = 0xA0; break;
+ /* NOT EQUAL TO */
+ case 0xAE: *t++ = 0xC3; *t++ = 0x86; break;
+ /* LATIN CAPITAL LETTER AE */
+ case 0xAF: *t++ = 0xC3; *t++ = 0x98; break;
+ /* LATIN CAPITAL LETTER O WITH STROKE */
+ case 0xB0: *t++ = 0xE2; *t++ = 0x88; *t++ = 0x9E; break;
+ /* INFINITY */
+ case 0xB1: *t++ = 0xC2; *t++ = 0xB1; break;
+ /* PLUS-MINUS SIGN */
+ case 0xB2: *t++ = 0xE2; *t++ = 0x89; *t++ = 0xA4; break;
+ /* LESS-THAN OR EQUAL TO */
+ case 0xB3: *t++ = 0xE2; *t++ = 0x89; *t++ = 0xA5; break;
+ /* GREATER-THAN OR EQUAL TO */
+ case 0xB4: *t++ = 0xC2; *t++ = 0xA5; break;
+ /* YEN SIGN */
+ case 0xB5: *t++ = 0xC2; *t++ = 0xB5; break;
+ /* MICRO SIGN */
+ case 0xB6: *t++ = 0xE2; *t++ = 0x88; *t++ = 0x82; break;
+ /* PARTIAL DIFFERENTIAL */
+ case 0xB7: *t++ = 0xE2; *t++ = 0x88; *t++ = 0x91; break;
+ /* N-ARY SUMMATION */
+ case 0xB8: *t++ = 0xE2; *t++ = 0x88; *t++ = 0x8F; break;
+ /* N-ARY PRODUCT */
+ case 0xB9: *t++ = 0xCF; *t++ = 0x80; break;
+ /* GREEK SMALL LETTER PI */
+ case 0xBA: *t++ = 0xE2; *t++ = 0x88; *t++ = 0xAB; break;
+ /* INTEGRAL */
+ case 0xBB: *t++ = 0xC2; *t++ = 0xAA; break;
+ /* FEMININE ORDINAL INDICATOR */
+ case 0xBC: *t++ = 0xC2; *t++ = 0xBA; break;
+ /* MASCULINE ORDINAL INDICATOR */
+ case 0xBD: *t++ = 0xCE; *t++ = 0xA9; break;
+ /* GREEK CAPITAL LETTER OMEGA */
+ case 0xBE: *t++ = 0xC3; *t++ = 0xA6; break;
+ /* LATIN SMALL LETTER AE */
+ case 0xBF: *t++ = 0xC3; *t++ = 0xB8; break;
+ /* LATIN SMALL LETTER O WITH STROKE */
+ case 0xC0: *t++ = 0xC2; *t++ = 0xBF; break;
+ /* INVERTED QUESTION MARK */
+ case 0xC1: *t++ = 0xC2; *t++ = 0xA1; break;
+ /* INVERTED EXCLAMATION MARK */
+ case 0xC2: *t++ = 0xC2; *t++ = 0xAC; break;
+ /* NOT SIGN */
+ case 0xC3: *t++ = 0xE2; *t++ = 0x88; *t++ = 0x9A; break;
+ /* SQUARE ROOT */
+ case 0xC4: *t++ = 0xC6; *t++ = 0x92; break;
+ /* LATIN SMALL LETTER F WITH HOOK */
+ case 0xC5: *t++ = 0xE2; *t++ = 0x89; *t++ = 0x88; break;
+ /* ALMOST EQUAL TO */
+ case 0xC6: *t++ = 0xE2; *t++ = 0x88; *t++ = 0x86; break;
+ /* INCREMENT */
+ case 0xC7: *t++ = 0xC2; *t++ = 0xAB; break;
+ /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
+ case 0xC8: *t++ = 0xC2; *t++ = 0xBB; break;
+ /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
+ case 0xC9: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xA6; break;
+ /* HORIZONTAL ELLIPSIS */
+ case 0xCA: *t++ = 0xC2; *t++ = 0xA0; break;
+ /* NO-BREAK SPACE */
+ case 0xCB: *t++ = 0xC3; *t++ = 0x80; break;
+ /* LATIN CAPITAL LETTER A WITH GRAVE */
+ case 0xCC: *t++ = 0xC3; *t++ = 0x83; break;
+ /* LATIN CAPITAL LETTER A WITH TILDE */
+ case 0xCD: *t++ = 0xC3; *t++ = 0x95; break;
+ /* LATIN CAPITAL LETTER O WITH TILDE */
+ case 0xCE: *t++ = 0xC5; *t++ = 0x92; break;
+ /* LATIN CAPITAL LIGATURE OE */
+ case 0xCF: *t++ = 0xC5; *t++ = 0x93; break;
+ /* LATIN SMALL LIGATURE OE */
+ case 0xD0: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x93; break;
+ /* EN DASH */
+ case 0xD1: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x94; break;
+ /* EM DASH */
+ case 0xD2: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x9C; break;
+ /* LEFT DOUBLE QUOTATION MARK */
+ case 0xD3: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x9D; break;
+ /* RIGHT DOUBLE QUOTATION MARK */
+ case 0xD4: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x98; break;
+ /* LEFT SINGLE QUOTATION MARK */
+ case 0xD5: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x99; break;
+ /* RIGHT SINGLE QUOTATION MARK */
+ case 0xD6: *t++ = 0xC3; *t++ = 0xB7; break;
+ /* DIVISION SIGN */
+ case 0xD7: *t++ = 0xE2; *t++ = 0x97; *t++ = 0x8A; break;
+ /* LOZENGE */
+ case 0xD8: *t++ = 0xC3; *t++ = 0xBF; break;
+ /* LATIN SMALL LETTER Y WITH DIAERESIS */
+ case 0xD9: *t++ = 0xC5; *t++ = 0xB8; break;
+ /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
+ case 0xDA: *t++ = 0xE2; *t++ = 0x81; *t++ = 0x84; break;
+ /* FRACTION SLASH */
+ case 0xDB: *t++ = 0xE2; *t++ = 0x82; *t++ = 0xAC; break;
+ /* EURO SIGN */
+ case 0xDC: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xB9; break;
+ /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */
+ case 0xDD: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xBA; break;
+ /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */
+ case 0xDE: *t++ = 0xEF; *t++ = 0xAC; *t++ = 0x81; break;
+ /* LATIN SMALL LIGATURE FI */
+ case 0xDF: *t++ = 0xEF; *t++ = 0xAC; *t++ = 0x82; break;
+ /* LATIN SMALL LIGATURE FL */
+ case 0xE0: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xA1; break;
+ /* DOUBLE DAGGER */
+ case 0xE1: *t++ = 0xC2; *t++ = 0xB7; break;
+ /* MIDDLE DOT */
+ case 0xE2: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x9A; break;
+ /* SINGLE LOW-9 QUOTATION MARK */
+ case 0xE3: *t++ = 0xE2; *t++ = 0x80; *t++ = 0x9E; break;
+ /* DOUBLE LOW-9 QUOTATION MARK */
+ case 0xE4: *t++ = 0xE2; *t++ = 0x80; *t++ = 0xB0; break;
+ /* PER MILLE SIGN */
+ case 0xE5: *t++ = 0xC3; *t++ = 0x82; break;
+ /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
+ case 0xE6: *t++ = 0xC3; *t++ = 0x8A; break;
+ /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
+ case 0xE7: *t++ = 0xC3; *t++ = 0x81; break;
+ /* LATIN CAPITAL LETTER A WITH ACUTE */
+ case 0xE8: *t++ = 0xC3; *t++ = 0x8B; break;
+ /* LATIN CAPITAL LETTER E WITH DIAERESIS */
+ case 0xE9: *t++ = 0xC3; *t++ = 0x88; break;
+ /* LATIN CAPITAL LETTER E WITH GRAVE */
+ case 0xEA: *t++ = 0xC3; *t++ = 0x8D; break;
+ /* LATIN CAPITAL LETTER I WITH ACUTE */
+ case 0xEB: *t++ = 0xC3; *t++ = 0x8E; break;
+ /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
+ case 0xEC: *t++ = 0xC3; *t++ = 0x8F; break;
+ /* LATIN CAPITAL LETTER I WITH DIAERESIS */
+ case 0xED: *t++ = 0xC3; *t++ = 0x8C; break;
+ /* LATIN CAPITAL LETTER I WITH GRAVE */
+ case 0xEE: *t++ = 0xC3; *t++ = 0x93; break;
+ /* LATIN CAPITAL LETTER O WITH ACUTE */
+ case 0xEF: *t++ = 0xC3; *t++ = 0x94; break;
+ /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
+ case 0xF0: *t++ = 0xEF; *t++ = 0xA3; *t++ = 0xBF; break;
+ /* Apple logo */
+ case 0xF1: *t++ = 0xC3; *t++ = 0x92; break;
+ /* LATIN CAPITAL LETTER O WITH GRAVE */
+ case 0xF2: *t++ = 0xC3; *t++ = 0x9A; break;
+ /* LATIN CAPITAL LETTER U WITH ACUTE */
+ case 0xF3: *t++ = 0xC3; *t++ = 0x9B; break;
+ /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
+ case 0xF4: *t++ = 0xC3; *t++ = 0x99; break;
+ /* LATIN CAPITAL LETTER U WITH GRAVE */
+ case 0xF5: *t++ = 0xC4; *t++ = 0xB1; break;
+ /* LATIN SMALL LETTER DOTLESS I */
+ case 0xF6: *t++ = 0xCB; *t++ = 0x86; break;
+ /* MODIFIER LETTER CIRCUMFLEX ACCENT */
+ case 0xF7: *t++ = 0xCB; *t++ = 0x9C; break;
+ /* SMALL TILDE */
+ case 0xF8: *t++ = 0xC2; *t++ = 0xAF; break;
+ /* MACRON */
+ case 0xF9: *t++ = 0xCB; *t++ = 0x98; break;
+ /* BREVE */
+ case 0xFA: *t++ = 0xCB; *t++ = 0x99; break;
+ /* DOT ABOVE */
+ case 0xFB: *t++ = 0xCB; *t++ = 0x9A; break;
+ /* RING ABOVE */
+ case 0xFC: *t++ = 0xC2; *t++ = 0xB8; break;
+ /* CEDILLA */
+ case 0xFD: *t++ = 0xCB; *t++ = 0x9D; break;
+ /* DOUBLE ACUTE ACCENT */
+ case 0xFE: *t++ = 0xCB; *t++ = 0x9B; break;
+ /* OGONEK */
+ case 0xFF: *t++ = 0xCB; *t++ = 0x87; break;
+ /* CARON */
+ default: *t++ = '?'; break;
+ /* shouldn't get here */
+ }
+ }
+ }
+}
+#endif
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEexport(tPbuf i)
+{
+ tMacErr err;
+ char *p;
+ ui3p s = PbufDat[i];
+ uimr L = PbufSize[i];
+ uimr sz = MacRoman2UniCodeSize(s, L);
+
+ if (NULL == (p = malloc(sz + 1))) {
+ err = mnvm_miscErr;
+ } else {
+ MacRoman2UniCodeData(s, L, p);
+ p[sz] = 0;
+
+ if (0 != SDL_SetClipboardText(p)) {
+ err = mnvm_miscErr;
+ } else {
+ err = mnvm_noErr;
+ }
+ free(p);
+ }
+
+ return err;
+}
+#endif
+
+#if IncludeHostTextClipExchange
+LOCALFUNC tMacErr UniCodeStrLength(char *s, uimr *r)
+{
+ tMacErr err;
+ ui3r t;
+ ui3r t2;
+ char *p = s;
+ uimr L = 0;
+
+label_retry:
+ if (0 == (t = *p++)) {
+ err = mnvm_noErr;
+ /* done */
+ } else
+ if (0 == (0x80 & t)) {
+ /* One-byte code */
+ L += 1;
+ goto label_retry;
+ } else
+ if (0 == (0x40 & t)) {
+ /* continuation code, error */
+ err = mnvm_miscErr;
+ } else
+ if (0 == (t2 = *p++)) {
+ err = mnvm_miscErr;
+ } else
+ if (0x80 != (0xC0 & t2)) {
+ /* not a continuation code, error */
+ err = mnvm_miscErr;
+ } else
+ if (0 == (0x20 & t)) {
+ /* two bytes */
+ L += 2;
+ goto label_retry;
+ } else
+ if (0 == (t2 = *p++)) {
+ err = mnvm_miscErr;
+ } else
+ if (0x80 != (0xC0 & t2)) {
+ /* not a continuation code, error */
+ err = mnvm_miscErr;
+ } else
+ if (0 == (0x10 & t)) {
+ /* three bytes */
+ L += 3;
+ goto label_retry;
+ } else
+ if (0 == (t2 = *p++)) {
+ err = mnvm_miscErr;
+ } else
+ if (0x80 != (0xC0 & t2)) {
+ /* not a continuation code, error */
+ err = mnvm_miscErr;
+ } else
+ if (0 == (0x08 & t)) {
+ /* four bytes */
+ L += 5;
+ goto label_retry;
+ } else
+ {
+ err = mnvm_miscErr;
+ /* longer code not supported yet */
+ }
+
+ *r = L;
+ return err;
+}
+#endif
+
+#if IncludeHostTextClipExchange
+LOCALFUNC ui3r UniCodePoint2MacRoman(ui5r x)
+{
+/*
+ adapted from
+ http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ROMAN.TXT
+*/
+ ui3r y;
+
+ if (x < 128) {
+ y = x;
+ } else {
+ switch (x) {
+ case 0x00C4: y = 0x80; break;
+ /* LATIN CAPITAL LETTER A WITH DIAERESIS */
+ case 0x00C5: y = 0x81; break;
+ /* LATIN CAPITAL LETTER A WITH RING ABOVE */
+ case 0x00C7: y = 0x82; break;
+ /* LATIN CAPITAL LETTER C WITH CEDILLA */
+ case 0x00C9: y = 0x83; break;
+ /* LATIN CAPITAL LETTER E WITH ACUTE */
+ case 0x00D1: y = 0x84; break;
+ /* LATIN CAPITAL LETTER N WITH TILDE */
+ case 0x00D6: y = 0x85; break;
+ /* LATIN CAPITAL LETTER O WITH DIAERESIS */
+ case 0x00DC: y = 0x86; break;
+ /* LATIN CAPITAL LETTER U WITH DIAERESIS */
+ case 0x00E1: y = 0x87; break;
+ /* LATIN SMALL LETTER A WITH ACUTE */
+ case 0x00E0: y = 0x88; break;
+ /* LATIN SMALL LETTER A WITH GRAVE */
+ case 0x00E2: y = 0x89; break;
+ /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
+ case 0x00E4: y = 0x8A; break;
+ /* LATIN SMALL LETTER A WITH DIAERESIS */
+ case 0x00E3: y = 0x8B; break;
+ /* LATIN SMALL LETTER A WITH TILDE */
+ case 0x00E5: y = 0x8C; break;
+ /* LATIN SMALL LETTER A WITH RING ABOVE */
+ case 0x00E7: y = 0x8D; break;
+ /* LATIN SMALL LETTER C WITH CEDILLA */
+ case 0x00E9: y = 0x8E; break;
+ /* LATIN SMALL LETTER E WITH ACUTE */
+ case 0x00E8: y = 0x8F; break;
+ /* LATIN SMALL LETTER E WITH GRAVE */
+ case 0x00EA: y = 0x90; break;
+ /* LATIN SMALL LETTER E WITH CIRCUMFLEX */
+ case 0x00EB: y = 0x91; break;
+ /* LATIN SMALL LETTER E WITH DIAERESIS */
+ case 0x00ED: y = 0x92; break;
+ /* LATIN SMALL LETTER I WITH ACUTE */
+ case 0x00EC: y = 0x93; break;
+ /* LATIN SMALL LETTER I WITH GRAVE */
+ case 0x00EE: y = 0x94; break;
+ /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
+ case 0x00EF: y = 0x95; break;
+ /* LATIN SMALL LETTER I WITH DIAERESIS */
+ case 0x00F1: y = 0x96; break;
+ /* LATIN SMALL LETTER N WITH TILDE */
+ case 0x00F3: y = 0x97; break;
+ /* LATIN SMALL LETTER O WITH ACUTE */
+ case 0x00F2: y = 0x98; break;
+ /* LATIN SMALL LETTER O WITH GRAVE */
+ case 0x00F4: y = 0x99; break;
+ /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
+ case 0x00F6: y = 0x9A; break;
+ /* LATIN SMALL LETTER O WITH DIAERESIS */
+ case 0x00F5: y = 0x9B; break;
+ /* LATIN SMALL LETTER O WITH TILDE */
+ case 0x00FA: y = 0x9C; break;
+ /* LATIN SMALL LETTER U WITH ACUTE */
+ case 0x00F9: y = 0x9D; break;
+ /* LATIN SMALL LETTER U WITH GRAVE */
+ case 0x00FB: y = 0x9E; break;
+ /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
+ case 0x00FC: y = 0x9F; break;
+ /* LATIN SMALL LETTER U WITH DIAERESIS */
+ case 0x2020: y = 0xA0; break;
+ /* DAGGER */
+ case 0x00B0: y = 0xA1; break;
+ /* DEGREE SIGN */
+ case 0x00A2: y = 0xA2; break;
+ /* CENT SIGN */
+ case 0x00A3: y = 0xA3; break;
+ /* POUND SIGN */
+ case 0x00A7: y = 0xA4; break;
+ /* SECTION SIGN */
+ case 0x2022: y = 0xA5; break;
+ /* BULLET */
+ case 0x00B6: y = 0xA6; break;
+ /* PILCROW SIGN */
+ case 0x00DF: y = 0xA7; break;
+ /* LATIN SMALL LETTER SHARP S */
+ case 0x00AE: y = 0xA8; break;
+ /* REGISTERED SIGN */
+ case 0x00A9: y = 0xA9; break;
+ /* COPYRIGHT SIGN */
+ case 0x2122: y = 0xAA; break;
+ /* TRADE MARK SIGN */
+ case 0x00B4: y = 0xAB; break;
+ /* ACUTE ACCENT */
+ case 0x00A8: y = 0xAC; break;
+ /* DIAERESIS */
+ case 0x2260: y = 0xAD; break;
+ /* NOT EQUAL TO */
+ case 0x00C6: y = 0xAE; break;
+ /* LATIN CAPITAL LETTER AE */
+ case 0x00D8: y = 0xAF; break;
+ /* LATIN CAPITAL LETTER O WITH STROKE */
+ case 0x221E: y = 0xB0; break;
+ /* INFINITY */
+ case 0x00B1: y = 0xB1; break;
+ /* PLUS-MINUS SIGN */
+ case 0x2264: y = 0xB2; break;
+ /* LESS-THAN OR EQUAL TO */
+ case 0x2265: y = 0xB3; break;
+ /* GREATER-THAN OR EQUAL TO */
+ case 0x00A5: y = 0xB4; break;
+ /* YEN SIGN */
+ case 0x00B5: y = 0xB5; break;
+ /* MICRO SIGN */
+ case 0x2202: y = 0xB6; break;
+ /* PARTIAL DIFFERENTIAL */
+ case 0x2211: y = 0xB7; break;
+ /* N-ARY SUMMATION */
+ case 0x220F: y = 0xB8; break;
+ /* N-ARY PRODUCT */
+ case 0x03C0: y = 0xB9; break;
+ /* GREEK SMALL LETTER PI */
+ case 0x222B: y = 0xBA; break;
+ /* INTEGRAL */
+ case 0x00AA: y = 0xBB; break;
+ /* FEMININE ORDINAL INDICATOR */
+ case 0x00BA: y = 0xBC; break;
+ /* MASCULINE ORDINAL INDICATOR */
+ case 0x03A9: y = 0xBD; break;
+ /* GREEK CAPITAL LETTER OMEGA */
+ case 0x00E6: y = 0xBE; break;
+ /* LATIN SMALL LETTER AE */
+ case 0x00F8: y = 0xBF; break;
+ /* LATIN SMALL LETTER O WITH STROKE */
+ case 0x00BF: y = 0xC0; break;
+ /* INVERTED QUESTION MARK */
+ case 0x00A1: y = 0xC1; break;
+ /* INVERTED EXCLAMATION MARK */
+ case 0x00AC: y = 0xC2; break;
+ /* NOT SIGN */
+ case 0x221A: y = 0xC3; break;
+ /* SQUARE ROOT */
+ case 0x0192: y = 0xC4; break;
+ /* LATIN SMALL LETTER F WITH HOOK */
+ case 0x2248: y = 0xC5; break;
+ /* ALMOST EQUAL TO */
+ case 0x2206: y = 0xC6; break;
+ /* INCREMENT */
+ case 0x00AB: y = 0xC7; break;
+ /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
+ case 0x00BB: y = 0xC8; break;
+ /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
+ case 0x2026: y = 0xC9; break;
+ /* HORIZONTAL ELLIPSIS */
+ case 0x00A0: y = 0xCA; break;
+ /* NO-BREAK SPACE */
+ case 0x00C0: y = 0xCB; break;
+ /* LATIN CAPITAL LETTER A WITH GRAVE */
+ case 0x00C3: y = 0xCC; break;
+ /* LATIN CAPITAL LETTER A WITH TILDE */
+ case 0x00D5: y = 0xCD; break;
+ /* LATIN CAPITAL LETTER O WITH TILDE */
+ case 0x0152: y = 0xCE; break;
+ /* LATIN CAPITAL LIGATURE OE */
+ case 0x0153: y = 0xCF; break;
+ /* LATIN SMALL LIGATURE OE */
+ case 0x2013: y = 0xD0; break;
+ /* EN DASH */
+ case 0x2014: y = 0xD1; break;
+ /* EM DASH */
+ case 0x201C: y = 0xD2; break;
+ /* LEFT DOUBLE QUOTATION MARK */
+ case 0x201D: y = 0xD3; break;
+ /* RIGHT DOUBLE QUOTATION MARK */
+ case 0x2018: y = 0xD4; break;
+ /* LEFT SINGLE QUOTATION MARK */
+ case 0x2019: y = 0xD5; break;
+ /* RIGHT SINGLE QUOTATION MARK */
+ case 0x00F7: y = 0xD6; break;
+ /* DIVISION SIGN */
+ case 0x25CA: y = 0xD7; break;
+ /* LOZENGE */
+ case 0x00FF: y = 0xD8; break;
+ /* LATIN SMALL LETTER Y WITH DIAERESIS */
+ case 0x0178: y = 0xD9; break;
+ /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
+ case 0x2044: y = 0xDA; break;
+ /* FRACTION SLASH */
+ case 0x20AC: y = 0xDB; break;
+ /* EURO SIGN */
+ case 0x2039: y = 0xDC; break;
+ /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK */
+ case 0x203A: y = 0xDD; break;
+ /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */
+ case 0xFB01: y = 0xDE; break;
+ /* LATIN SMALL LIGATURE FI */
+ case 0xFB02: y = 0xDF; break;
+ /* LATIN SMALL LIGATURE FL */
+ case 0x2021: y = 0xE0; break;
+ /* DOUBLE DAGGER */
+ case 0x00B7: y = 0xE1; break;
+ /* MIDDLE DOT */
+ case 0x201A: y = 0xE2; break;
+ /* SINGLE LOW-9 QUOTATION MARK */
+ case 0x201E: y = 0xE3; break;
+ /* DOUBLE LOW-9 QUOTATION MARK */
+ case 0x2030: y = 0xE4; break;
+ /* PER MILLE SIGN */
+ case 0x00C2: y = 0xE5; break;
+ /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
+ case 0x00CA: y = 0xE6; break;
+ /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
+ case 0x00C1: y = 0xE7; break;
+ /* LATIN CAPITAL LETTER A WITH ACUTE */
+ case 0x00CB: y = 0xE8; break;
+ /* LATIN CAPITAL LETTER E WITH DIAERESIS */
+ case 0x00C8: y = 0xE9; break;
+ /* LATIN CAPITAL LETTER E WITH GRAVE */
+ case 0x00CD: y = 0xEA; break;
+ /* LATIN CAPITAL LETTER I WITH ACUTE */
+ case 0x00CE: y = 0xEB; break;
+ /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
+ case 0x00CF: y = 0xEC; break;
+ /* LATIN CAPITAL LETTER I WITH DIAERESIS */
+ case 0x00CC: y = 0xED; break;
+ /* LATIN CAPITAL LETTER I WITH GRAVE */
+ case 0x00D3: y = 0xEE; break;
+ /* LATIN CAPITAL LETTER O WITH ACUTE */
+ case 0x00D4: y = 0xEF; break;
+ /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
+ case 0xF8FF: y = 0xF0; break;
+ /* Apple logo */
+ case 0x00D2: y = 0xF1; break;
+ /* LATIN CAPITAL LETTER O WITH GRAVE */
+ case 0x00DA: y = 0xF2; break;
+ /* LATIN CAPITAL LETTER U WITH ACUTE */
+ case 0x00DB: y = 0xF3; break;
+ /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
+ case 0x00D9: y = 0xF4; break;
+ /* LATIN CAPITAL LETTER U WITH GRAVE */
+ case 0x0131: y = 0xF5; break;
+ /* LATIN SMALL LETTER DOTLESS I */
+ case 0x02C6: y = 0xF6; break;
+ /* MODIFIER LETTER CIRCUMFLEX ACCENT */
+ case 0x02DC: y = 0xF7; break;
+ /* SMALL TILDE */
+ case 0x00AF: y = 0xF8; break;
+ /* MACRON */
+ case 0x02D8: y = 0xF9; break;
+ /* BREVE */
+ case 0x02D9: y = 0xFA; break;
+ /* DOT ABOVE */
+ case 0x02DA: y = 0xFB; break;
+ /* RING ABOVE */
+ case 0x00B8: y = 0xFC; break;
+ /* CEDILLA */
+ case 0x02DD: y = 0xFD; break;
+ /* DOUBLE ACUTE ACCENT */
+ case 0x02DB: y = 0xFE; break;
+ /* OGONEK */
+ case 0x02C7: y = 0xFF; break;
+ /* CARON */
+ default: y = '?'; break;
+ /* unrecognized */
+ }
+ }
+
+ return y;
+}
+#endif
+
+#if IncludeHostTextClipExchange
+LOCALPROC UniCodeStr2MacRoman(char *s, char *r)
+{
+ tMacErr err;
+ ui3r t;
+ ui3r t2;
+ ui3r t3;
+ ui3r t4;
+ ui5r v;
+ char *p = s;
+ char *q = r;
+
+label_retry:
+ if (0 == (t = *p++)) {
+ err = mnvm_noErr;
+ /* done */
+ } else
+ if (0 == (0x80 & t)) {
+ *q++ = t;
+ goto label_retry;
+ } else
+ if (0 == (0x40 & t)) {
+ /* continuation code, error */
+ err = mnvm_miscErr;
+ } else
+ if (0 == (t2 = *p++)) {
+ err = mnvm_miscErr;
+ } else
+ if (0x80 != (0xC0 & t2)) {
+ /* not a continuation code, error */
+ err = mnvm_miscErr;
+ } else
+ if (0 == (0x20 & t)) {
+ /* two bytes */
+ v = t & 0x1F;
+ v = (v << 6) | (t2 & 0x3F);
+ *q++ = UniCodePoint2MacRoman(v);
+ goto label_retry;
+ } else
+ if (0 == (t3 = *p++)) {
+ err = mnvm_miscErr;
+ } else
+ if (0x80 != (0xC0 & t3)) {
+ /* not a continuation code, error */
+ err = mnvm_miscErr;
+ } else
+ if (0 == (0x10 & t)) {
+ /* three bytes */
+ v = t & 0x0F;
+ v = (v << 6) | (t3 & 0x3F);
+ v = (v << 6) | (t2 & 0x3F);
+ *q++ = UniCodePoint2MacRoman(v);
+ goto label_retry;
+ } else
+ if (0 == (t4 = *p++)) {
+ err = mnvm_miscErr;
+ } else
+ if (0x80 != (0xC0 & t4)) {
+ /* not a continuation code, error */
+ err = mnvm_miscErr;
+ } else
+ if (0 == (0x08 & t)) {
+ /* four bytes */
+ v = t & 0x07;
+ v = (v << 6) | (t4 & 0x3F);
+ v = (v << 6) | (t3 & 0x3F);
+ v = (v << 6) | (t2 & 0x3F);
+ *q++ = UniCodePoint2MacRoman(v);
+ goto label_retry;
+ } else
+ {
+ err = mnvm_miscErr;
+ /* longer code not supported yet */
+ }
+}
+#endif
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEimport(tPbuf *r)
+{
+ tMacErr err;
+ uimr L;
+ char *s = NULL;
+ tPbuf t = NotAPbuf;
+
+ if (NULL == (s = SDL_GetClipboardText())) {
+ err = mnvm_miscErr;
+ } else
+ if (mnvm_noErr != (err =
+ UniCodeStrLength(s, &L)))
+ {
+ /* fail */
+ } else
+ if (mnvm_noErr != (err =
+ PbufNew(L, &t)))
+ {
+ /* fail */
+ } else
+ {
+ err = mnvm_noErr;
+
+ UniCodeStr2MacRoman(s, PbufDat[t]);
+ *r = t;
+ t = NotAPbuf;
+ }
+
+ if (NotAPbuf != t) {
+ PbufDispose(t);
+ }
+ if (NULL != s) {
+ SDL_free(s);
+ }
+
+ return err;
+}
+#endif
+
+/* --- event handling for main window --- */
+
+#define UseMotionEvents 1
+
+#if UseMotionEvents
+LOCALVAR blnr CaughtMouse = falseblnr;
+#endif
+
+LOCALPROC HandleTheEvent(SDL_Event *event)
+{
+ switch (event->type) {
+ case SDL_QUIT:
+ RequestMacOff = trueblnr;
+ break;
+ case SDL_WINDOWEVENT:
+ switch (event->window.event) {
+ case SDL_WINDOWEVENT_FOCUS_GAINED:
+ gTrueBackgroundFlag = 0;
+ break;
+ case SDL_WINDOWEVENT_FOCUS_LOST:
+ gTrueBackgroundFlag = 1;
+ break;
+ case SDL_WINDOWEVENT_ENTER:
+ CaughtMouse = 1;
+ break;
+ case SDL_WINDOWEVENT_LEAVE:
+ CaughtMouse = 0;
+ break;
+ }
+ break;
+ case SDL_MOUSEMOTION:
+#if EnableFSMouseMotion && ! HaveWorkingWarp
+ if (HaveMouseMotion) {
+ MousePositionNotifyRelative(
+ event->motion.xrel, event->motion.yrel);
+ } else
+#endif
+ {
+ MousePositionNotify(
+ event->motion.x, event->motion.y);
+ }
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ /* any mouse button, we don't care which */
+#if EnableFSMouseMotion && ! HaveWorkingWarp
+ if (HaveMouseMotion) {
+ /* ignore position */
+ } else
+#endif
+ {
+ MousePositionNotify(
+ event->button.x, event->button.y);
+ }
+ MyMouseButtonSet(trueblnr);
+ break;
+ case SDL_MOUSEBUTTONUP:
+#if EnableFSMouseMotion && ! HaveWorkingWarp
+ if (HaveMouseMotion) {
+ /* ignore position */
+ } else
+#endif
+ {
+ MousePositionNotify(
+ event->button.x, event->button.y);
+ }
+ MyMouseButtonSet(falseblnr);
+ break;
+ case SDL_KEYDOWN:
+ DoKeyCode(&event->key.keysym, trueblnr);
+ break;
+ case SDL_KEYUP:
+ DoKeyCode(&event->key.keysym, falseblnr);
+ break;
+ case SDL_MOUSEWHEEL:
+ if (event->wheel.x < 0) {
+ Keyboard_UpdateKeyMap2(MKC_Left, trueblnr);
+ Keyboard_UpdateKeyMap2(MKC_Left, falseblnr);
+ } else if (event->wheel.x > 0) {
+ Keyboard_UpdateKeyMap2(MKC_Right, trueblnr);
+ Keyboard_UpdateKeyMap2(MKC_Right, falseblnr);
+ }
+ if (event->wheel.y < 0) {
+ Keyboard_UpdateKeyMap2(MKC_Down, trueblnr);
+ Keyboard_UpdateKeyMap2(MKC_Down, falseblnr);
+ } else if(event->wheel.y > 0) {
+ Keyboard_UpdateKeyMap2(MKC_Up, trueblnr);
+ Keyboard_UpdateKeyMap2(MKC_Up, falseblnr);
+ }
+ break;
+ case SDL_DROPFILE:
+ {
+ char *s = event->drop.file;
+
+ (void) Sony_Insert1a(s, falseblnr);
+ SDL_RaiseWindow(my_main_wind);
+ SDL_free(s);
+ }
+ break;
+#if 0
+ case Expose: /* SDL doesn't have an expose event */
+ int x0 = event->expose.x;
+ int y0 = event->expose.y;
+ int x1 = x0 + event->expose.width;
+ int y1 = y0 + event->expose.height;
+
+ if (x0 < 0) {
+ x0 = 0;
+ }
+ if (x1 > vMacScreenWidth) {
+ x1 = vMacScreenWidth;
+ }
+ if (y0 < 0) {
+ y0 = 0;
+ }
+ if (y1 > vMacScreenHeight) {
+ y1 = vMacScreenHeight;
+ }
+ if ((x0 < x1) && (y0 < y1)) {
+ HaveChangedScreenBuff(y0, x0, y1, x1);
+ }
+ break;
+#endif
+ }
+}
+
+/* --- main window creation and disposal --- */
+
+LOCALVAR int my_argc;
+LOCALVAR char **my_argv;
+
+LOCALFUNC blnr Screen_Init(void)
+{
+ blnr v = falseblnr;
+
+ InitKeyCodes();
+
+ if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
+ {
+ fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
+ } else {
+ v = trueblnr;
+ }
+
+ return v;
+}
+
+#if MayFullScreen
+LOCALVAR blnr GrabMachine = falseblnr;
+#endif
+
+#if MayFullScreen
+LOCALPROC GrabTheMachine(void)
+{
+#if GrabKeysFullScreen
+ SDL_SetWindowGrab(my_main_wind, SDL_TRUE);
+#endif
+
+#if EnableFSMouseMotion
+
+#if HaveWorkingWarp
+ /*
+ if magnification changes, need to reset,
+ even if HaveMouseMotion already true
+ */
+ if (MyMoveMouse(ViewHStart + (ViewHSize / 2),
+ ViewVStart + (ViewVSize / 2)))
+ {
+ SavedMouseH = ViewHStart + (ViewHSize / 2);
+ SavedMouseV = ViewVStart + (ViewVSize / 2);
+ HaveMouseMotion = trueblnr;
+ }
+#else
+ if (0 == SDL_SetRelativeMouseMode(SDL_ENABLE)) {
+ HaveMouseMotion = trueblnr;
+ }
+#endif
+
+#endif /* EnableFSMouseMotion */
+}
+#endif
+
+#if MayFullScreen
+LOCALPROC UngrabMachine(void)
+{
+#if EnableFSMouseMotion
+
+ if (HaveMouseMotion) {
+#if HaveWorkingWarp
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+#else
+ SDL_SetRelativeMouseMode(SDL_DISABLE);
+#endif
+
+ HaveMouseMotion = falseblnr;
+ }
+
+#endif /* EnableFSMouseMotion */
+
+#if GrabKeysFullScreen
+ SDL_SetWindowGrab(my_main_wind, SDL_FALSE);
+#endif
+}
+#endif
+
+#if EnableFSMouseMotion && HaveWorkingWarp
+LOCALPROC MyMouseConstrain(void)
+{
+ si4b shiftdh;
+ si4b shiftdv;
+
+ if (SavedMouseH < ViewHStart + (ViewHSize / 4)) {
+ shiftdh = ViewHSize / 2;
+ } else if (SavedMouseH > ViewHStart + ViewHSize - (ViewHSize / 4)) {
+ shiftdh = - ViewHSize / 2;
+ } else {
+ shiftdh = 0;
+ }
+ if (SavedMouseV < ViewVStart + (ViewVSize / 4)) {
+ shiftdv = ViewVSize / 2;
+ } else if (SavedMouseV > ViewVStart + ViewVSize - (ViewVSize / 4)) {
+ shiftdv = - ViewVSize / 2;
+ } else {
+ shiftdv = 0;
+ }
+ if ((shiftdh != 0) || (shiftdv != 0)) {
+ SavedMouseH += shiftdh;
+ SavedMouseV += shiftdv;
+ if (! MyMoveMouse(SavedMouseH, SavedMouseV)) {
+ HaveMouseMotion = falseblnr;
+ }
+ }
+}
+#endif
+
+enum {
+ kMagStateNormal,
+#if EnableMagnify
+ kMagStateMagnifgy,
+#endif
+ kNumMagStates
+};
+
+#define kMagStateAuto kNumMagStates
+
+#if MayNotFullScreen
+LOCALVAR int CurWinIndx;
+LOCALVAR blnr HavePositionWins[kNumMagStates];
+LOCALVAR int WinPositionsX[kNumMagStates];
+LOCALVAR int WinPositionsY[kNumMagStates];
+#endif
+
+LOCALFUNC blnr CreateMainWindow(void)
+{
+ int NewWindowX;
+ int NewWindowY;
+ int NewWindowHeight = vMacScreenHeight;
+ int NewWindowWidth = vMacScreenWidth;
+ Uint32 flags = 0 /* SDL_WINDOW_HIDDEN */;
+ blnr v = falseblnr;
+
+#if EnableMagnify && 1
+ if (UseMagnify) {
+ NewWindowHeight *= MyWindowScale;
+ NewWindowWidth *= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ /*
+ We don't want physical screen mode to be changed in modern
+ displays, so we pass this _DESKTOP flag.
+ */
+ flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
+
+ NewWindowX = SDL_WINDOWPOS_UNDEFINED;
+ NewWindowY = SDL_WINDOWPOS_UNDEFINED;
+ }
+#endif
+#if VarFullScreen
+ else
+#endif
+#if MayNotFullScreen
+ {
+ int WinIndx;
+
+#if EnableMagnify
+ if (UseMagnify) {
+ WinIndx = kMagStateMagnifgy;
+ } else
+#endif
+ {
+ WinIndx = kMagStateNormal;
+ }
+
+ if (! HavePositionWins[WinIndx]) {
+ NewWindowX = SDL_WINDOWPOS_CENTERED;
+ NewWindowY = SDL_WINDOWPOS_CENTERED;
+ } else {
+ NewWindowX = WinPositionsX[WinIndx];
+ NewWindowY = WinPositionsY[WinIndx];
+ }
+
+ CurWinIndx = WinIndx;
+ }
+#endif
+
+#if 0
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
+#endif
+
+ if (NULL == (my_main_wind = SDL_CreateWindow(
+ (NULL != n_arg) ? n_arg : kStrAppName,
+ NewWindowX, NewWindowY,
+ NewWindowWidth, NewWindowHeight,
+ flags)))
+ {
+ fprintf(stderr, "SDL_CreateWindow fails: %s\n",
+ SDL_GetError());
+ } else
+ if (NULL == (my_renderer = SDL_CreateRenderer(
+ my_main_wind, -1,
+ 0 /* SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC */
+ /*
+ SDL_RENDERER_ACCELERATED not needed
+ "no flags gives priority to available
+ SDL_RENDERER_ACCELERATED renderers"
+ */
+ /* would rather not require vsync */
+ )))
+ {
+ fprintf(stderr, "SDL_CreateRenderer fails: %s\n",
+ SDL_GetError());
+ } else
+ if (NULL == (my_texture = SDL_CreateTexture(
+ my_renderer,
+ SDL_PIXELFORMAT_ARGB8888,
+ SDL_TEXTUREACCESS_STREAMING,
+#if UseSDLscaling
+ vMacScreenWidth, vMacScreenHeight
+#else
+ NewWindowWidth, NewWindowHeight
+#endif
+ )))
+ {
+ fprintf(stderr, "SDL_CreateTexture fails: %s\n",
+ SDL_GetError());
+ } else
+ if (NULL == (my_format = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888)))
+ {
+ fprintf(stderr, "SDL_AllocFormat fails: %s\n",
+ SDL_GetError());
+ } else
+ {
+ /* SDL_ShowWindow(my_main_wind); */
+
+ SDL_RenderClear(my_renderer);
+
+#if 0
+ SDL_DisplayMode info;
+
+ if (0 != SDL_GetCurrentDisplayMode(0, &info)) {
+ fprintf(stderr, "SDL_GetCurrentDisplayMode fails: %s\n",
+ SDL_GetError());
+
+ return falseblnr;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ int wr;
+ int hr;
+
+ SDL_GL_GetDrawableSize(my_main_wind, &wr, &hr);
+
+ ViewHSize = wr;
+ ViewVSize = hr;
+#if EnableMagnify
+ if (UseMagnify) {
+ ViewHSize /= MyWindowScale;
+ ViewVSize /= MyWindowScale;
+ }
+#endif
+ if (ViewHSize >= vMacScreenWidth) {
+ ViewHStart = 0;
+ ViewHSize = vMacScreenWidth;
+ } else {
+ ViewHSize &= ~ 1;
+ }
+ if (ViewVSize >= vMacScreenHeight) {
+ ViewVStart = 0;
+ ViewVSize = vMacScreenHeight;
+ } else {
+ ViewVSize &= ~ 1;
+ }
+
+ if (wr > NewWindowWidth) {
+ hOffset = (wr - NewWindowWidth) / 2;
+ } else {
+ hOffset = 0;
+ }
+ if (hr > NewWindowHeight) {
+ vOffset = (hr - NewWindowHeight) / 2;
+ } else {
+ vOffset = 0;
+ }
+ }
+#endif
+
+#if 0 != vMacScreenDepth
+ ColorModeWorks = trueblnr;
+#endif
+
+ v = trueblnr;
+ }
+
+ return v;
+}
+
+LOCALPROC CloseMainWindow(void)
+{
+ if (NULL != my_format) {
+ SDL_FreeFormat(my_format);
+ my_format = NULL;
+ }
+
+ if (NULL != my_texture) {
+ SDL_DestroyTexture(my_texture);
+ my_texture = NULL;
+ }
+
+ if (NULL != my_renderer) {
+ SDL_DestroyRenderer(my_renderer);
+ my_renderer = NULL;
+ }
+
+ if (NULL != my_main_wind) {
+ SDL_DestroyWindow(my_main_wind);
+ my_main_wind = NULL;
+ }
+}
+
+#if EnableRecreateW
+LOCALPROC ZapMyWState(void)
+{
+ my_main_wind = NULL;
+ my_renderer = NULL;
+ my_texture = NULL;
+ my_format = NULL;
+}
+#endif
+
+#if EnableRecreateW
+struct MyWState {
+#if MayFullScreen
+ ui4r f_ViewHSize;
+ ui4r f_ViewVSize;
+ ui4r f_ViewHStart;
+ ui4r f_ViewVStart;
+ int f_hOffset;
+ int f_vOffset;
+#endif
+#if VarFullScreen
+ blnr f_UseFullScreen;
+#endif
+#if EnableMagnify
+ blnr f_UseMagnify;
+#endif
+#if MayNotFullScreen
+ int f_CurWinIndx;
+#endif
+ SDL_Window *f_my_main_wind;
+ SDL_Renderer *f_my_renderer;
+ SDL_Texture *f_my_texture;
+ SDL_PixelFormat *f_my_format;
+};
+typedef struct MyWState MyWState;
+#endif
+
+#if EnableRecreateW
+LOCALPROC GetMyWState(MyWState *r)
+{
+#if MayFullScreen
+ r->f_ViewHSize = ViewHSize;
+ r->f_ViewVSize = ViewVSize;
+ r->f_ViewHStart = ViewHStart;
+ r->f_ViewVStart = ViewVStart;
+ r->f_hOffset = hOffset;
+ r->f_vOffset = vOffset;
+#endif
+#if VarFullScreen
+ r->f_UseFullScreen = UseFullScreen;
+#endif
+#if EnableMagnify
+ r->f_UseMagnify = UseMagnify;
+#endif
+#if MayNotFullScreen
+ r->f_CurWinIndx = CurWinIndx;
+#endif
+ r->f_my_main_wind = my_main_wind;
+ r->f_my_renderer = my_renderer;
+ r->f_my_texture = my_texture;
+ r->f_my_format = my_format;
+}
+#endif
+
+#if EnableRecreateW
+LOCALPROC SetMyWState(MyWState *r)
+{
+#if MayFullScreen
+ ViewHSize = r->f_ViewHSize;
+ ViewVSize = r->f_ViewVSize;
+ ViewHStart = r->f_ViewHStart;
+ ViewVStart = r->f_ViewVStart;
+ hOffset = r->f_hOffset;
+ vOffset = r->f_vOffset;
+#endif
+#if VarFullScreen
+ UseFullScreen = r->f_UseFullScreen;
+#endif
+#if EnableMagnify
+ UseMagnify = r->f_UseMagnify;
+#endif
+#if MayNotFullScreen
+ CurWinIndx = r->f_CurWinIndx;
+#endif
+ my_main_wind = r->f_my_main_wind;
+ my_renderer = r->f_my_renderer;
+ my_texture = r->f_my_texture;
+ my_format = r->f_my_format;
+}
+#endif
+
+#if VarFullScreen && EnableMagnify
+enum {
+ kWinStateWindowed,
+#if EnableMagnify
+ kWinStateFullScreen,
+#endif
+ kNumWinStates
+};
+#endif
+
+#if VarFullScreen && EnableMagnify
+LOCALVAR int WinMagStates[kNumWinStates];
+#endif
+
+#if EnableRecreateW
+LOCALFUNC blnr ReCreateMainWindow(void)
+{
+ MyWState old_state;
+ MyWState new_state;
+#if HaveWorkingWarp
+ blnr HadCursorHidden = HaveCursorHidden;
+#endif
+#if VarFullScreen && EnableMagnify
+ int OldWinState =
+ UseFullScreen ? kWinStateFullScreen : kWinStateWindowed;
+ int OldMagState =
+ UseMagnify ? kMagStateMagnifgy : kMagStateNormal;
+
+ WinMagStates[OldWinState] =
+ OldMagState;
+#endif
+
+#if VarFullScreen
+ if (! UseFullScreen)
+#endif
+#if MayNotFullScreen
+ {
+ SDL_GetWindowPosition(my_main_wind,
+ &WinPositionsX[CurWinIndx],
+ &WinPositionsY[CurWinIndx]);
+ HavePositionWins[CurWinIndx] = trueblnr;
+ }
+#endif
+
+ ForceShowCursor(); /* hide/show cursor api is per window */
+
+#if MayFullScreen
+ if (GrabMachine) {
+ GrabMachine = falseblnr;
+ UngrabMachine();
+ }
+#endif
+
+ GetMyWState(&old_state);
+
+ ZapMyWState();
+
+#if EnableMagnify
+ UseMagnify = WantMagnify;
+#endif
+#if VarFullScreen
+ UseFullScreen = WantFullScreen;
+#endif
+
+ if (! CreateMainWindow()) {
+ CloseMainWindow();
+ SetMyWState(&old_state);
+
+ /* avoid retry */
+#if VarFullScreen
+ WantFullScreen = UseFullScreen;
+#endif
+#if EnableMagnify
+ WantMagnify = UseMagnify;
+#endif
+
+ } else {
+ GetMyWState(&new_state);
+ SetMyWState(&old_state);
+ CloseMainWindow();
+ SetMyWState(&new_state);
+
+#if HaveWorkingWarp
+ if (HadCursorHidden) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ }
+#endif
+ }
+
+ return trueblnr;
+}
+#endif
+
+LOCALPROC ZapWinStateVars(void)
+{
+#if MayNotFullScreen
+ {
+ int i;
+
+ for (i = 0; i < kNumMagStates; ++i) {
+ HavePositionWins[i] = falseblnr;
+ }
+ }
+#endif
+#if VarFullScreen && EnableMagnify
+ {
+ int i;
+
+ for (i = 0; i < kNumWinStates; ++i) {
+ WinMagStates[i] = kMagStateAuto;
+ }
+ }
+#endif
+}
+
+#if VarFullScreen
+LOCALPROC ToggleWantFullScreen(void)
+{
+ WantFullScreen = ! WantFullScreen;
+
+#if EnableMagnify
+ {
+ int OldWinState =
+ UseFullScreen ? kWinStateFullScreen : kWinStateWindowed;
+ int OldMagState =
+ UseMagnify ? kMagStateMagnifgy : kMagStateNormal;
+ int NewWinState =
+ WantFullScreen ? kWinStateFullScreen : kWinStateWindowed;
+ int NewMagState = WinMagStates[NewWinState];
+
+ WinMagStates[OldWinState] = OldMagState;
+ if (kMagStateAuto != NewMagState) {
+ WantMagnify = (kMagStateMagnifgy == NewMagState);
+ } else {
+ WantMagnify = falseblnr;
+ if (WantFullScreen) {
+ SDL_Rect r;
+
+ if (0 == SDL_GetDisplayBounds(0, &r)) {
+ if ((r.w >= vMacScreenWidth * MyWindowScale)
+ && (r.h >= vMacScreenHeight * MyWindowScale)
+ )
+ {
+ WantMagnify = trueblnr;
+ }
+ }
+ }
+ }
+ }
+#endif
+}
+#endif
+
+/* --- SavedTasks --- */
+
+LOCALPROC LeaveBackground(void)
+{
+ ReconnectKeyCodes3();
+ DisableKeyRepeat();
+}
+
+LOCALPROC EnterBackground(void)
+{
+ RestoreKeyRepeat();
+ DisconnectKeyCodes3();
+
+ ForceShowCursor();
+}
+
+LOCALPROC LeaveSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Start();
+#endif
+
+ StartUpTimeAdjust();
+}
+
+LOCALPROC EnterSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+}
+
+LOCALPROC CheckForSavedTasks(void)
+{
+ if (MyEvtQNeedRecover) {
+ MyEvtQNeedRecover = falseblnr;
+
+ /* attempt cleanup, MyEvtQNeedRecover may get set again */
+ MyEvtQTryRecoverFromFull();
+ }
+
+#if EnableFSMouseMotion && HaveWorkingWarp
+ if (HaveMouseMotion) {
+ MyMouseConstrain();
+ }
+#endif
+
+ if (RequestMacOff) {
+ RequestMacOff = falseblnr;
+ if (AnyDiskInserted()) {
+ MacMsgOverride(kStrQuitWarningTitle,
+ kStrQuitWarningMessage);
+ } else {
+ ForceMacOff = trueblnr;
+ }
+ }
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (gTrueBackgroundFlag != gBackgroundFlag) {
+ gBackgroundFlag = gTrueBackgroundFlag;
+ if (gTrueBackgroundFlag) {
+ EnterBackground();
+ } else {
+ LeaveBackground();
+ }
+ }
+
+ if (CurSpeedStopped != (SpeedStopped ||
+ (gBackgroundFlag && ! RunInBackground
+#if EnableAutoSlow && 0
+ && (QuietSubTicks >= 4092)
+#endif
+ )))
+ {
+ CurSpeedStopped = ! CurSpeedStopped;
+ if (CurSpeedStopped) {
+ EnterSpeedStopped();
+ } else {
+ LeaveSpeedStopped();
+ }
+ }
+
+ if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) {
+ MacMsgDisplayOn();
+ }
+
+#if EnableRecreateW
+ if (0
+#if EnableMagnify
+ || (UseMagnify != WantMagnify)
+#endif
+#if VarFullScreen
+ || (UseFullScreen != WantFullScreen)
+#endif
+ )
+ {
+ (void) ReCreateMainWindow();
+ }
+#endif
+
+#if MayFullScreen
+ if (GrabMachine != (
+#if VarFullScreen
+ UseFullScreen &&
+#endif
+ ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ GrabMachine = ! GrabMachine;
+ if (GrabMachine) {
+ GrabTheMachine();
+ } else {
+ UngrabMachine();
+ }
+ }
+#endif
+
+ if (NeedWholeScreenDraw) {
+ NeedWholeScreenDraw = falseblnr;
+ ScreenChangedAll();
+ }
+
+#if NeedRequestIthDisk
+ if (0 != RequestIthDisk) {
+ Sony_InsertIth(RequestIthDisk);
+ RequestIthDisk = 0;
+ }
+#endif
+
+ if (HaveCursorHidden != (WantCursorHidden
+ && ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ HaveCursorHidden = ! HaveCursorHidden;
+ (void) SDL_ShowCursor(
+ HaveCursorHidden ? SDL_DISABLE : SDL_ENABLE);
+ }
+}
+
+/* --- command line parsing --- */
+
+LOCALFUNC blnr ScanCommandLine(void)
+{
+ char *pa;
+ int i = 1;
+
+label_retry:
+ if (i < my_argc) {
+ pa = my_argv[i++];
+ if ('-' == pa[0]) {
+ if ((0 == strcmp(pa, "--rom"))
+ || (0 == strcmp(pa, "-r")))
+ {
+ if (i < my_argc) {
+ rom_path = my_argv[i++];
+ goto label_retry;
+ }
+ } else
+ if (0 == strcmp(pa, "-n"))
+ {
+ if (i < my_argc) {
+ n_arg = my_argv[i++];
+ goto label_retry;
+ }
+ } else
+ if (0 == strcmp(pa, "-d"))
+ {
+ if (i < my_argc) {
+ d_arg = my_argv[i++];
+ goto label_retry;
+ }
+ } else
+ if (('p' == pa[1]) && ('s' == pa[2]) && ('n' == pa[3]))
+ {
+ /* seen in OS X. ignore */
+ goto label_retry;
+ } else
+ {
+ MacMsg(kStrBadArgTitle, kStrBadArgMessage, falseblnr);
+#if dbglog_HAVE
+ dbglog_writeln("bad command line argument");
+ dbglog_writeln(pa);
+#endif
+ }
+ } else {
+ (void) Sony_Insert1(pa, falseblnr);
+ goto label_retry;
+ }
+ }
+
+ return trueblnr;
+}
+
+/* --- main program flow --- */
+
+GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void)
+{
+ UpdateTrueEmulatedTime();
+ return TrueEmulatedTime == OnTrueTime;
+}
+
+LOCALPROC WaitForTheNextEvent(void)
+{
+ SDL_Event event;
+
+ if (SDL_WaitEvent(&event)) {
+ HandleTheEvent(&event);
+ }
+}
+
+LOCALPROC CheckForSystemEvents(void)
+{
+ SDL_Event event;
+ int i = 10;
+
+ while ((--i >= 0) && SDL_PollEvent(&event)) {
+ HandleTheEvent(&event);
+ }
+}
+
+GLOBALOSGLUPROC WaitForNextTick(void)
+{
+label_retry:
+ CheckForSystemEvents();
+ CheckForSavedTasks();
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (CurSpeedStopped) {
+ DoneWithDrawingForTick();
+ WaitForTheNextEvent();
+ goto label_retry;
+ }
+
+ if (ExtraTimeNotOver()) {
+ (void) SDL_Delay(NextIntTime - LastTime);
+ goto label_retry;
+ }
+
+ if (CheckDateTime()) {
+#if MySoundEnabled
+ MySound_SecondNotify();
+#endif
+#if EnableDemoMsg
+ DemoModeSecondNotify();
+#endif
+ }
+
+ if ((! gBackgroundFlag)
+#if UseMotionEvents
+ && (! CaughtMouse)
+#endif
+ )
+ {
+ CheckMouseState();
+ }
+
+ OnTrueTime = TrueEmulatedTime;
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("WaitForNextTick, OnTrueTime", OnTrueTime);
+#endif
+}
+
+/* --- platform independent code can be thought of as going here --- */
+
+#include "PROGMAIN.h"
+
+LOCALPROC ZapOSGLUVars(void)
+{
+ InitDrives();
+ ZapWinStateVars();
+}
+
+LOCALPROC ReserveAllocAll(void)
+{
+#if dbglog_HAVE
+ dbglog_ReserveAlloc();
+#endif
+ ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr);
+
+ ReserveAllocOneBlock(&screencomparebuff,
+ vMacScreenNumBytes, 5, trueblnr);
+#if UseControlKeys
+ ReserveAllocOneBlock(&CntrlDisplayBuff,
+ vMacScreenNumBytes, 5, falseblnr);
+#endif
+
+ ReserveAllocOneBlock(&CLUT_final, CLUT_finalsz, 5, falseblnr);
+#if MySoundEnabled
+ ReserveAllocOneBlock((ui3p *)&TheSoundBuffer,
+ dbhBufferSize, 5, falseblnr);
+#endif
+
+ EmulationReserveAlloc();
+}
+
+LOCALFUNC blnr AllocMyMemory(void)
+{
+ uimr n;
+ blnr IsOk = falseblnr;
+
+ ReserveAllocOffset = 0;
+ ReserveAllocBigBlock = nullpr;
+ ReserveAllocAll();
+ n = ReserveAllocOffset;
+ ReserveAllocBigBlock = (ui3p)calloc(1, n);
+ if (NULL == ReserveAllocBigBlock) {
+ MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr);
+ } else {
+ ReserveAllocOffset = 0;
+ ReserveAllocAll();
+ if (n != ReserveAllocOffset) {
+ /* oops, program error */
+ } else {
+ IsOk = trueblnr;
+ }
+ }
+
+ return IsOk;
+}
+
+LOCALPROC UnallocMyMemory(void)
+{
+ if (nullpr != ReserveAllocBigBlock) {
+ free((char *)ReserveAllocBigBlock);
+ }
+}
+
+#if CanGetAppPath
+LOCALFUNC blnr InitWhereAmI(void)
+{
+ app_parent = SDL_GetBasePath();
+
+ pref_dir = SDL_GetPrefPath("gryphel", "minivmac");
+
+ return trueblnr; /* keep going regardless */
+}
+#endif
+
+#if CanGetAppPath
+LOCALPROC UninitWhereAmI(void)
+{
+ SDL_free(pref_dir);
+
+ SDL_free(app_parent);
+}
+#endif
+
+LOCALFUNC blnr InitOSGLU(void)
+{
+ if (AllocMyMemory())
+#if CanGetAppPath
+ if (InitWhereAmI())
+#endif
+#if dbglog_HAVE
+ if (dbglog_open())
+#endif
+ if (ScanCommandLine())
+ if (LoadMacRom())
+ if (LoadInitialImages())
+ if (InitLocationDat())
+#if MySoundEnabled
+ if (MySound_Init())
+#endif
+ if (Screen_Init())
+ if (CreateMainWindow())
+ if (WaitForRom())
+ {
+ return trueblnr;
+ }
+ return falseblnr;
+}
+
+LOCALPROC UnInitOSGLU(void)
+{
+ if (MacMsgDisplayed) {
+ MacMsgDisplayOff();
+ }
+
+ RestoreKeyRepeat();
+#if MayFullScreen
+ UngrabMachine();
+#endif
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+#if MySoundEnabled
+ MySound_UnInit();
+#endif
+#if IncludePbufs
+ UnInitPbufs();
+#endif
+ UnInitDrives();
+
+ ForceShowCursor();
+
+#if dbglog_HAVE
+ dbglog_close();
+#endif
+
+#if CanGetAppPath
+ UninitWhereAmI();
+#endif
+ UnallocMyMemory();
+
+ CheckSavedMacMsg();
+
+ CloseMainWindow();
+
+ SDL_Quit();
+}
+
+int main(int argc, char **argv)
+{
+ my_argc = argc;
+ my_argv = argv;
+
+ ZapOSGLUVars();
+ if (InitOSGLU()) {
+ ProgramMain();
+ }
+ UnInitOSGLU();
+
+ return 0;
+}
--- /dev/null
+++ b/src/OSGLUSDL.c
@@ -1,0 +1,2324 @@
+/*
+ OSGLUSDL.c
+
+ Copyright (C) 2012 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Operating System GLUe for SDL library
+
+ All operating system dependent code for the
+ SDL Library should go here.
+*/
+
+#include "CNFGRAPI.h"
+#include "SYSDEPNS.h"
+#include "ENDIANAC.h"
+
+#include "MYOSGLUE.h"
+
+#include "STRCONST.h"
+
+/* --- some simple utilities --- */
+
+GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount)
+{
+ (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount);
+}
+
+/* --- control mode and internationalization --- */
+
+#define NeedCell2PlainAsciiMap 1
+
+#include "INTLCHAR.h"
+
+/* --- sending debugging info to file --- */
+
+#if dbglog_HAVE
+
+#define dbglog_ToStdErr 0
+
+#if ! dbglog_ToStdErr
+LOCALVAR FILE *dbglog_File = NULL;
+#endif
+
+LOCALFUNC blnr dbglog_open0(void)
+{
+#if dbglog_ToStdErr
+ return trueblnr;
+#else
+ dbglog_File = fopen("dbglog.txt", "w");
+ return (NULL != dbglog_File);
+#endif
+}
+
+LOCALPROC dbglog_write0(char *s, uimr L)
+{
+#if dbglog_ToStdErr
+ (void) fwrite(s, 1, L, stderr);
+#else
+ if (dbglog_File != NULL) {
+ (void) fwrite(s, 1, L, dbglog_File);
+ }
+#endif
+}
+
+LOCALPROC dbglog_close0(void)
+{
+#if ! dbglog_ToStdErr
+ if (dbglog_File != NULL) {
+ fclose(dbglog_File);
+ dbglog_File = NULL;
+ }
+#endif
+}
+
+#endif
+
+/* --- information about the environment --- */
+
+#define WantColorTransValid 0
+
+#include "COMOSGLU.h"
+
+#include "PBUFSTDC.h"
+
+#include "CONTROLM.h"
+
+/* --- text translation --- */
+
+LOCALPROC NativeStrFromCStr(char *r, char *s)
+{
+ ui3b ps[ClStrMaxLength];
+ int i;
+ int L;
+
+ ClStrFromSubstCStr(&L, ps, s);
+
+ for (i = 0; i < L; ++i) {
+ r[i] = Cell2PlainAsciiMap[ps[i]];
+ }
+
+ r[L] = 0;
+}
+
+/* --- drives --- */
+
+#define NotAfileRef NULL
+
+LOCALVAR FILE *Drives[NumDrives]; /* open disk image files */
+
+LOCALPROC InitDrives(void)
+{
+ /*
+ This isn't really needed, Drives[i] and DriveNames[i]
+ need not have valid values when not vSonyIsInserted[i].
+ */
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ Drives[i] = NotAfileRef;
+ }
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer,
+ tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
+ ui5r *Sony_ActCount)
+{
+ tMacErr err = mnvm_miscErr;
+ FILE *refnum = Drives[Drive_No];
+ ui5r NewSony_Count = 0;
+
+ if (0 == fseek(refnum, Sony_Start, SEEK_SET)) {
+ if (IsWrite) {
+ NewSony_Count = fwrite(Buffer, 1, Sony_Count, refnum);
+ } else {
+ NewSony_Count = fread(Buffer, 1, Sony_Count, refnum);
+ }
+
+ if (NewSony_Count == Sony_Count) {
+ err = mnvm_noErr;
+ }
+ }
+
+ if (nullpr != Sony_ActCount) {
+ *Sony_ActCount = NewSony_Count;
+ }
+
+ return err; /*& figure out what really to return &*/
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count)
+{
+ tMacErr err = mnvm_miscErr;
+ FILE *refnum = Drives[Drive_No];
+ long v;
+
+ if (0 == fseek(refnum, 0, SEEK_END)) {
+ v = ftell(refnum);
+ if (v >= 0) {
+ *Sony_Count = v;
+ err = mnvm_noErr;
+ }
+ }
+
+ return err; /*& figure out what really to return &*/
+}
+
+LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit)
+{
+ FILE *refnum = Drives[Drive_No];
+
+ DiskEjectedNotify(Drive_No);
+
+ fclose(refnum);
+ Drives[Drive_No] = NotAfileRef; /* not really needed */
+
+ return mnvm_noErr;
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No)
+{
+ return vSonyEject0(Drive_No, falseblnr);
+}
+
+LOCALPROC UnInitDrives(void)
+{
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ if (vSonyIsInserted(i)) {
+ (void) vSonyEject(i);
+ }
+ }
+}
+
+LOCALFUNC blnr Sony_Insert0(FILE *refnum, blnr locked,
+ char *drivepath)
+{
+ tDrive Drive_No;
+ blnr IsOk = falseblnr;
+
+ if (! FirstFreeDisk(&Drive_No)) {
+ MacMsg(kStrTooManyImagesTitle, kStrTooManyImagesMessage,
+ falseblnr);
+ } else {
+ /* printf("Sony_Insert0 %d\n", (int)Drive_No); */
+
+ {
+ Drives[Drive_No] = refnum;
+ DiskInsertNotify(Drive_No, locked);
+
+ IsOk = trueblnr;
+ }
+ }
+
+ if (! IsOk) {
+ fclose(refnum);
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr Sony_Insert1(char *drivepath, blnr silentfail)
+{
+ blnr locked = falseblnr;
+ /* printf("Sony_Insert1 %s\n", drivepath); */
+ FILE *refnum = fopen(drivepath, "rb+");
+ if (NULL == refnum) {
+ locked = trueblnr;
+ refnum = fopen(drivepath, "rb");
+ }
+ if (NULL == refnum) {
+ if (! silentfail) {
+ MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
+ }
+ } else {
+ return Sony_Insert0(refnum, locked, drivepath);
+ }
+ return falseblnr;
+}
+
+LOCALFUNC tMacErr LoadMacRomFrom(char *path)
+{
+ tMacErr err;
+ FILE *ROM_File;
+ int File_Size;
+
+ ROM_File = fopen(path, "rb");
+ if (NULL == ROM_File) {
+ err = mnvm_fnfErr;
+ } else {
+ File_Size = fread(ROM, 1, kROM_Size, ROM_File);
+ if (File_Size != kROM_Size) {
+ if (feof(ROM_File)) {
+ MacMsgOverride(kStrShortROMTitle,
+ kStrShortROMMessage);
+ err = mnvm_eofErr;
+ } else {
+ MacMsgOverride(kStrNoReadROMTitle,
+ kStrNoReadROMMessage);
+ err = mnvm_miscErr;
+ }
+ } else {
+ err = ROM_IsValid();
+ }
+ fclose(ROM_File);
+ }
+
+ return err;
+}
+
+#if 0 /* no drag and drop to make use of this */
+LOCALFUNC blnr Sony_Insert1a(char *drivepath, blnr silentfail)
+{
+ blnr v;
+
+ if (! ROM_loaded) {
+ v = (mnvm_noErr == LoadMacRomFrom(drivepath));
+ } else {
+ v = Sony_Insert1(drivepath, silentfail);
+ }
+
+ return v;
+}
+#endif
+
+LOCALFUNC blnr Sony_Insert2(char *s)
+{
+ return Sony_Insert1(s, trueblnr);
+}
+
+LOCALFUNC blnr Sony_InsertIth(int i)
+{
+ blnr v;
+
+ if ((i > 9) || ! FirstFreeDisk(nullpr)) {
+ v = falseblnr;
+ } else {
+ char s[] = "disk?.dsk";
+
+ s[4] = '0' + i;
+
+ v = Sony_Insert2(s);
+ }
+
+ return v;
+}
+
+LOCALFUNC blnr LoadInitialImages(void)
+{
+ if (! AnyDiskInserted()) {
+ int i;
+
+ for (i = 1; Sony_InsertIth(i); ++i) {
+ /* stop on first error (including file not found) */
+ }
+ }
+
+ return trueblnr;
+}
+
+/* --- ROM --- */
+
+LOCALVAR char *rom_path = NULL;
+
+LOCALFUNC blnr LoadMacRom(void)
+{
+ tMacErr err;
+
+ if ((NULL == rom_path)
+ || (mnvm_fnfErr == (err = LoadMacRomFrom(rom_path))))
+ if (mnvm_fnfErr == (err = LoadMacRomFrom(RomFileName)))
+ {
+ }
+
+ return trueblnr; /* keep launching Mini vMac, regardless */
+}
+
+/* --- video out --- */
+
+#if VarFullScreen
+LOCALVAR blnr UseFullScreen = (WantInitFullScreen != 0);
+#endif
+
+#if EnableMagnify
+LOCALVAR blnr UseMagnify = (WantInitMagnify != 0);
+#endif
+
+LOCALVAR blnr gBackgroundFlag = falseblnr;
+LOCALVAR blnr gTrueBackgroundFlag = falseblnr;
+LOCALVAR blnr CurSpeedStopped = trueblnr;
+
+#if EnableMagnify
+#define MaxScale MyWindowScale
+#else
+#define MaxScale 1
+#endif
+
+
+LOCALVAR SDL_Surface *my_surface = nullpr;
+
+LOCALVAR ui3p ScalingBuff = nullpr;
+
+LOCALVAR ui3p CLUT_final;
+
+#define CLUT_finalsz (256 * 8 * 4 * MaxScale)
+ /*
+ 256 possible values of one byte
+ 8 pixels per byte maximum (when black and white)
+ 4 bytes per destination pixel maximum
+ multiplied by MyWindowScale if EnableMagnify
+ */
+
+#define ScrnMapr_DoMap UpdateBWDepth3Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth4Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 4
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth5Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth3ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth4ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 4
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth5ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+
+#define ScrnMapr_DoMap UpdateColorDepth3Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth4Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 4
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth5Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth3ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth4ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 4
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth5ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#endif
+
+
+LOCALPROC HaveChangedScreenBuff(ui4r top, ui4r left,
+ ui4r bottom, ui4r right)
+{
+ int i;
+ int j;
+ ui3b *p;
+ Uint32 pixel;
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ Uint32 CLUT_pixel[CLUT_size];
+#endif
+ Uint32 BWLUT_pixel[2];
+ ui5r top2 = top;
+ ui5r left2 = left;
+ ui5r bottom2 = bottom;
+ ui5r right2 = right;
+
+#if EnableMagnify
+ if (UseMagnify) {
+ top2 *= MyWindowScale;
+ left2 *= MyWindowScale;
+ bottom2 *= MyWindowScale;
+ right2 *= MyWindowScale;
+ }
+#endif
+
+ if (SDL_MUSTLOCK(my_surface)) {
+ if (SDL_LockSurface(my_surface) < 0) {
+ return;
+ }
+ }
+
+ {
+
+ int bpp = my_surface->format->BytesPerPixel;
+ ui5r ExpectedPitch = vMacScreenWidth * bpp;
+
+#if EnableMagnify
+ if (UseMagnify) {
+ ExpectedPitch *= MyWindowScale;
+ }
+#endif
+
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+#if vMacScreenDepth < 4
+ for (i = 0; i < CLUT_size; ++i) {
+ CLUT_pixel[i] = SDL_MapRGB(my_surface->format,
+ CLUT_reds[i] >> 8,
+ CLUT_greens[i] >> 8,
+ CLUT_blues[i] >> 8);
+ }
+#endif
+ } else
+#endif
+ {
+ BWLUT_pixel[1] = SDL_MapRGB(my_surface->format, 0, 0, 0);
+ /* black */
+ BWLUT_pixel[0] = SDL_MapRGB(my_surface->format, 255, 255, 255);
+ /* white */
+ }
+
+ if ((0 == ((bpp - 1) & bpp)) /* a power of 2 */
+ && (my_surface->pitch == ExpectedPitch)
+#if (vMacScreenDepth > 3)
+ && ! UseColorMode
+#endif
+ )
+ {
+ int k;
+ Uint32 v;
+#if EnableMagnify
+ int a;
+#endif
+ int PixPerByte =
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ UseColorMode ? (1 << (3 - vMacScreenDepth)) :
+#endif
+ 8;
+ Uint8 *p4 = (Uint8 *)CLUT_final;
+
+ for (i = 0; i < 256; ++i) {
+ for (k = PixPerByte; --k >= 0; ) {
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ if (UseColorMode) {
+ v = CLUT_pixel[
+#if 3 == vMacScreenDepth
+ i
+#else
+ (i >> (k << vMacScreenDepth))
+ & (CLUT_size - 1)
+#endif
+ ];
+ } else
+#endif
+ {
+ v = BWLUT_pixel[(i >> k) & 1];
+ }
+
+#if EnableMagnify
+ for (a = UseMagnify ? MyWindowScale : 1; --a >= 0; )
+#endif
+ {
+ switch (bpp) {
+ case 1: /* Assuming 8-bpp */
+ *p4++ = v;
+ break;
+ case 2: /* Probably 15-bpp or 16-bpp */
+ *(Uint16 *)p4 = v;
+ p4 += 2;
+ break;
+ case 4: /* Probably 32-bpp */
+ *(Uint32 *)p4 = v;
+ p4 += 4;
+ break;
+ }
+ }
+ }
+ }
+
+ ScalingBuff = (ui3p)my_surface->pixels;
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ if (UseColorMode) {
+#if EnableMagnify
+ if (UseMagnify) {
+ switch (bpp) {
+ case 1:
+ UpdateColorDepth3ScaledCopy(
+ top, left, bottom, right);
+ break;
+ case 2:
+ UpdateColorDepth4ScaledCopy(
+ top, left, bottom, right);
+ break;
+ case 4:
+ UpdateColorDepth5ScaledCopy(
+ top, left, bottom, right);
+ break;
+ }
+ } else
+#endif
+ {
+ switch (bpp) {
+ case 1:
+ UpdateColorDepth3Copy(top, left, bottom, right);
+ break;
+ case 2:
+ UpdateColorDepth4Copy(top, left, bottom, right);
+ break;
+ case 4:
+ UpdateColorDepth5Copy(top, left, bottom, right);
+ break;
+ }
+ }
+ } else
+#endif
+ {
+#if EnableMagnify
+ if (UseMagnify) {
+ switch (bpp) {
+ case 1:
+ UpdateBWDepth3ScaledCopy(
+ top, left, bottom, right);
+ break;
+ case 2:
+ UpdateBWDepth4ScaledCopy(
+ top, left, bottom, right);
+ break;
+ case 4:
+ UpdateBWDepth5ScaledCopy(
+ top, left, bottom, right);
+ break;
+ }
+ } else
+#endif
+ {
+ switch (bpp) {
+ case 1:
+ UpdateBWDepth3Copy(top, left, bottom, right);
+ break;
+ case 2:
+ UpdateBWDepth4Copy(top, left, bottom, right);
+ break;
+ case 4:
+ UpdateBWDepth5Copy(top, left, bottom, right);
+ break;
+ }
+ }
+ }
+
+ } else {
+ ui3b *the_data = (ui3b *)GetCurDrawBuff();
+
+ /* adapted from putpixel in SDL documentation */
+
+ for (i = top2; i < bottom2; ++i) {
+ for (j = left2; j < right2; ++j) {
+ int i0 = i;
+ int j0 = j;
+ Uint8 *bufp = (Uint8 *)my_surface->pixels
+ + i * my_surface->pitch + j * bpp;
+
+#if EnableMagnify
+ if (UseMagnify) {
+ i0 /= MyWindowScale;
+ j0 /= MyWindowScale;
+ }
+#endif
+
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+#if vMacScreenDepth < 4
+ p = the_data + ((i0 * vMacScreenWidth + j0)
+ >> (3 - vMacScreenDepth));
+ {
+ ui3r k = (*p >> (((~ j0)
+ & ((1 << (3 - vMacScreenDepth)) - 1))
+ << vMacScreenDepth))
+ & (CLUT_size - 1);
+ pixel = CLUT_pixel[k];
+ }
+#elif 4 == vMacScreenDepth
+ p = the_data + ((i0 * vMacScreenWidth + j0) << 1);
+ {
+ ui4r t0 = do_get_mem_word(p);
+ pixel = SDL_MapRGB(my_surface->format,
+ ((t0 & 0x7C00) >> 7)
+ | ((t0 & 0x7000) >> 12),
+ ((t0 & 0x03E0) >> 2)
+ | ((t0 & 0x0380) >> 7),
+ ((t0 & 0x001F) << 3)
+ | ((t0 & 0x001C) >> 2));
+ }
+#elif 5 == vMacScreenDepth
+ p = the_data + ((i0 * vMacScreenWidth + j0) << 2);
+ pixel = SDL_MapRGB(my_surface->format,
+ p[1],
+ p[2],
+ p[3]);
+#endif
+ } else
+#endif
+ {
+ p = the_data + ((i0 * vMacScreenWidth + j0) / 8);
+ pixel = BWLUT_pixel[(*p >> ((~ j0) & 0x7)) & 1];
+ }
+
+ switch (bpp) {
+ case 1: /* Assuming 8-bpp */
+ *bufp = pixel;
+ break;
+ case 2: /* Probably 15-bpp or 16-bpp */
+ *(Uint16 *)bufp = pixel;
+ break;
+ case 3:
+ /* Slow 24-bpp mode, usually not used */
+ if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+ bufp[0] = (pixel >> 16) & 0xff;
+ bufp[1] = (pixel >> 8) & 0xff;
+ bufp[2] = pixel & 0xff;
+ } else {
+ bufp[0] = pixel & 0xff;
+ bufp[1] = (pixel >> 8) & 0xff;
+ bufp[2] = (pixel >> 16) & 0xff;
+ }
+ break;
+ case 4: /* Probably 32-bpp */
+ *(Uint32 *)bufp = pixel;
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ if (SDL_MUSTLOCK(my_surface)) {
+ SDL_UnlockSurface(my_surface);
+ }
+
+ SDL_UpdateRect(my_surface, left2, top2,
+ right2 - left2, bottom2 - top2);
+}
+
+LOCALPROC MyDrawChangesAndClear(void)
+{
+ if (ScreenChangedBottom > ScreenChangedTop) {
+ HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft,
+ ScreenChangedBottom, ScreenChangedRight);
+ ScreenClearChanges();
+ }
+}
+
+GLOBALOSGLUPROC DoneWithDrawingForTick(void)
+{
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ AutoScrollScreen();
+ }
+#endif
+ MyDrawChangesAndClear();
+}
+
+/* --- mouse --- */
+
+/* cursor hiding */
+
+LOCALVAR blnr HaveCursorHidden = falseblnr;
+LOCALVAR blnr WantCursorHidden = falseblnr;
+
+LOCALPROC ForceShowCursor(void)
+{
+ if (HaveCursorHidden) {
+ HaveCursorHidden = falseblnr;
+ (void) SDL_ShowCursor(SDL_ENABLE);
+ }
+}
+
+/* cursor moving */
+
+LOCALFUNC blnr MyMoveMouse(si4b h, si4b v)
+{
+#if EnableMagnify
+ if (UseMagnify) {
+ h *= MyWindowScale;
+ v *= MyWindowScale;
+ }
+#endif
+
+ SDL_WarpMouse(h, v);
+
+ return trueblnr;
+}
+
+/* cursor state */
+
+LOCALPROC MousePositionNotify(int NewMousePosh, int NewMousePosv)
+{
+ blnr ShouldHaveCursorHidden = trueblnr;
+
+#if EnableMagnify
+ if (UseMagnify) {
+ NewMousePosh /= MyWindowScale;
+ NewMousePosv /= MyWindowScale;
+ }
+#endif
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMousePositionSetDelta(NewMousePosh - SavedMouseH,
+ NewMousePosv - SavedMouseV);
+ SavedMouseH = NewMousePosh;
+ SavedMouseV = NewMousePosv;
+ } else
+#endif
+ {
+ if (NewMousePosh < 0) {
+ NewMousePosh = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosh >= vMacScreenWidth) {
+ NewMousePosh = vMacScreenWidth - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+ if (NewMousePosv < 0) {
+ NewMousePosv = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosv >= vMacScreenHeight) {
+ NewMousePosv = vMacScreenHeight - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ ShouldHaveCursorHidden = trueblnr;
+ }
+#endif
+
+ /* if (ShouldHaveCursorHidden || CurMouseButton) */
+ /*
+ for a game like arkanoid, would like mouse to still
+ move even when outside window in one direction
+ */
+ MyMousePositionSet(NewMousePosh, NewMousePosv);
+ }
+
+ WantCursorHidden = ShouldHaveCursorHidden;
+}
+
+LOCALPROC CheckMouseState(void)
+{
+ /*
+ this doesn't work as desired, doesn't get mouse movements
+ when outside of our window.
+ */
+ int x;
+ int y;
+
+ (void) SDL_GetMouseState(&x, &y);
+ MousePositionNotify(x, y);
+}
+
+/* --- keyboard input --- */
+
+LOCALFUNC ui3r SDLKey2MacKeyCode(SDLKey i)
+{
+ ui3r v = MKC_None;
+
+ switch (i) {
+ case SDLK_BACKSPACE: v = MKC_BackSpace; break;
+ case SDLK_TAB: v = MKC_Tab; break;
+ case SDLK_CLEAR: v = MKC_Clear; break;
+ case SDLK_RETURN: v = MKC_Return; break;
+ case SDLK_PAUSE: v = MKC_Pause; break;
+ case SDLK_ESCAPE: v = MKC_formac_Escape; break;
+ case SDLK_SPACE: v = MKC_Space; break;
+ case SDLK_EXCLAIM: /* ? */ break;
+ case SDLK_QUOTEDBL: /* ? */ break;
+ case SDLK_HASH: /* ? */ break;
+ case SDLK_DOLLAR: /* ? */ break;
+ case SDLK_AMPERSAND: /* ? */ break;
+ case SDLK_QUOTE: v = MKC_SingleQuote; break;
+ case SDLK_LEFTPAREN: /* ? */ break;
+ case SDLK_RIGHTPAREN: /* ? */ break;
+ case SDLK_ASTERISK: /* ? */ break;
+ case SDLK_PLUS: /* ? */ break;
+ case SDLK_COMMA: v = MKC_Comma; break;
+ case SDLK_MINUS: v = MKC_Minus; break;
+ case SDLK_PERIOD: v = MKC_Period; break;
+ case SDLK_SLASH: v = MKC_formac_Slash; break;
+ case SDLK_0: v = MKC_0; break;
+ case SDLK_1: v = MKC_1; break;
+ case SDLK_2: v = MKC_2; break;
+ case SDLK_3: v = MKC_3; break;
+ case SDLK_4: v = MKC_4; break;
+ case SDLK_5: v = MKC_5; break;
+ case SDLK_6: v = MKC_6; break;
+ case SDLK_7: v = MKC_7; break;
+ case SDLK_8: v = MKC_8; break;
+ case SDLK_9: v = MKC_9; break;
+ case SDLK_COLON: /* ? */ break;
+ case SDLK_SEMICOLON: v = MKC_SemiColon; break;
+ case SDLK_LESS: /* ? */ break;
+ case SDLK_EQUALS: v = MKC_Equal; break;
+ case SDLK_GREATER: /* ? */ break;
+ case SDLK_QUESTION: /* ? */ break;
+ case SDLK_AT: /* ? */ break;
+
+ case SDLK_LEFTBRACKET: v = MKC_LeftBracket; break;
+ case SDLK_BACKSLASH: v = MKC_formac_BackSlash; break;
+ case SDLK_RIGHTBRACKET: v = MKC_RightBracket; break;
+ case SDLK_CARET: /* ? */ break;
+ case SDLK_UNDERSCORE: /* ? */ break;
+ case SDLK_BACKQUOTE: v = MKC_formac_Grave; break;
+
+ case SDLK_a: v = MKC_A; break;
+ case SDLK_b: v = MKC_B; break;
+ case SDLK_c: v = MKC_C; break;
+ case SDLK_d: v = MKC_D; break;
+ case SDLK_e: v = MKC_E; break;
+ case SDLK_f: v = MKC_F; break;
+ case SDLK_g: v = MKC_G; break;
+ case SDLK_h: v = MKC_H; break;
+ case SDLK_i: v = MKC_I; break;
+ case SDLK_j: v = MKC_J; break;
+ case SDLK_k: v = MKC_K; break;
+ case SDLK_l: v = MKC_L; break;
+ case SDLK_m: v = MKC_M; break;
+ case SDLK_n: v = MKC_N; break;
+ case SDLK_o: v = MKC_O; break;
+ case SDLK_p: v = MKC_P; break;
+ case SDLK_q: v = MKC_Q; break;
+ case SDLK_r: v = MKC_R; break;
+ case SDLK_s: v = MKC_S; break;
+ case SDLK_t: v = MKC_T; break;
+ case SDLK_u: v = MKC_U; break;
+ case SDLK_v: v = MKC_V; break;
+ case SDLK_w: v = MKC_W; break;
+ case SDLK_x: v = MKC_X; break;
+ case SDLK_y: v = MKC_Y; break;
+ case SDLK_z: v = MKC_Z; break;
+
+ case SDLK_KP0: v = MKC_KP0; break;
+ case SDLK_KP1: v = MKC_KP1; break;
+ case SDLK_KP2: v = MKC_KP2; break;
+ case SDLK_KP3: v = MKC_KP3; break;
+ case SDLK_KP4: v = MKC_KP4; break;
+ case SDLK_KP5: v = MKC_KP5; break;
+ case SDLK_KP6: v = MKC_KP6; break;
+ case SDLK_KP7: v = MKC_KP7; break;
+ case SDLK_KP8: v = MKC_KP8; break;
+ case SDLK_KP9: v = MKC_KP9; break;
+
+ case SDLK_KP_PERIOD: v = MKC_Decimal; break;
+ case SDLK_KP_DIVIDE: v = MKC_KPDevide; break;
+ case SDLK_KP_MULTIPLY: v = MKC_KPMultiply; break;
+ case SDLK_KP_MINUS: v = MKC_KPSubtract; break;
+ case SDLK_KP_PLUS: v = MKC_KPAdd; break;
+ case SDLK_KP_ENTER: v = MKC_formac_Enter; break;
+ case SDLK_KP_EQUALS: v = MKC_KPEqual; break;
+
+ case SDLK_UP: v = MKC_Up; break;
+ case SDLK_DOWN: v = MKC_Down; break;
+ case SDLK_RIGHT: v = MKC_Right; break;
+ case SDLK_LEFT: v = MKC_Left; break;
+ case SDLK_INSERT: v = MKC_formac_Help; break;
+ case SDLK_HOME: v = MKC_formac_Home; break;
+ case SDLK_END: v = MKC_formac_End; break;
+ case SDLK_PAGEUP: v = MKC_formac_PageUp; break;
+ case SDLK_PAGEDOWN: v = MKC_formac_PageDown; break;
+
+ case SDLK_F1: v = MKC_formac_F1; break;
+ case SDLK_F2: v = MKC_formac_F2; break;
+ case SDLK_F3: v = MKC_formac_F3; break;
+ case SDLK_F4: v = MKC_formac_F4; break;
+ case SDLK_F5: v = MKC_formac_F5; break;
+ case SDLK_F6: v = MKC_F6; break;
+ case SDLK_F7: v = MKC_F7; break;
+ case SDLK_F8: v = MKC_F8; break;
+ case SDLK_F9: v = MKC_F9; break;
+ case SDLK_F10: v = MKC_F10; break;
+ case SDLK_F11: v = MKC_F11; break;
+ case SDLK_F12: v = MKC_F12; break;
+
+ case SDLK_F13: /* ? */ break;
+ case SDLK_F14: /* ? */ break;
+ case SDLK_F15: /* ? */ break;
+
+ case SDLK_NUMLOCK: v = MKC_formac_ForwardDel; break;
+ case SDLK_CAPSLOCK: v = MKC_formac_CapsLock; break;
+ case SDLK_SCROLLOCK: v = MKC_ScrollLock; break;
+ case SDLK_RSHIFT: v = MKC_formac_RShift; break;
+ case SDLK_LSHIFT: v = MKC_formac_Shift; break;
+ case SDLK_RCTRL: v = MKC_formac_RControl; break;
+ case SDLK_LCTRL: v = MKC_formac_Control; break;
+ case SDLK_RALT: v = MKC_formac_RCommand; break;
+ case SDLK_LALT: v = MKC_formac_Command; break;
+ case SDLK_RMETA: v = MKC_formac_RCommand; break;
+ case SDLK_LMETA: v = MKC_formac_Command; break;
+ case SDLK_LSUPER: v = MKC_formac_Option; break;
+ case SDLK_RSUPER: v = MKC_formac_ROption; break;
+
+ case SDLK_MODE: /* ? */ break;
+ case SDLK_COMPOSE: /* ? */ break;
+
+ case SDLK_HELP: v = MKC_formac_Help; break;
+ case SDLK_PRINT: v = MKC_Print; break;
+
+ case SDLK_SYSREQ: /* ? */ break;
+ case SDLK_BREAK: /* ? */ break;
+ case SDLK_MENU: /* ? */ break;
+ case SDLK_POWER: /* ? */ break;
+ case SDLK_EURO: /* ? */ break;
+ case SDLK_UNDO: /* ? */ break;
+
+ default:
+ break;
+ }
+
+ return v;
+}
+
+LOCALPROC DoKeyCode(SDL_keysym *r, blnr down)
+{
+ ui3r v = SDLKey2MacKeyCode(r->sym);
+ if (MKC_None != v) {
+ Keyboard_UpdateKeyMap2(v, down);
+ }
+}
+
+LOCALPROC DisableKeyRepeat(void)
+{
+}
+
+LOCALPROC RestoreKeyRepeat(void)
+{
+}
+
+LOCALPROC ReconnectKeyCodes3(void)
+{
+}
+
+LOCALPROC DisconnectKeyCodes3(void)
+{
+ DisconnectKeyCodes2();
+ MyMouseButtonSet(falseblnr);
+}
+
+/* --- time, date, location --- */
+
+#define dbglog_TimeStuff (0 && dbglog_HAVE)
+
+LOCALVAR ui5b TrueEmulatedTime = 0;
+
+#define MyInvTimeDivPow 16
+#define MyInvTimeDiv (1 << MyInvTimeDivPow)
+#define MyInvTimeDivMask (MyInvTimeDiv - 1)
+#define MyInvTimeStep 1089590 /* 1000 / 60.14742 * MyInvTimeDiv */
+
+LOCALVAR Uint32 LastTime;
+
+LOCALVAR Uint32 NextIntTime;
+LOCALVAR ui5b NextFracTime;
+
+LOCALPROC IncrNextTime(void)
+{
+ NextFracTime += MyInvTimeStep;
+ NextIntTime += (NextFracTime >> MyInvTimeDivPow);
+ NextFracTime &= MyInvTimeDivMask;
+}
+
+LOCALPROC InitNextTime(void)
+{
+ NextIntTime = LastTime;
+ NextFracTime = 0;
+ IncrNextTime();
+}
+
+LOCALVAR ui5b NewMacDateInSeconds;
+
+LOCALFUNC blnr UpdateTrueEmulatedTime(void)
+{
+ Uint32 LatestTime;
+ si5b TimeDiff;
+
+ LatestTime = SDL_GetTicks();
+ if (LatestTime != LastTime) {
+
+ NewMacDateInSeconds = LatestTime / 1000;
+ /* no date and time api in SDL */
+
+ LastTime = LatestTime;
+ TimeDiff = (LatestTime - NextIntTime);
+ /* this should work even when time wraps */
+ if (TimeDiff >= 0) {
+ if (TimeDiff > 256) {
+ /* emulation interrupted, forget it */
+ ++TrueEmulatedTime;
+ InitNextTime();
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("emulation interrupted",
+ TrueEmulatedTime);
+#endif
+ } else {
+ do {
+ ++TrueEmulatedTime;
+ IncrNextTime();
+ TimeDiff = (LatestTime - NextIntTime);
+ } while (TimeDiff >= 0);
+ }
+ return trueblnr;
+ } else {
+ if (TimeDiff < -256) {
+#if dbglog_TimeStuff
+ dbglog_writeln("clock set back");
+#endif
+ /* clock goofed if ever get here, reset */
+ InitNextTime();
+ }
+ }
+ }
+ return falseblnr;
+}
+
+
+LOCALFUNC blnr CheckDateTime(void)
+{
+ if (CurMacDateInSeconds != NewMacDateInSeconds) {
+ CurMacDateInSeconds = NewMacDateInSeconds;
+ return trueblnr;
+ } else {
+ return falseblnr;
+ }
+}
+
+LOCALPROC StartUpTimeAdjust(void)
+{
+ LastTime = SDL_GetTicks();
+ InitNextTime();
+}
+
+LOCALFUNC blnr InitLocationDat(void)
+{
+ LastTime = SDL_GetTicks();
+ InitNextTime();
+ NewMacDateInSeconds = LastTime / 1000;
+ CurMacDateInSeconds = NewMacDateInSeconds;
+
+ return trueblnr;
+}
+
+/* --- sound --- */
+
+#if MySoundEnabled
+
+#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */
+#define kSoundBuffers (1 << kLn2SoundBuffers)
+#define kSoundBuffMask (kSoundBuffers - 1)
+
+#define DesiredMinFilledSoundBuffs 3
+ /*
+ if too big then sound lags behind emulation.
+ if too small then sound will have pauses.
+ */
+
+#define kLnOneBuffLen 9
+#define kLnAllBuffLen (kLn2SoundBuffers + kLnOneBuffLen)
+#define kOneBuffLen (1UL << kLnOneBuffLen)
+#define kAllBuffLen (1UL << kLnAllBuffLen)
+#define kLnOneBuffSz (kLnOneBuffLen + kLn2SoundSampSz - 3)
+#define kLnAllBuffSz (kLnAllBuffLen + kLn2SoundSampSz - 3)
+#define kOneBuffSz (1UL << kLnOneBuffSz)
+#define kAllBuffSz (1UL << kLnAllBuffSz)
+#define kOneBuffMask (kOneBuffLen - 1)
+#define kAllBuffMask (kAllBuffLen - 1)
+#define dbhBufferSize (kAllBuffSz + kOneBuffSz)
+
+#define dbglog_SoundStuff (0 && dbglog_HAVE)
+#define dbglog_SoundBuffStats (0 && dbglog_HAVE)
+
+LOCALVAR tpSoundSamp TheSoundBuffer = nullpr;
+volatile static ui4b ThePlayOffset;
+volatile static ui4b TheFillOffset;
+volatile static ui4b MinFilledSoundBuffs;
+#if dbglog_SoundBuffStats
+LOCALVAR ui4b MaxFilledSoundBuffs;
+#endif
+LOCALVAR ui4b TheWriteOffset;
+
+LOCALPROC MySound_Init0(void)
+{
+ ThePlayOffset = 0;
+ TheFillOffset = 0;
+ TheWriteOffset = 0;
+}
+
+LOCALPROC MySound_Start0(void)
+{
+ /* Reset variables */
+ MinFilledSoundBuffs = kSoundBuffers + 1;
+#if dbglog_SoundBuffStats
+ MaxFilledSoundBuffs = 0;
+#endif
+}
+
+GLOBALOSGLUFUNC tpSoundSamp MySound_BeginWrite(ui4r n, ui4r *actL)
+{
+ ui4b ToFillLen = kAllBuffLen - (TheWriteOffset - ThePlayOffset);
+ ui4b WriteBuffContig =
+ kOneBuffLen - (TheWriteOffset & kOneBuffMask);
+
+ if (WriteBuffContig < n) {
+ n = WriteBuffContig;
+ }
+ if (ToFillLen < n) {
+ /* overwrite previous buffer */
+#if dbglog_SoundStuff
+ dbglog_writeln("sound buffer over flow");
+#endif
+ TheWriteOffset -= kOneBuffLen;
+ }
+
+ *actL = n;
+ return TheSoundBuffer + (TheWriteOffset & kAllBuffMask);
+}
+
+#if 4 == kLn2SoundSampSz
+LOCALPROC ConvertSoundBlockToNative(tpSoundSamp p)
+{
+ int i;
+
+ for (i = kOneBuffLen; --i >= 0; ) {
+ *p++ -= 0x8000;
+ }
+}
+#else
+#define ConvertSoundBlockToNative(p)
+#endif
+
+LOCALPROC MySound_WroteABlock(void)
+{
+#if (4 == kLn2SoundSampSz)
+ ui4b PrevWriteOffset = TheWriteOffset - kOneBuffLen;
+ tpSoundSamp p = TheSoundBuffer + (PrevWriteOffset & kAllBuffMask);
+#endif
+
+#if dbglog_SoundStuff
+ dbglog_writeln("enter MySound_WroteABlock");
+#endif
+
+ ConvertSoundBlockToNative(p);
+
+ TheFillOffset = TheWriteOffset;
+
+#if dbglog_SoundBuffStats
+ {
+ ui4b ToPlayLen = TheFillOffset
+ - ThePlayOffset;
+ ui4b ToPlayBuffs = ToPlayLen >> kLnOneBuffLen;
+
+ if (ToPlayBuffs > MaxFilledSoundBuffs) {
+ MaxFilledSoundBuffs = ToPlayBuffs;
+ }
+ }
+#endif
+}
+
+LOCALFUNC blnr MySound_EndWrite0(ui4r actL)
+{
+ blnr v;
+
+ TheWriteOffset += actL;
+
+ if (0 != (TheWriteOffset & kOneBuffMask)) {
+ v = falseblnr;
+ } else {
+ /* just finished a block */
+
+ MySound_WroteABlock();
+
+ v = trueblnr;
+ }
+
+ return v;
+}
+
+LOCALPROC MySound_SecondNotify0(void)
+{
+ if (MinFilledSoundBuffs <= kSoundBuffers) {
+ if (MinFilledSoundBuffs > DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too high");
+#endif
+ IncrNextTime();
+ } else if (MinFilledSoundBuffs < DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too low");
+#endif
+ ++TrueEmulatedTime;
+ }
+#if dbglog_SoundBuffStats
+ dbglog_writelnNum("MinFilledSoundBuffs",
+ MinFilledSoundBuffs);
+ dbglog_writelnNum("MaxFilledSoundBuffs",
+ MaxFilledSoundBuffs);
+ MaxFilledSoundBuffs = 0;
+#endif
+ MinFilledSoundBuffs = kSoundBuffers + 1;
+ }
+}
+
+typedef ui4r trSoundTemp;
+
+#define kCenterTempSound 0x8000
+
+#define AudioStepVal 0x0040
+
+#if 3 == kLn2SoundSampSz
+#define ConvertTempSoundSampleFromNative(v) ((v) << 8)
+#elif 4 == kLn2SoundSampSz
+#define ConvertTempSoundSampleFromNative(v) ((v) + kCenterSound)
+#else
+#error "unsupported kLn2SoundSampSz"
+#endif
+
+#if 3 == kLn2SoundSampSz
+#define ConvertTempSoundSampleToNative(v) ((v) >> 8)
+#elif 4 == kLn2SoundSampSz
+#define ConvertTempSoundSampleToNative(v) ((v) - kCenterSound)
+#else
+#error "unsupported kLn2SoundSampSz"
+#endif
+
+LOCALPROC SoundRampTo(trSoundTemp *last_val, trSoundTemp dst_val,
+ tpSoundSamp *stream, int *len)
+{
+ trSoundTemp diff;
+ tpSoundSamp p = *stream;
+ int n = *len;
+ trSoundTemp v1 = *last_val;
+
+ while ((v1 != dst_val) && (0 != n)) {
+ if (v1 > dst_val) {
+ diff = v1 - dst_val;
+ if (diff > AudioStepVal) {
+ v1 -= AudioStepVal;
+ } else {
+ v1 = dst_val;
+ }
+ } else {
+ diff = dst_val - v1;
+ if (diff > AudioStepVal) {
+ v1 += AudioStepVal;
+ } else {
+ v1 = dst_val;
+ }
+ }
+
+ --n;
+ *p++ = ConvertTempSoundSampleToNative(v1);
+ }
+
+ *stream = p;
+ *len = n;
+ *last_val = v1;
+}
+
+struct MySoundR {
+ tpSoundSamp fTheSoundBuffer;
+ volatile ui4b (*fPlayOffset);
+ volatile ui4b (*fFillOffset);
+ volatile ui4b (*fMinFilledSoundBuffs);
+
+ volatile trSoundTemp lastv;
+
+ blnr wantplaying;
+ blnr HaveStartedPlaying;
+};
+typedef struct MySoundR MySoundR;
+
+static void my_audio_callback(void *udata, Uint8 *stream, int len)
+{
+ ui4b ToPlayLen;
+ ui4b FilledSoundBuffs;
+ int i;
+ MySoundR *datp = (MySoundR *)udata;
+ tpSoundSamp CurSoundBuffer = datp->fTheSoundBuffer;
+ ui4b CurPlayOffset = *datp->fPlayOffset;
+ trSoundTemp v0 = datp->lastv;
+ trSoundTemp v1 = v0;
+ tpSoundSamp dst = (tpSoundSamp)stream;
+
+#if kLn2SoundSampSz > 3
+ len >>= (kLn2SoundSampSz - 3);
+#endif
+
+#if dbglog_SoundStuff
+ dbglog_writeln("Enter my_audio_callback");
+ dbglog_writelnNum("len", len);
+#endif
+
+label_retry:
+ ToPlayLen = *datp->fFillOffset - CurPlayOffset;
+ FilledSoundBuffs = ToPlayLen >> kLnOneBuffLen;
+
+ if (! datp->wantplaying) {
+#if dbglog_SoundStuff
+ dbglog_writeln("playing end transistion");
+#endif
+
+ SoundRampTo(&v1, kCenterTempSound, &dst, &len);
+
+ ToPlayLen = 0;
+ } else if (! datp->HaveStartedPlaying) {
+#if dbglog_SoundStuff
+ dbglog_writeln("playing start block");
+#endif
+
+ if ((ToPlayLen >> kLnOneBuffLen) < 8) {
+ ToPlayLen = 0;
+ } else {
+ tpSoundSamp p = datp->fTheSoundBuffer
+ + (CurPlayOffset & kAllBuffMask);
+ trSoundTemp v2 = ConvertTempSoundSampleFromNative(*p);
+
+#if dbglog_SoundStuff
+ dbglog_writeln("have enough samples to start");
+#endif
+
+ SoundRampTo(&v1, v2, &dst, &len);
+
+ if (v1 == v2) {
+#if dbglog_SoundStuff
+ dbglog_writeln("finished start transition");
+#endif
+
+ datp->HaveStartedPlaying = trueblnr;
+ }
+ }
+ }
+
+ if (0 == len) {
+ /* done */
+
+ if (FilledSoundBuffs < *datp->fMinFilledSoundBuffs) {
+ *datp->fMinFilledSoundBuffs = FilledSoundBuffs;
+ }
+ } else if (0 == ToPlayLen) {
+
+#if dbglog_SoundStuff
+ dbglog_writeln("under run");
+#endif
+
+ for (i = 0; i < len; ++i) {
+ *dst++ = ConvertTempSoundSampleToNative(v1);
+ }
+ *datp->fMinFilledSoundBuffs = 0;
+ } else {
+ ui4b PlayBuffContig = kAllBuffLen
+ - (CurPlayOffset & kAllBuffMask);
+ tpSoundSamp p = CurSoundBuffer
+ + (CurPlayOffset & kAllBuffMask);
+
+ if (ToPlayLen > PlayBuffContig) {
+ ToPlayLen = PlayBuffContig;
+ }
+ if (ToPlayLen > len) {
+ ToPlayLen = len;
+ }
+
+ for (i = 0; i < ToPlayLen; ++i) {
+ *dst++ = *p++;
+ }
+ v1 = ConvertTempSoundSampleFromNative(p[-1]);
+
+ CurPlayOffset += ToPlayLen;
+ len -= ToPlayLen;
+
+ *datp->fPlayOffset = CurPlayOffset;
+
+ goto label_retry;
+ }
+
+ datp->lastv = v1;
+}
+
+LOCALVAR MySoundR cur_audio;
+
+LOCALVAR blnr HaveSoundOut = falseblnr;
+
+LOCALPROC MySound_Stop(void)
+{
+#if dbglog_SoundStuff
+ dbglog_writeln("enter MySound_Stop");
+#endif
+
+ if (cur_audio.wantplaying && HaveSoundOut) {
+ ui4r retry_limit = 50; /* half of a second */
+
+ cur_audio.wantplaying = falseblnr;
+
+label_retry:
+ if (kCenterTempSound == cur_audio.lastv) {
+#if dbglog_SoundStuff
+ dbglog_writeln("reached kCenterTempSound");
+#endif
+
+ /* done */
+ } else if (0 == --retry_limit) {
+#if dbglog_SoundStuff
+ dbglog_writeln("retry limit reached");
+#endif
+ /* done */
+ } else
+ {
+ /*
+ give time back, particularly important
+ if got here on a suspend event.
+ */
+
+#if dbglog_SoundStuff
+ dbglog_writeln("busy, so sleep");
+#endif
+
+ (void) SDL_Delay(10);
+
+ goto label_retry;
+ }
+
+ SDL_PauseAudio(1);
+ }
+
+#if dbglog_SoundStuff
+ dbglog_writeln("leave MySound_Stop");
+#endif
+}
+
+LOCALPROC MySound_Start(void)
+{
+ if ((! cur_audio.wantplaying) && HaveSoundOut) {
+ MySound_Start0();
+ cur_audio.lastv = kCenterTempSound;
+ cur_audio.HaveStartedPlaying = falseblnr;
+ cur_audio.wantplaying = trueblnr;
+
+ SDL_PauseAudio(0);
+ }
+}
+
+LOCALPROC MySound_UnInit(void)
+{
+ if (HaveSoundOut) {
+ SDL_CloseAudio();
+ }
+}
+
+#define SOUND_SAMPLERATE 22255 /* = round(7833600 * 2 / 704) */
+
+LOCALFUNC blnr MySound_Init(void)
+{
+ SDL_AudioSpec desired;
+
+ MySound_Init0();
+
+ cur_audio.fTheSoundBuffer = TheSoundBuffer;
+ cur_audio.fPlayOffset = &ThePlayOffset;
+ cur_audio.fFillOffset = &TheFillOffset;
+ cur_audio.fMinFilledSoundBuffs = &MinFilledSoundBuffs;
+ cur_audio.wantplaying = falseblnr;
+
+ desired.freq = SOUND_SAMPLERATE;
+
+#if 3 == kLn2SoundSampSz
+ desired.format = AUDIO_U8;
+#elif 4 == kLn2SoundSampSz
+ desired.format = AUDIO_S16SYS;
+#else
+#error "unsupported audio format"
+#endif
+
+ desired.channels = 1;
+ desired.samples = 1024;
+ desired.callback = my_audio_callback;
+ desired.userdata = (void *)&cur_audio;
+
+ /* Open the audio device */
+ if (SDL_OpenAudio(&desired, NULL) < 0) {
+ fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
+ } else {
+ HaveSoundOut = trueblnr;
+
+ MySound_Start();
+ /*
+ This should be taken care of by LeaveSpeedStopped,
+ but since takes a while to get going properly,
+ start early.
+ */
+ }
+
+ return trueblnr; /* keep going, even if no sound */
+}
+
+GLOBALOSGLUPROC MySound_EndWrite(ui4r actL)
+{
+ if (MySound_EndWrite0(actL)) {
+ }
+}
+
+LOCALPROC MySound_SecondNotify(void)
+{
+ if (HaveSoundOut) {
+ MySound_SecondNotify0();
+ }
+}
+
+#endif
+
+/* --- basic dialogs --- */
+
+LOCALPROC CheckSavedMacMsg(void)
+{
+ /* called only on quit, if error saved but not yet reported */
+
+ if (nullpr != SavedBriefMsg) {
+ char briefMsg0[ClStrMaxLength + 1];
+ char longMsg0[ClStrMaxLength + 1];
+
+ NativeStrFromCStr(briefMsg0, SavedBriefMsg);
+ NativeStrFromCStr(longMsg0, SavedLongMsg);
+
+ fprintf(stderr, "%s\n", briefMsg0);
+ fprintf(stderr, "%s\n", longMsg0);
+
+ SavedBriefMsg = nullpr;
+ }
+}
+
+/* --- clipboard --- */
+
+#define UseMotionEvents 1
+
+#if UseMotionEvents
+LOCALVAR blnr CaughtMouse = falseblnr;
+#endif
+
+/* --- event handling for main window --- */
+
+LOCALPROC HandleTheEvent(SDL_Event *event)
+{
+ switch (event->type) {
+ case SDL_QUIT:
+ RequestMacOff = trueblnr;
+ break;
+ case SDL_ACTIVEEVENT:
+ switch (event->active.state) {
+ case SDL_APPINPUTFOCUS:
+ gTrueBackgroundFlag = (0 == event->active.gain);
+#if 0 && UseMotionEvents
+ if (! gTrueBackgroundFlag) {
+ CheckMouseState();
+ }
+#endif
+ break;
+ case SDL_APPMOUSEFOCUS:
+ CaughtMouse = (0 != event->active.gain);
+ break;
+ }
+ break;
+ case SDL_MOUSEMOTION:
+ MousePositionNotify(
+ event->motion.x, event->motion.y);
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ /* any mouse button, we don't care which */
+ MousePositionNotify(
+ event->button.x, event->button.y);
+ MyMouseButtonSet(trueblnr);
+ break;
+ case SDL_MOUSEBUTTONUP:
+ MousePositionNotify(
+ event->button.x, event->button.y);
+ MyMouseButtonSet(falseblnr);
+ break;
+ case SDL_KEYDOWN:
+ DoKeyCode(&event->key.keysym, trueblnr);
+ break;
+ case SDL_KEYUP:
+ DoKeyCode(&event->key.keysym, falseblnr);
+ break;
+#if 0
+ case Expose: /* SDL doesn't have an expose event */
+ int x0 = event->expose.x;
+ int y0 = event->expose.y;
+ int x1 = x0 + event->expose.width;
+ int y1 = y0 + event->expose.height;
+
+ if (x0 < 0) {
+ x0 = 0;
+ }
+ if (x1 > vMacScreenWidth) {
+ x1 = vMacScreenWidth;
+ }
+ if (y0 < 0) {
+ y0 = 0;
+ }
+ if (y1 > vMacScreenHeight) {
+ y1 = vMacScreenHeight;
+ }
+ if ((x0 < x1) && (y0 < y1)) {
+ HaveChangedScreenBuff(y0, x0, y1, x1);
+ }
+ break;
+#endif
+ }
+}
+
+/* --- main window creation and disposal --- */
+
+LOCALVAR int my_argc;
+LOCALVAR char **my_argv;
+
+LOCALFUNC blnr Screen_Init(void)
+{
+ blnr v = falseblnr;
+
+ InitKeyCodes();
+
+ if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
+ {
+ fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
+ } else {
+ SDL_WM_SetCaption(kStrAppName, NULL);
+ v = trueblnr;
+ }
+
+ return v;
+}
+
+#if MayFullScreen
+LOCALVAR blnr GrabMachine = falseblnr;
+#endif
+
+#if MayFullScreen
+LOCALPROC GrabTheMachine(void)
+{
+#if GrabKeysFullScreen
+ (void) SDL_WM_GrabInput(SDL_GRAB_ON);
+#endif
+
+#if EnableFSMouseMotion
+ /*
+ if magnification changes, need to reset,
+ even if HaveMouseMotion already true
+ */
+ if (MyMoveMouse(ViewHStart + (ViewHSize / 2),
+ ViewVStart + (ViewVSize / 2)))
+ {
+ SavedMouseH = ViewHStart + (ViewHSize / 2);
+ SavedMouseV = ViewVStart + (ViewVSize / 2);
+ HaveMouseMotion = trueblnr;
+ }
+#endif
+}
+#endif
+
+#if MayFullScreen
+LOCALPROC UngrabMachine(void)
+{
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ HaveMouseMotion = falseblnr;
+ }
+#endif
+
+#if GrabKeysFullScreen
+ (void) SDL_WM_GrabInput(SDL_GRAB_OFF);
+#endif
+}
+#endif
+
+#if EnableFSMouseMotion
+LOCALPROC MyMouseConstrain(void)
+{
+ si4b shiftdh;
+ si4b shiftdv;
+
+ if (SavedMouseH < ViewHStart + (ViewHSize / 4)) {
+ shiftdh = ViewHSize / 2;
+ } else if (SavedMouseH > ViewHStart + ViewHSize - (ViewHSize / 4)) {
+ shiftdh = - ViewHSize / 2;
+ } else {
+ shiftdh = 0;
+ }
+ if (SavedMouseV < ViewVStart + (ViewVSize / 4)) {
+ shiftdv = ViewVSize / 2;
+ } else if (SavedMouseV > ViewVStart + ViewVSize - (ViewVSize / 4)) {
+ shiftdv = - ViewVSize / 2;
+ } else {
+ shiftdv = 0;
+ }
+ if ((shiftdh != 0) || (shiftdv != 0)) {
+ SavedMouseH += shiftdh;
+ SavedMouseV += shiftdv;
+ if (! MyMoveMouse(SavedMouseH, SavedMouseV)) {
+ HaveMouseMotion = falseblnr;
+ }
+ }
+}
+#endif
+
+LOCALFUNC blnr CreateMainWindow(void)
+{
+ int NewWindowHeight = vMacScreenHeight;
+ int NewWindowWidth = vMacScreenWidth;
+ Uint32 flags = SDL_SWSURFACE;
+ blnr v = falseblnr;
+
+#if EnableMagnify && 1
+ if (UseMagnify) {
+ NewWindowHeight *= MyWindowScale;
+ NewWindowWidth *= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ flags |= SDL_FULLSCREEN;
+ }
+#endif
+
+ ViewHStart = 0;
+ ViewVStart = 0;
+ ViewHSize = vMacScreenWidth;
+ ViewVSize = vMacScreenHeight;
+
+ my_surface = SDL_SetVideoMode(NewWindowWidth, NewWindowHeight,
+#if 0 != vMacScreenDepth
+ 32,
+#else
+ /* 32 */ /* 24 */ /* 16 */ 8,
+#endif
+ flags);
+ if (NULL == my_surface) {
+ fprintf(stderr, "SDL_SetVideoMode fails: %s\n",
+ SDL_GetError());
+ } else {
+#if 0 != vMacScreenDepth
+ ColorModeWorks = trueblnr;
+#endif
+ v = trueblnr;
+ }
+
+ return v;
+}
+
+#if EnableRecreateW
+LOCALFUNC blnr ReCreateMainWindow(void)
+{
+ ForceShowCursor(); /* hide/show cursor api is per window */
+
+#if MayFullScreen
+ if (GrabMachine) {
+ GrabMachine = falseblnr;
+ UngrabMachine();
+ }
+#endif
+
+#if EnableMagnify
+ UseMagnify = WantMagnify;
+#endif
+#if VarFullScreen
+ UseFullScreen = WantFullScreen;
+#endif
+
+ (void) CreateMainWindow();
+
+ if (HaveCursorHidden) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ }
+
+ return trueblnr;
+}
+#endif
+
+LOCALPROC ZapWinStateVars(void)
+{
+}
+
+#if VarFullScreen
+LOCALPROC ToggleWantFullScreen(void)
+{
+ WantFullScreen = ! WantFullScreen;
+}
+#endif
+
+/* --- SavedTasks --- */
+
+LOCALPROC LeaveBackground(void)
+{
+ ReconnectKeyCodes3();
+ DisableKeyRepeat();
+}
+
+LOCALPROC EnterBackground(void)
+{
+ RestoreKeyRepeat();
+ DisconnectKeyCodes3();
+
+ ForceShowCursor();
+}
+
+LOCALPROC LeaveSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Start();
+#endif
+
+ StartUpTimeAdjust();
+}
+
+LOCALPROC EnterSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+}
+
+LOCALPROC CheckForSavedTasks(void)
+{
+ if (MyEvtQNeedRecover) {
+ MyEvtQNeedRecover = falseblnr;
+
+ /* attempt cleanup, MyEvtQNeedRecover may get set again */
+ MyEvtQTryRecoverFromFull();
+ }
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMouseConstrain();
+ }
+#endif
+
+ if (RequestMacOff) {
+ RequestMacOff = falseblnr;
+ if (AnyDiskInserted()) {
+ MacMsgOverride(kStrQuitWarningTitle,
+ kStrQuitWarningMessage);
+ } else {
+ ForceMacOff = trueblnr;
+ }
+ }
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (gTrueBackgroundFlag != gBackgroundFlag) {
+ gBackgroundFlag = gTrueBackgroundFlag;
+ if (gTrueBackgroundFlag) {
+ EnterBackground();
+ } else {
+ LeaveBackground();
+ }
+ }
+
+ if (CurSpeedStopped != (SpeedStopped ||
+ (gBackgroundFlag && ! RunInBackground
+#if EnableAutoSlow && 0
+ && (QuietSubTicks >= 4092)
+#endif
+ )))
+ {
+ CurSpeedStopped = ! CurSpeedStopped;
+ if (CurSpeedStopped) {
+ EnterSpeedStopped();
+ } else {
+ LeaveSpeedStopped();
+ }
+ }
+
+ if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) {
+ MacMsgDisplayOn();
+ }
+
+#if EnableRecreateW
+ if (0
+#if EnableMagnify
+ || (UseMagnify != WantMagnify)
+#endif
+#if VarFullScreen
+ || (UseFullScreen != WantFullScreen)
+#endif
+ )
+ {
+ (void) ReCreateMainWindow();
+ }
+#endif
+
+#if MayFullScreen
+ if (GrabMachine != (
+#if VarFullScreen
+ UseFullScreen &&
+#endif
+ ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ GrabMachine = ! GrabMachine;
+ if (GrabMachine) {
+ GrabTheMachine();
+ } else {
+ UngrabMachine();
+ }
+ }
+#endif
+
+ if (NeedWholeScreenDraw) {
+ NeedWholeScreenDraw = falseblnr;
+ ScreenChangedAll();
+ }
+
+#if NeedRequestIthDisk
+ if (0 != RequestIthDisk) {
+ Sony_InsertIth(RequestIthDisk);
+ RequestIthDisk = 0;
+ }
+#endif
+
+ if (HaveCursorHidden != (WantCursorHidden
+ && ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ HaveCursorHidden = ! HaveCursorHidden;
+ (void) SDL_ShowCursor(
+ HaveCursorHidden ? SDL_DISABLE : SDL_ENABLE);
+ }
+}
+
+/* --- command line parsing --- */
+
+LOCALFUNC blnr ScanCommandLine(void)
+{
+ char *pa;
+ int i = 1;
+
+label_retry:
+ if (i < my_argc) {
+ pa = my_argv[i++];
+ if ('-' == pa[0]) {
+ if ((0 == strcmp(pa, "--rom"))
+ || (0 == strcmp(pa, "-r")))
+ {
+ if (i < my_argc) {
+ rom_path = my_argv[i++];
+ goto label_retry;
+ }
+ } else
+ {
+ MacMsg(kStrBadArgTitle, kStrBadArgMessage, falseblnr);
+ }
+ } else {
+ (void) Sony_Insert1(pa, falseblnr);
+ goto label_retry;
+ }
+ }
+
+ return trueblnr;
+}
+
+/* --- main program flow --- */
+
+GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void)
+{
+ UpdateTrueEmulatedTime();
+ return TrueEmulatedTime == OnTrueTime;
+}
+
+LOCALPROC WaitForTheNextEvent(void)
+{
+ SDL_Event event;
+
+ if (SDL_WaitEvent(&event)) {
+ HandleTheEvent(&event);
+ }
+}
+
+LOCALPROC CheckForSystemEvents(void)
+{
+ SDL_Event event;
+ int i = 10;
+
+ while ((--i >= 0) && SDL_PollEvent(&event)) {
+ HandleTheEvent(&event);
+ }
+}
+
+GLOBALOSGLUPROC WaitForNextTick(void)
+{
+label_retry:
+ CheckForSystemEvents();
+ CheckForSavedTasks();
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (CurSpeedStopped) {
+ DoneWithDrawingForTick();
+ WaitForTheNextEvent();
+ goto label_retry;
+ }
+
+ if (ExtraTimeNotOver()) {
+ (void) SDL_Delay(NextIntTime - LastTime);
+ goto label_retry;
+ }
+
+ if (CheckDateTime()) {
+#if MySoundEnabled
+ MySound_SecondNotify();
+#endif
+#if EnableDemoMsg
+ DemoModeSecondNotify();
+#endif
+ }
+
+ if ((! gBackgroundFlag)
+#if UseMotionEvents
+ && (! CaughtMouse)
+#endif
+ )
+ {
+ CheckMouseState();
+ }
+
+ OnTrueTime = TrueEmulatedTime;
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("WaitForNextTick, OnTrueTime", OnTrueTime);
+#endif
+}
+
+/* --- platform independent code can be thought of as going here --- */
+
+#include "PROGMAIN.h"
+
+LOCALPROC ZapOSGLUVars(void)
+{
+ InitDrives();
+ ZapWinStateVars();
+}
+
+LOCALPROC ReserveAllocAll(void)
+{
+#if dbglog_HAVE
+ dbglog_ReserveAlloc();
+#endif
+ ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr);
+
+ ReserveAllocOneBlock(&screencomparebuff,
+ vMacScreenNumBytes, 5, trueblnr);
+#if UseControlKeys
+ ReserveAllocOneBlock(&CntrlDisplayBuff,
+ vMacScreenNumBytes, 5, falseblnr);
+#endif
+
+ ReserveAllocOneBlock(&CLUT_final, CLUT_finalsz, 5, falseblnr);
+#if MySoundEnabled
+ ReserveAllocOneBlock((ui3p *)&TheSoundBuffer,
+ dbhBufferSize, 5, falseblnr);
+#endif
+
+ EmulationReserveAlloc();
+}
+
+LOCALFUNC blnr AllocMyMemory(void)
+{
+ uimr n;
+ blnr IsOk = falseblnr;
+
+ ReserveAllocOffset = 0;
+ ReserveAllocBigBlock = nullpr;
+ ReserveAllocAll();
+ n = ReserveAllocOffset;
+ ReserveAllocBigBlock = (ui3p)calloc(1, n);
+ if (NULL == ReserveAllocBigBlock) {
+ MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr);
+ } else {
+ ReserveAllocOffset = 0;
+ ReserveAllocAll();
+ if (n != ReserveAllocOffset) {
+ /* oops, program error */
+ } else {
+ IsOk = trueblnr;
+ }
+ }
+
+ return IsOk;
+}
+
+LOCALPROC UnallocMyMemory(void)
+{
+ if (nullpr != ReserveAllocBigBlock) {
+ free((char *)ReserveAllocBigBlock);
+ }
+}
+
+LOCALFUNC blnr InitOSGLU(void)
+{
+ if (AllocMyMemory())
+#if dbglog_HAVE
+ if (dbglog_open())
+#endif
+ if (ScanCommandLine())
+ if (LoadMacRom())
+ if (LoadInitialImages())
+ if (InitLocationDat())
+#if MySoundEnabled
+ if (MySound_Init())
+#endif
+ if (Screen_Init())
+ if (CreateMainWindow())
+ if (WaitForRom())
+ {
+ return trueblnr;
+ }
+ return falseblnr;
+}
+
+LOCALPROC UnInitOSGLU(void)
+{
+ if (MacMsgDisplayed) {
+ MacMsgDisplayOff();
+ }
+
+ RestoreKeyRepeat();
+#if MayFullScreen
+ UngrabMachine();
+#endif
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+#if MySoundEnabled
+ MySound_UnInit();
+#endif
+#if IncludePbufs
+ UnInitPbufs();
+#endif
+ UnInitDrives();
+
+ ForceShowCursor();
+
+#if dbglog_HAVE
+ dbglog_close();
+#endif
+
+ UnallocMyMemory();
+
+ CheckSavedMacMsg();
+
+ SDL_Quit();
+}
+
+int main(int argc, char **argv)
+{
+ my_argc = argc;
+ my_argv = argv;
+
+ ZapOSGLUVars();
+ if (InitOSGLU()) {
+ ProgramMain();
+ }
+ UnInitOSGLU();
+
+ return 0;
+}
--- /dev/null
+++ b/src/OSGLUWIN.c
@@ -1,0 +1,6216 @@
+/*
+ OSGLUWIN.c
+
+ Copyright (C) 2009 Philip Cummins, Weston Pawlowski,
+ Bradford L. Barrett, Paul C. Pratt, Fabio Concas
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Operating System GLUe for microsoft WINdows
+
+ All operating system dependent code for the
+ Microsoft Windows platform should go here.
+
+ This code is descended from Weston Pawlowski's Windows
+ port of vMac, by Philip Cummins.
+ Adapted by Fabio Concas to run on Pocket PC 2003 devices.
+
+ The main entry point '_tWinMain' is at the end of this file.
+*/
+
+#include "CNFGRAPI.h"
+#include "SYSDEPNS.h"
+#include "ENDIANAC.h"
+
+#include "MYOSGLUE.h"
+
+
+/* --- adapting to API/ABI version differences --- */
+
+#ifdef UNICODE
+#define MyUseUni 1
+#else
+#define MyUseUni 0
+#endif
+
+#ifdef _WIN32_WCE
+#define UseWinCE 1
+#else
+#define UseWinCE 0
+#endif
+
+
+#define My_CSIDL_APPDATA 0x001a
+
+typedef BOOL (WINAPI *SHGetSpecialFolderPathProcPtr) (
+ HWND hwndOwner,
+ LPTSTR lpszPath,
+ int nFolder,
+ BOOL fCreate
+);
+LOCALVAR SHGetSpecialFolderPathProcPtr MySHGetSpecialFolderPath = NULL;
+LOCALVAR blnr DidSHGetSpecialFolderPath = falseblnr;
+
+LOCALFUNC blnr HaveMySHGetSpecialFolderPath(void)
+{
+ if (! DidSHGetSpecialFolderPath) {
+ HMODULE hLibModule = LoadLibrary(TEXT("shell32.dll"));
+ if (NULL != hLibModule) {
+ MySHGetSpecialFolderPath =
+ (SHGetSpecialFolderPathProcPtr)
+ GetProcAddress(hLibModule,
+#if MyUseUni
+ TEXT("SHGetSpecialFolderPathW")
+#else
+ TEXT("SHGetSpecialFolderPathA")
+#endif
+ );
+ /* FreeLibrary(hLibModule); */
+ }
+ DidSHGetSpecialFolderPath = trueblnr;
+ }
+ return (MySHGetSpecialFolderPath != NULL);
+}
+
+
+/* --- end of adapting to API/ABI version differences --- */
+
+#include "STRCONST.h"
+
+#if MyUseUni
+#define NeedCell2UnicodeMap 1
+#else
+#define NeedCell2WinAsciiMap 1
+#endif
+
+#include "INTLCHAR.h"
+
+
+LOCALPROC NativeStrFromCStr(LPTSTR r, char *s, blnr AddEllipsis)
+{
+ ui3b ps[ClStrMaxLength];
+ int i;
+ int L;
+
+ ClStrFromSubstCStr(&L, ps, s);
+
+ for (i = 0; i < L; ++i) {
+ r[i] = (TCHAR)
+#if MyUseUni
+ Cell2UnicodeMap[ps[i]];
+#else
+ Cell2WinAsciiMap[ps[i]];
+#endif
+ }
+
+ if (AddEllipsis) {
+#if MyUseUni
+ r[L] = 0x2026;
+ ++L;
+#else
+ r[L] = '.';
+ ++L;
+ r[L] = '.';
+ ++L;
+ r[L] = '.';
+ ++L;
+#endif
+ }
+
+ r[L] = 0;
+}
+
+LOCALFUNC LPTSTR FindLastTerm(LPTSTR s, TCHAR delim)
+{
+ TCHAR c;
+ LPTSTR p0 = s;
+ LPTSTR p = (LPTSTR)nullpr;
+
+ while ((c = *p0++) != (TCHAR)('\0')) {
+ if (c == delim) {
+ p = p0;
+ }
+ }
+
+ return p;
+}
+
+LOCALVAR HINSTANCE AppInstance;
+
+LOCALFUNC blnr GetAppDir(LPTSTR pathName)
+/* be sure at least _MAX_PATH long! */
+{
+ if (GetModuleFileName(AppInstance, pathName, _MAX_PATH) == 0) {
+ /* MacMsg("error", "GetModuleFileName failed", falseblnr); */
+ } else {
+ LPTSTR p = FindLastTerm(pathName,
+ (TCHAR)('\\'));
+ if (p == nullpr) {
+ /* MacMsg("error", "strrchr failed", falseblnr); */
+ } else {
+ *--p = (TCHAR)('\0');
+ return trueblnr;
+ }
+ }
+ return falseblnr;
+}
+
+/* --- sending debugging info to file --- */
+
+#if dbglog_HAVE
+
+LOCALVAR HANDLE dbglog_File = INVALID_HANDLE_VALUE;
+
+LOCALFUNC blnr dbglog_open0(void)
+{
+ TCHAR pathName[_MAX_PATH];
+ TCHAR Child0[] = TEXT("\\dbglog.txt");
+ size_t newlen;
+
+ if (GetAppDir(pathName)) {
+ newlen = _tcslen(pathName) + _tcslen(Child0);
+ if (newlen + 1 < _MAX_PATH) {
+ _tcscat(pathName, Child0);
+
+ dbglog_File = CreateFile(
+ pathName, /* pointer to name of the file */
+ GENERIC_READ + GENERIC_WRITE,
+ /* access (read-write) mode */
+ 0, /* share mode */
+ NULL, /* pointer to security descriptor */
+ OPEN_ALWAYS, /* how to create */
+ FILE_ATTRIBUTE_NORMAL, /* file attributes */
+ NULL /* handle to file with attributes to copy */
+ );
+ if (INVALID_HANDLE_VALUE == dbglog_File) {
+ /* report error (how?) */
+ } else if (SetFilePointer(
+ dbglog_File, /* handle of file */
+ 0, /* number of bytes to move file pointer */
+ nullpr,
+ /* address of high-order word of distance to move */
+ FILE_BEGIN /* how to move */
+ ) != 0)
+ {
+ /* report error (how?) */
+ }
+ }
+ }
+
+ return (INVALID_HANDLE_VALUE != dbglog_File);
+}
+
+LOCALPROC dbglog_write0(char *s, uimr L)
+{
+ DWORD BytesWritten;
+
+ if (INVALID_HANDLE_VALUE != dbglog_File) {
+ if (! WriteFile(dbglog_File, /* handle of file to read */
+ (LPVOID)s, /* address of buffer that receives data */
+ (DWORD)L, /* number of bytes to read */
+ &BytesWritten, /* address of number of bytes read */
+ nullpr) /* address of structure for data */
+ || ((ui5b)BytesWritten != L))
+ {
+ /* report error (how?) */
+ }
+ }
+}
+
+LOCALPROC dbglog_close0(void)
+{
+ if (INVALID_HANDLE_VALUE != dbglog_File) {
+ if (! SetEndOfFile(dbglog_File)) {
+ /* report error (how?) */
+ }
+ (void) CloseHandle(dbglog_File);
+ dbglog_File = INVALID_HANDLE_VALUE;
+ }
+}
+
+#endif
+
+#include "COMOSGLU.h"
+
+#ifndef InstallFileIcons
+#define InstallFileIcons 0
+#endif
+
+/* Resource Ids */
+
+#define IDI_VMAC 256
+#if InstallFileIcons
+#define IDI_ROM 257
+#define IDI_DISK 258
+#endif
+
+/* --- some simple utilities --- */
+
+#define TestBit(i, p) (((unsigned long)(i) & PowOf2(p)) != 0)
+
+GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount)
+{
+/*
+ must work even if blocks overlap in memory
+*/
+ (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount);
+}
+
+/* --- Parameter buffers --- */
+
+#if IncludePbufs
+LOCALVAR HGLOBAL PbufDat[NumPbufs];
+#endif
+
+#if IncludePbufs
+LOCALFUNC tMacErr PbufNewFromHandle(HGLOBAL h, ui5b count, tPbuf *r)
+{
+ tPbuf i;
+ tMacErr err;
+
+ if (! FirstFreePbuf(&i)) {
+ (void) GlobalFree(h);
+ err = mnvm_miscErr;
+ } else {
+ *r = i;
+ PbufDat[i] = h;
+ PbufNewNotify(i, count);
+ err = mnvm_noErr;
+ }
+
+ return err;
+}
+#endif
+
+#if IncludePbufs
+GLOBALOSGLUFUNC tMacErr PbufNew(ui5b count, tPbuf *r)
+{
+ HGLOBAL h;
+ tMacErr err = mnvm_miscErr;
+
+ h = GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT, count);
+ if (h != NULL) {
+ /* need to clear h */
+ err = PbufNewFromHandle(h, count, r);
+ }
+
+ return err;
+}
+#endif
+
+#if IncludePbufs
+GLOBALOSGLUPROC PbufDispose(tPbuf i)
+{
+ (void) GlobalFree(PbufDat[i]);
+ PbufDisposeNotify(i);
+}
+#endif
+
+#if IncludePbufs
+LOCALPROC UnInitPbufs(void)
+{
+ tPbuf i;
+
+ for (i = 0; i < NumPbufs; ++i) {
+ if (PbufIsAllocated(i)) {
+ PbufDispose(i);
+ }
+ }
+}
+#endif
+
+#if IncludePbufs
+#define PbufHaveLock 1
+#endif
+
+#if IncludePbufs
+LOCALFUNC ui3p PbufLock(tPbuf i)
+{
+ HGLOBAL h = PbufDat[i];
+ return (ui3p)GlobalLock(h);
+}
+#endif
+
+#if IncludePbufs
+LOCALPROC PbufUnlock(tPbuf i)
+{
+ (void) GlobalUnlock(PbufDat[i]);
+}
+#endif
+
+#if IncludePbufs
+GLOBALOSGLUPROC PbufTransfer(ui3p Buffer,
+ tPbuf i, ui5r offset, ui5r count, blnr IsWrite)
+{
+ HGLOBAL h = PbufDat[i];
+ ui3p p0 = GlobalLock(h);
+ if (p0 != NULL) {
+ void *p = p0 + offset;
+ if (IsWrite) {
+ (void) memcpy(p, Buffer, count);
+ } else {
+ (void) memcpy(Buffer, p, count);
+ }
+ }
+ (void) GlobalUnlock(h);
+}
+#endif
+
+/* --- control mode and internationalization --- */
+
+#include "CONTROLM.h"
+
+/* --- main window info --- */
+
+LOCALVAR HWND MainWnd = NULL;
+
+LOCALVAR int WndX;
+LOCALVAR int WndY;
+
+#if UseWinCE
+LOCALVAR short oldOrientation;
+LOCALVAR unsigned long oldDisplayOrientation;
+#endif
+
+#if VarFullScreen
+LOCALVAR blnr UseFullScreen = (WantInitFullScreen != 0);
+#endif
+
+#if EnableMagnify
+LOCALVAR blnr UseMagnify = (WantInitMagnify != 0);
+#endif
+
+#if MayFullScreen
+LOCALVAR short hOffset;
+LOCALVAR short vOffset;
+#endif
+
+/* cursor hiding */
+
+LOCALVAR blnr HaveCursorHidden = falseblnr;
+LOCALVAR blnr WantCursorHidden = falseblnr;
+
+LOCALPROC ForceShowCursor(void)
+{
+ if (HaveCursorHidden) {
+ HaveCursorHidden = falseblnr;
+ (void) ShowCursor(TRUE);
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ }
+}
+
+/* cursor moving */
+
+LOCALFUNC blnr MyMoveMouse(si4b h, si4b v)
+{
+ POINT NewMousePos;
+ ui5b difftime;
+ blnr IsOk;
+ DWORD StartTime = GetTickCount();
+ LONG x = h;
+ LONG y = v;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ x -= ViewHStart;
+ y -= ViewVStart;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ x *= MyWindowScale;
+ y *= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ x += hOffset;
+ y += vOffset;
+ }
+#endif
+
+ x += WndX;
+ y += WndY;
+
+ do {
+ (void) SetCursorPos(x, y);
+ if (! GetCursorPos(&NewMousePos)) {
+ IsOk = falseblnr;
+ } else {
+ IsOk = (x == NewMousePos.x) && (y == NewMousePos.y);
+ }
+ difftime = (ui5b)(GetTickCount() - StartTime);
+ } while ((! IsOk) && (difftime < 100));
+ return IsOk;
+}
+
+#if EnableFSMouseMotion
+LOCALPROC StartSaveMouseMotion(void)
+{
+ if (! HaveMouseMotion) {
+ if (MyMoveMouse(ViewHStart + (ViewHSize / 2),
+ ViewVStart + (ViewVSize / 2)))
+ {
+ SavedMouseH = ViewHStart + (ViewHSize / 2);
+ SavedMouseV = ViewVStart + (ViewVSize / 2);
+ HaveMouseMotion = trueblnr;
+ }
+ }
+}
+#endif
+
+#if EnableFSMouseMotion
+LOCALPROC StopSaveMouseMotion(void)
+{
+ if (HaveMouseMotion) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ HaveMouseMotion = falseblnr;
+ }
+}
+#endif
+
+LOCALVAR blnr MyMouseCaptured = falseblnr;
+
+LOCALPROC MyMouseCaptureSet(blnr v)
+{
+ if (v != MyMouseCaptured) {
+ if (v) {
+ (void) SetCapture(MainWnd);
+ } else {
+ (void) ReleaseCapture();
+ }
+ MyMouseCaptured = v;
+ }
+}
+
+LOCALPROC SetCurMouseButton(blnr v)
+{
+ MyMouseButtonSet(v);
+ MyMouseCaptureSet(v);
+}
+
+/* keyboard */
+
+/* these constants weren't in the header files I have */
+#define myVK_Subtract 0xBD
+#define myVK_Equal 0xBB
+#define myVK_BackSlash 0xDC
+#define myVK_Comma 0xBC
+#define myVK_Period 0xBE
+#define myVK_Slash 0xBF
+#define myVK_SemiColon 0xBA
+#define myVK_SingleQuote 0xDE
+#define myVK_LeftBracket 0xDB
+#define myVK_RightBracket 0xDD
+#define myVK_Grave 0xC0
+
+/* some new ones, need to check if in all header versions */
+#define myVK_PRIOR 0x21
+#define myVK_NEXT 0x22
+#define myVK_END 0x23
+#define myVK_HOME 0x24
+#define myVK_INSERT 0x2D
+#define myVK_DELETE 0x2E
+#define myVK_HELP 0x2F
+#define myVK_SCROLL 0x91
+#define myVK_SNAPSHOT 0x2C
+#define myVK_PAUSE 0x13
+#define myVK_CLEAR 0x0C
+
+#define myVK_OEM_8 0xDF
+#define myVK_OEM_102 0xE2
+
+#ifndef ItnlKyBdFix
+#define ItnlKyBdFix 0
+#endif
+
+#if ItnlKyBdFix
+LOCALVAR ui3b MyVkMapA[256];
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkSwapZY(void)
+{
+ MyVkMapA['Z'] = 'Y';
+ MyVkMapA['Y'] = 'Z';
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkSwapGraveQuote(void)
+{
+ MyVkMapA[myVK_Grave] = myVK_SingleQuote;
+ MyVkMapA[myVK_SingleQuote] = myVK_Grave;
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkSwapSlashSubtract(void)
+{
+ MyVkMapA[myVK_Slash] = myVK_Subtract;
+ MyVkMapA[myVK_Subtract] = myVK_Slash;
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkSwapAQZWGraveQuote(void)
+{
+ MyVkSwapGraveQuote();
+ MyVkMapA['A'] = 'Q';
+ MyVkMapA['Q'] = 'A';
+ MyVkMapA['Z'] = 'W';
+ MyVkMapA['W'] = 'Z';
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkMapBelgian(void)
+{
+ MyVkSwapAQZWGraveQuote();
+ MyVkMapA['M'] = myVK_SemiColon;
+ MyVkMapA[myVK_SemiColon] = myVK_RightBracket;
+ MyVkMapA[myVK_RightBracket] = myVK_LeftBracket;
+ MyVkMapA[myVK_LeftBracket] = myVK_Subtract;
+ MyVkMapA[myVK_Subtract] = myVK_Equal;
+ MyVkMapA[myVK_Equal] = myVK_Slash;
+ MyVkMapA[myVK_Slash] = myVK_Period;
+ MyVkMapA[myVK_Period] = myVK_Comma;
+ MyVkMapA[myVK_Comma] = 'M';
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkMapSwiss(void)
+{
+ MyVkSwapZY();
+ MyVkMapA[myVK_OEM_8] = myVK_BackSlash;
+ MyVkMapA[myVK_BackSlash] = myVK_SingleQuote;
+ MyVkMapA[myVK_SingleQuote] = myVK_SemiColon;
+ MyVkMapA[myVK_SemiColon] = myVK_LeftBracket;
+ MyVkMapA[myVK_LeftBracket] = myVK_Subtract;
+ MyVkMapA[myVK_Subtract] = myVK_Slash;
+ MyVkMapA[myVK_Slash] = myVK_Grave;
+ MyVkMapA[myVK_Grave] = myVK_RightBracket;
+ MyVkMapA[myVK_RightBracket] = myVK_Equal;
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkMapDanish(void)
+{
+ MyVkMapA[myVK_Equal] = myVK_Subtract;
+ MyVkMapA[myVK_Subtract] = myVK_Slash;
+ MyVkMapA[myVK_Slash] = myVK_BackSlash;
+ MyVkMapA[myVK_BackSlash] = myVK_Grave;
+ MyVkMapA[myVK_Grave] = myVK_SemiColon;
+ MyVkMapA[myVK_SemiColon] = myVK_RightBracket;
+ MyVkMapA[myVK_RightBracket] = myVK_LeftBracket;
+ MyVkMapA[myVK_LeftBracket] = myVK_Equal;
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkMapBritish(void)
+{
+ MyVkMapA[myVK_OEM_8] = myVK_Grave;
+ MyVkMapA[myVK_Grave] = myVK_SingleQuote;
+ MyVkMapA[myVK_SingleQuote] = myVK_BackSlash;
+ MyVkMapA[myVK_BackSlash] = myVK_OEM_102;
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkMapSpanish(void)
+{
+ MyVkMapA[myVK_SemiColon] = myVK_LeftBracket;
+ MyVkMapA[myVK_LeftBracket] = myVK_Subtract;
+ MyVkMapA[myVK_Subtract] = myVK_Slash;
+ MyVkMapA[myVK_Slash] = myVK_BackSlash;
+ MyVkMapA[myVK_BackSlash] = myVK_Grave;
+ MyVkMapA[myVK_Grave] = myVK_SemiColon;
+
+ MyVkMapA[myVK_RightBracket] = myVK_Equal;
+ MyVkMapA[myVK_Equal] = myVK_RightBracket;
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkMapDutch(void)
+{
+ MyVkSwapGraveQuote();
+ MyVkMapA[myVK_SemiColon] = myVK_RightBracket;
+ MyVkMapA[myVK_RightBracket] = myVK_LeftBracket;
+ MyVkMapA[myVK_LeftBracket] = myVK_Subtract;
+ MyVkMapA[myVK_Subtract] = myVK_Slash;
+ MyVkMapA[myVK_Slash] = myVK_Equal;
+ MyVkMapA[myVK_Equal] = myVK_SemiColon;
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkMapGreekIBM(void)
+{
+ MyVkSwapSlashSubtract();
+ MyVkMapA[myVK_LeftBracket] = myVK_Equal;
+ MyVkMapA[myVK_Equal] = myVK_LeftBracket;
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkMapFrench(void)
+{
+ MyVkSwapAQZWGraveQuote();
+ MyVkMapA['M'] = myVK_SemiColon;
+ MyVkMapA[myVK_SemiColon] = myVK_RightBracket;
+ MyVkMapA[myVK_RightBracket] = myVK_LeftBracket;
+ MyVkMapA[myVK_LeftBracket] = myVK_Subtract;
+ MyVkMapA[myVK_Comma] = 'M';
+ MyVkMapA[myVK_Period] = myVK_Comma;
+ MyVkMapA[myVK_Slash] = myVK_Period;
+ MyVkMapA[myVK_OEM_8] = myVK_Slash;
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkMapGerman(void)
+{
+ MyVkSwapZY();
+ MyVkMapSpanish();
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkMapBosnian(void)
+{
+ MyVkSwapZY();
+ /* not in Windows 95 */
+ MyVkSwapSlashSubtract();
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkMapBulgarian(void)
+{
+ MyVkMapA[myVK_OEM_8] = myVK_Comma;
+ MyVkMapA[myVK_Comma] = 'Q';
+ MyVkMapA['Q'] = myVK_Period;
+ MyVkMapA[myVK_Period] = myVK_Equal;
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyVkMapFromLayout(uimr sv)
+{
+ int i;
+
+ for (i = 0; i < 256; ++i) {
+ MyVkMapA[i] = i;
+ }
+
+ switch (sv) {
+ case 0x00000409:
+ /* United States 101 */
+ break;
+ case 0x0000041c:
+ /* Albanian; */
+ MyVkSwapZY();
+ break;
+ case 0x0000042B:
+ /* Armenian Eastern; */
+ MyVkMapDutch();
+ break;
+ case 0x0001042B:
+ /* Armenian Western; */
+ MyVkMapDutch();
+ break;
+ case 0x0000042C:
+ /* not in Windows 95 */
+ /* Azeri Latin */
+ MyVkMapBritish();
+ break;
+ case 0x0001080C:
+ /* Belgian (comma) */
+ MyVkMapBelgian();
+ break;
+ case 0x0000080c:
+ /* Belgian French */
+ MyVkMapBelgian();
+ break;
+ case 0x00000813:
+ /* not in Windows 95 */
+ /* Belgian (period); */
+ MyVkMapBelgian();
+ break;
+ case 0x0000141A:
+ /* not in Windows 95 */
+ /* Bosnian */
+ MyVkMapBosnian();
+ break;
+ case 0x00000809:
+ /* British / United Kingdom */
+ MyVkMapBritish();
+ break;
+ case 0x00000452:
+ /* not in Windows 95 */
+ /* United Kingdom Extended */
+ MyVkMapBritish();
+ break;
+ case 0x00000402:
+ /* Bulgarian */
+ /* not same in Windows 95 */
+ MyVkMapBulgarian();
+ break;
+ case 0x00030402:
+ /* Bulgarian */
+ MyVkMapBulgarian();
+ break;
+ case 0x00020402:
+ /* Bulgarian (Phonetic) */
+ MyVkMapBosnian();
+ break;
+ case 0x00001009:
+ /* Canadian Multilingual */
+ /* not in Windows 95 */
+ MyVkSwapGraveQuote();
+ break;
+ case 0x00011009:
+ /* Canadian Standard */
+ MyVkSwapGraveQuote();
+ break;
+ case 0x0000041a:
+ /* Croatian */
+ MyVkMapBosnian();
+ break;
+ case 0x00000405:
+ /* Czech */
+ MyVkMapBosnian();
+#if 0
+ /* but Windows 7 gives */
+ MyVkSwapZY();
+ MyVkMapA[myVK_Equal] = myVK_Subtract;
+ MyVkMapA[myVK_Subtract] = myVK_Slash;
+ MyVkMapA[myVK_Slash] = myVK_Equal;
+#endif
+ break;
+ case 0x00020405:
+ /* Czech (Programmers) */
+ /* only in Windows 95 */
+ /* MyVkSwapZY(); */
+ break;
+ case 0x00010405:
+ /* Czech (Qwerty) */
+ /* only in Windows 95 */
+ /* MyVkSwapZY(); */
+ break;
+ case 0x00000406:
+ /* Danish */
+ MyVkMapDanish();
+ break;
+ case 0x00000413:
+ /* Dutch */
+ MyVkMapDutch();
+ break;
+ case 0x00000425:
+ /* Estonian */
+ MyVkMapA[myVK_Grave] = myVK_LeftBracket;
+ MyVkMapA[myVK_LeftBracket] = myVK_RightBracket;
+ MyVkMapA[myVK_RightBracket] = myVK_Slash;
+ MyVkMapA[myVK_Slash] = myVK_SingleQuote;
+ MyVkMapA[myVK_SingleQuote] = myVK_Grave;
+ /* only in Windows 95 ? */
+ /* MyVkMapA[VK_DECIMAL] = VK_DELETE; */
+ break;
+ case 0x00000438:
+ /* Faeroe Islands */
+ MyVkMapDanish();
+ break;
+ case 0x0000040b:
+ /* Finnish */
+ MyVkMapDanish();
+ break;
+ case 0x0001083B:
+ /* not in Windows 95 */
+ /* Finnish with Sami */
+ MyVkMapDanish();
+ break;
+ case 0x0000040c:
+ /* v = kMyKbdFrench; */
+ /* French */
+ MyVkMapFrench();
+ break;
+ case 0x00000c0c:
+ /* French Canadian */
+ MyVkSwapGraveQuote();
+ break;
+ case 0x00011809:
+ /* not in Windows 95 */
+ /* Gaelic */
+ MyVkMapBritish();
+ break;
+ case 0x00010407:
+ /* German (IBM) */
+ MyVkMapGerman();
+ break;
+ case 0x00000407:
+ /* German (Standard) */
+ MyVkMapGerman();
+ break;
+ case 0x00010408:
+ /* Greek IBM 220 */
+ /* not in Windows 95 */
+ MyVkMapGreekIBM();
+ break;
+ case 0x00030408:
+ /* Greek IBM 319 */
+ /* not in Windows 95 */
+ MyVkMapGreekIBM();
+ break;
+ case 0x00020408:
+ /* Greek Latin IBM 220 */
+ /* not in Windows 95 */
+ MyVkSwapSlashSubtract();
+ break;
+ case 0x00040408:
+ /* Greek Latin IBM 319 */
+ /* not in Windows 95 */
+ MyVkSwapSlashSubtract();
+ break;
+ case 0x0000040e:
+ /* Hungarian */
+ MyVkMapBosnian();
+ MyVkMapA[myVK_Grave] = '0';
+ MyVkMapA['0'] = myVK_Grave;
+ break;
+ case 0x0001040E:
+ /* Hungarian (101 Keys) */
+ MyVkMapA[myVK_Grave] = '0';
+ MyVkMapA['0'] = myVK_Grave;
+ break;
+ case 0x0000040f:
+ /* Icelandic */
+ MyVkMapDanish();
+ break;
+ case 0x00001809:
+ /* Irish */
+ MyVkMapBritish();
+ break;
+ case 0x00000410:
+ /* Italian */
+ MyVkMapSpanish();
+ break;
+ case 0x00010410:
+ /* Italian 142 */
+ MyVkMapSpanish();
+ break;
+ case 0x0000080a:
+ /* Latin American */
+ MyVkMapSpanish();
+ break;
+ case 0x0000046E:
+ /* Luxembourgish */
+ MyVkMapSwiss();
+ break;
+ case 0x00000414:
+ /* Norwegian */
+ MyVkMapDanish();
+ break;
+ case 0x0000043B:
+ /* Norwegian with Sami */
+ MyVkMapDanish();
+ break;
+ case 0x00010415:
+ /* Polish (214) */
+ MyVkSwapZY();
+ /* not in windows 95 */
+ MyVkMapA[myVK_Equal] = myVK_Subtract;
+ MyVkMapA[myVK_Subtract] = myVK_Slash;
+ MyVkMapA[myVK_Slash] = myVK_Equal;
+ break;
+ case 0x00010416:
+ /* Porguguese (Brazilian ABNT2) */
+ /* MyVkMapA[myVK_OEM_8] = ??; */
+ /* MyVkMapA[VK_SEPARATOR] = ??; */
+ break;
+ case 0x00000816:
+ /* Porguguese (Standard) */
+ MyVkMapA[myVK_SemiColon] = myVK_RightBracket;
+ MyVkMapA[myVK_RightBracket] = myVK_Equal;
+ MyVkMapA[myVK_Equal] = myVK_LeftBracket;
+ MyVkMapA[myVK_LeftBracket] = myVK_Subtract;
+ MyVkMapA[myVK_Subtract] = myVK_Slash;
+ MyVkMapA[myVK_Slash] = myVK_BackSlash;
+ MyVkMapA[myVK_BackSlash] = myVK_Grave;
+ MyVkMapA[myVK_Grave] = myVK_SemiColon;
+ break;
+ case 0x00000418:
+ /* Romanian (Legacy) */
+ MyVkSwapZY();
+ /* only in Windows 95 */
+ /* MyVkSwapSlashSubtract(); */
+ break;
+ case 0x0002083B:
+ /* Sami Extended Finland-Sweden */
+ MyVkMapDanish();
+ break;
+ case 0x0001043B:
+ /* Sami Extended Norway */
+ MyVkMapDanish();
+ break;
+ case 0x00010C1A:
+ /* in Windows 95 */
+ /* Serbian (Latin) */
+ MyVkSwapZY();
+ break;
+ case 0x0000081A:
+ /* not in Windows 95 */
+ /* Serbian (Latin) */
+ MyVkMapBosnian();
+ break;
+ case 0x0000041b:
+ /* Slovak */
+ MyVkMapBosnian();
+ /* not in Windows 95 */
+ MyVkMapA[myVK_OEM_8] = myVK_Equal;
+ break;
+ case 0x00000424:
+ /* Slovenian */
+ MyVkMapBosnian();
+ break;
+ case 0x0000040A:
+ /* Spanish, not windows 95 */
+ MyVkMapSpanish();
+ break;
+ case 0x0001040A:
+ /* Spanish Variation, not windows 95 */
+ MyVkMapA[myVK_OEM_8] = myVK_Slash;
+ MyVkMapA[myVK_Slash] = myVK_BackSlash;
+ MyVkMapA[myVK_BackSlash] = myVK_Grave;
+ MyVkMapA[myVK_Grave] = myVK_SemiColon;
+ MyVkMapA[myVK_SemiColon] = myVK_RightBracket;
+ MyVkMapA[myVK_RightBracket] = myVK_LeftBracket;
+ MyVkMapA[myVK_LeftBracket] = myVK_Equal;
+ break;
+ case 0x00000c0a:
+ /* kMyKbdSpanish; */
+ /* Spanish Modern, windows 95 */
+ MyVkMapSpanish();
+ break;
+ case 0x00000403:
+ /* Spanish Traditional */
+ MyVkMapSpanish();
+ break;
+ case 0x0000041d:
+ /* Swedish */
+ MyVkMapDanish();
+ break;
+ case 0x0000083B:
+ /* not in windows 95 */
+ /* Swedish with Sami */
+ MyVkMapDanish();
+ break;
+ case 0x0000100c:
+ /* Swiss French */
+ MyVkMapSwiss();
+ break;
+ case 0x00000807:
+ /* Swiss German */
+ MyVkMapSwiss();
+ break;
+ case 0x0000085D:
+ /* Inuktitut Latin */
+ /* in windows 7, not XP */
+ MyVkMapBritish();
+ break;
+ case 0x0001045D:
+ /* Inuktitut - Naqittaut */
+ MyVkMapBritish();
+ break;
+ case 0x0000046F:
+ /* Greenlandic */
+ MyVkMapDanish();
+ break;
+ case 0x00020427:
+ /* Lithuanian Standard */
+ MyVkMapDanish();
+ break;
+ case 0x0000042f:
+ /* Macedonian (FYROM) - Standard */
+ MyVkMapBosnian();
+ break;
+ case 0x0000042E:
+ /* Sorbian Standard (Legacy) */
+ MyVkMapGerman();
+ break;
+ case 0x0001042E:
+ /* Sorbian Extended */
+ MyVkMapGerman();
+ break;
+ case 0x0002042E:
+ /* Sorbian Standard */
+ MyVkMapGerman();
+ break;
+ case 0x00000488:
+ /* Wolof */
+ MyVkMapFrench();
+ break;
+ case 0x0000041f:
+ /* Turkish (Q type) */
+ /* windows 95 */
+ /* MyVkMapA[myVK_Equal] = myVK_Subtract; */
+ /* MyVkMapA[myVK_Subtract] = myVK_Equal; */
+ /* not windows 95 */
+ MyVkMapA[myVK_OEM_8] = myVK_Subtract;
+ MyVkMapA[myVK_Subtract] = myVK_Equal;
+
+ MyVkMapA[myVK_Comma] = myVK_BackSlash;
+ MyVkMapA[myVK_BackSlash] = myVK_Period;
+ MyVkMapA[myVK_Period] = myVK_Slash;
+ MyVkMapA[myVK_Slash] = myVK_Comma;
+ break;
+ case 0x00010409:
+ /* United States Dvorak */
+ MyVkMapA[myVK_LeftBracket] = myVK_Subtract;
+ MyVkMapA[myVK_RightBracket] = myVK_Equal;
+ MyVkMapA[myVK_SingleQuote] = 'Q';
+ MyVkMapA[myVK_Comma] = 'W';
+ MyVkMapA[myVK_Period] = 'E';
+ MyVkMapA['P'] = 'R';
+ MyVkMapA['Y'] = 'T';
+ MyVkMapA['F'] = 'Y';
+ MyVkMapA['G'] = 'U';
+ MyVkMapA['C'] = 'I';
+ MyVkMapA['R'] = 'O';
+ MyVkMapA['L'] = 'P';
+ MyVkMapA[myVK_Slash] = myVK_LeftBracket;
+ MyVkMapA[myVK_Equal] = myVK_RightBracket;
+ MyVkMapA['O'] = 'S';
+ MyVkMapA['E'] = 'D';
+ MyVkMapA['U'] = 'F';
+ MyVkMapA['I'] = 'G';
+ MyVkMapA['D'] = 'H';
+ MyVkMapA['H'] = 'J';
+ MyVkMapA['T'] = 'K';
+ MyVkMapA['N'] = 'L';
+ MyVkMapA['S'] = myVK_SemiColon;
+ MyVkMapA[myVK_Subtract] = myVK_SingleQuote;
+ MyVkMapA[myVK_SemiColon] = 'Z';
+ MyVkMapA['Q'] = 'X';
+ MyVkMapA['J'] = 'C';
+ MyVkMapA['K'] = 'V';
+ MyVkMapA['X'] = 'B';
+ MyVkMapA['B'] = 'N';
+ MyVkMapA['W'] = myVK_Comma;
+ MyVkMapA['V'] = myVK_Period;
+ MyVkMapA['Z'] = myVK_Slash;
+ break;
+#if 0
+ /* too complicated, don't bother with */
+ case 0x0x00000426:
+ /* Latvian */
+ MyVkMapA['F'] = myVK_Equal;
+ MyVkMapA['G'] = 'W';
+ MyVkMapA['J'] = 'E';
+ MyVkMapA['M'] = 'T';
+ MyVkMapA['V'] = 'Y';
+ MyVkMapA['N'] = 'U';
+ MyVkMapA['Z'] = 'I';
+ MyVkMapA['W'] = 'O';
+ MyVkMapA['X'] = 'P';
+ MyVkMapA['Y'] = myVK_LeftBracket;
+ MyVkMapA['H'] = myVK_RightBracket;
+ MyVkMapA[myVK_SemiColon] = 'A';
+ MyVkMapA['U'] = 'S';
+ MyVkMapA['S'] = 'D';
+ MyVkMapA['I'] = 'F';
+ MyVkMapA['L'] = 'G';
+ MyVkMapA['D'] = 'H';
+ MyVkMapA['A'] = 'J';
+ MyVkMapA['T'] = 'K';
+ MyVkMapA['E'] = 'L';
+ MyVkMapA['C'] = myVK_SemiColon;
+ MyVkMapA[myVK_LeftBracket] = 'Z';
+ MyVkMapA['B'] = 'X';
+ MyVkMapA[myVK_RightBracket] = 'C';
+ MyVkMapA['K'] = 'V';
+ MyVkMapA['P'] = 'B';
+ MyVkMapA['O'] = 'N';
+ MyVkMapA[myVK_OEM_8] = 'M';
+ break;
+ case 0x0001041F:
+ /* Turkish (F type) */
+
+ MyVkMapA[myVK_Equal] = myVK_Subtract;
+ MyVkMapA[myVK_Subtract] = myVK_Equal;
+ MyVkMapA['F'] = 'Q';
+ MyVkMapA['G'] = 'W';
+ MyVkMapA[myVK_SemiColon] = 'E';
+ MyVkMapA['I'] = 'R';
+ MyVkMapA['O'] = 'T';
+ MyVkMapA['D'] = 'Y';
+ MyVkMapA['R'] = 'U';
+ MyVkMapA['N'] = 'I';
+ MyVkMapA['H'] = 'O';
+ MyVkMapA['Q'] = myVK_LeftBracket;
+ MyVkMapA['W'] = myVK_RightBracket;
+ MyVkMapA['U'] = 'A';
+ MyVkMapA[myVK_LeftBracket] = 'S';
+ MyVkMapA['E'] = 'D';
+ MyVkMapA['A'] = 'F';
+ MyVkMapA[myVK_RightBracket] = 'G';
+ MyVkMapA['T'] = 'H';
+ MyVkMapA['K'] = 'J';
+ MyVkMapA['M'] = 'K';
+ MyVkMapA['Y'] = myVK_SemiColon;
+ MyVkMapA['X'] = myVK_BackSlash;
+ MyVkMapA['J'] = 'Z';
+ MyVkMapA[myVK_BackSlash] = 'X';
+ MyVkMapA['V'] = 'C';
+ MyVkMapA['C'] = 'V';
+ MyVkMapA[myVK_Slash] = 'B';
+ MyVkMapA['Z'] = 'N';
+ MyVkMapA['S'] = 'M';
+ MyVkMapA['B'] = myVK_Comma;
+ MyVkMapA[myVK_Comma] = myVK_Slash;
+ break;
+ case 0x00030409:
+ /* United States LH Dvorak */
+ MyVkMapA[myVK_LeftBracket] = '1';
+ MyVkMapA[myVK_RightBracket] = '2';
+ MyVkMapA[myVK_Slash] = '3';
+ MyVkMapA['P'] = '4';
+ MyVkMapA['F'] = '5';
+ MyVkMapA['M'] = '6';
+ MyVkMapA['L'] = '7';
+ MyVkMapA['J'] = '8';
+ MyVkMapA['4'] = '9';
+ MyVkMapA['3'] = '0';
+ MyVkMapA['2'] = myVK_Subtract;
+ MyVkMapA['1'] = myVK_Equal;
+ MyVkMapA[myVK_SemiColon] = 'Q';
+ MyVkMapA['Q'] = 'W';
+ MyVkMapA['B'] = 'E';
+ MyVkMapA['Y'] = 'R';
+ MyVkMapA['U'] = 'T';
+ MyVkMapA['R'] = 'Y';
+ MyVkMapA['S'] = 'U';
+ MyVkMapA['O'] = 'I';
+ MyVkMapA[myVK_Period] = 'O';
+ MyVkMapA['6'] = 'P';
+ MyVkMapA['5'] = myVK_LeftBracket;
+ MyVkMapA[myVK_Equal] = myVK_RightBracket;
+ MyVkMapA[myVK_Subtract] = 'A';
+ MyVkMapA['K'] = 'S';
+ MyVkMapA['C'] = 'D';
+ MyVkMapA['D'] = 'F';
+ MyVkMapA['T'] = 'G';
+ MyVkMapA['E'] = 'J';
+ MyVkMapA['A'] = 'K';
+ MyVkMapA['Z'] = 'L';
+ MyVkMapA['8'] = myVK_SemiColon;
+ MyVkMapA['7'] = myVK_SingleQuote;
+ MyVkMapA[myVK_SingleQuote] = 'Z';
+ MyVkMapA['G'] = 'C';
+ MyVkMapA['W'] = 'B';
+ MyVkMapA['I'] = 'M';
+ MyVkMapA['0'] = myVK_Period;
+ MyVkMapA['9'] = myVK_Slash;
+ break;
+ case 0x00040409:
+ /* United States RH Dvorak */
+ MyVkMapA['J'] = '5';
+ MyVkMapA['L'] = '6';
+ MyVkMapA['M'] = '7';
+ MyVkMapA['F'] = '8';
+ MyVkMapA['P'] = '9';
+ MyVkMapA[myVK_Slash] = '0';
+ MyVkMapA[myVK_LeftBracket] = myVK_Subtract;
+ MyVkMapA[myVK_RightBracket] = myVK_Equal;
+ MyVkMapA['5'] = 'Q';
+ MyVkMapA['6'] = 'W';
+ MyVkMapA['Q'] = 'E';
+ MyVkMapA[myVK_Period] = 'R';
+ MyVkMapA['O'] = 'T';
+ MyVkMapA['R'] = 'Y';
+ MyVkMapA['S'] = 'U';
+ MyVkMapA['U'] = 'I';
+ MyVkMapA['Y'] = 'O';
+ MyVkMapA['B'] = 'P';
+ MyVkMapA[myVK_SemiColon] = myVK_LeftBracket;
+ MyVkMapA[myVK_Equal] = myVK_RightBracket;
+ MyVkMapA['7'] = 'A';
+ MyVkMapA['8'] = 'S';
+ MyVkMapA['Z'] = 'D';
+ MyVkMapA['A'] = 'F';
+ MyVkMapA['E'] = 'G';
+ MyVkMapA['T'] = 'J';
+ MyVkMapA['D'] = 'K';
+ MyVkMapA['C'] = 'L';
+ MyVkMapA['K'] = myVK_SemiColon;
+ MyVkMapA[myVK_Subtract] = myVK_SingleQuote;
+ MyVkMapA['9'] = 'Z';
+ MyVkMapA['0'] = 'X';
+ MyVkMapA['X'] = 'C';
+ MyVkMapA[myVK_Comma] = 'V';
+ MyVkMapA['I'] = 'B';
+ MyVkMapA['W'] = 'M';
+ MyVkMapA['V'] = myVK_Comma;
+ MyVkMapA['G'] = myVK_Period;
+ MyVkMapA[myVK_SingleQuote] = myVK_Slash;
+ break;
+#endif
+#if 0
+ case 0x0000082C:
+ /* not in Windows 95 */
+ /* Azeri Cyrillic */
+ break;
+ case 0x00000423:
+ /* Belarusian */
+ break;
+ case 0x00000445:
+ /* not in Windows 95 */
+ /* Bengali */
+ break;
+ case 0x00010445:
+ /* not in Windows 95 */
+ /* Bengali (Inscript) */
+ break;
+ case 0x0000201A:
+ /* not in Windows 95 */
+ /* Bosnian Cyrillic*/
+ break;
+ case 0x00010402:
+ /* Bulgarian Latin */
+#if 0 /* Only in Windows 95 */
+ MyVkMapA['J'] = 'Q';
+ MyVkMapA['C'] = 'W';
+ MyVkMapA['U'] = 'E';
+ MyVkMapA['K'] = 'R';
+ MyVkMapA['E'] = 'T';
+ MyVkMapA['N'] = 'Y';
+ MyVkMapA['G'] = 'U';
+ MyVkMapA[myVK_SemiColon] = 'I';
+ MyVkMapA[myVK_OEM_102] = 'O';
+ MyVkMapA['Z'] = 'P';
+ MyVkMapA['H'] = myVK_LeftBracket;
+ MyVkMapA['F'] = 'A';
+ MyVkMapA['Y'] = 'S';
+ MyVkMapA['W'] = 'D';
+ MyVkMapA['A'] = 'F';
+ MyVkMapA['P'] = 'G';
+ MyVkMapA['R'] = 'H';
+ MyVkMapA['O'] = 'J';
+ MyVkMapA['L'] = 'K';
+ MyVkMapA['D'] = 'L';
+ MyVkMapA['V'] = myVK_SemiColon;
+ MyVkMapA[myVK_LeftBracket] = 'Z';
+ MyVkMapA['S'] = 'X';
+ MyVkMapA['M'] = 'C';
+ MyVkMapA['I'] = 'V';
+ MyVkMapA['T'] = 'B';
+ MyVkMapA['X'] = 'N';
+ MyVkMapA['B'] = 'M';
+ MyVkMapA['Q'] = myVK_OEM_102;
+#endif
+ break;
+ case 0x00000408:
+ /* Greek */
+ break;
+ case 0x00050408:
+ /* Greek Latin */
+ break;
+ case 0x00060408:
+ /* Greek Polytonic */
+ break;
+ case 0x0000043F:
+ /* Kazakh */
+ break;
+ case 0x00000440:
+ /* Kyrgyz Cyrillic */
+ break;
+ case 0x00010426:
+ /* Latvian Latin */
+ break;
+ case 0x00010427:
+ /* Lithuanian */
+ break;
+ case 0x00000427:
+ /* Lithuanian (IBM) */
+ break;
+ case 0x0000044C:
+ /* Malayalam */
+ break;
+ case 0x0000042f:
+ /* Macedonian (FYROM) */
+ break;
+ case 0x0000043A:
+ /* Maltese 47-key */
+ break;
+ case 0x0001043A:
+ /* Maltese 48-key */
+ break;
+ case 0x00000481:
+ /* Maori */
+ break;
+ case 0x00000450:
+ /* Mongolian Cyrillic */
+ break;
+ case 0x00000461:
+ /* Nepali */
+ break;
+ case 0x00000463:
+ /* Pashto */
+ break;
+ case 0x00000415:
+ /* Polish (Programmers) */
+ break;
+ case 0x00000416:
+ /* Porguguese (Brazilian standard) */
+ break;
+ case 0x00000419:
+ /* Russian */
+ break;
+ case 0x00010419:
+ /* Russian (Typewriter) */
+ break;
+ case 0x00000c1a:
+ /* Serbian */
+ break;
+ case 0x0001041B:
+ /* Slovak (Qwerty) */
+ break;
+ case 0x00000444:
+ /* Tatar */
+ break;
+ case 0x00000422:
+ /* Ukrainian */
+ break;
+ case 0x00020409:
+ /* United States International */
+ break;
+ case 0x00000843:
+ /* Uzbek Cyrillic */
+ break;
+ case 0x00010418:
+ /* Romanian (Standard) */
+ break;
+ case 0x00020418:
+ /* Romanian (Programmers) */
+ break;
+ case 0x00000401:
+ /* Arabic (101) */
+ break;
+ case 0x00010401:
+ /* Arabic (102) */
+ break;
+ case 0x0000044D:
+ /* Assamese - INSCRIPT */
+ break;
+ case 0x0000046D:
+ /* Bashkir */
+ break;
+ case 0x00040402:
+ /* Bulgarian (Phonetic Traditional) */
+ break;
+ case 0x00000404:
+ /* Chinese (Traditional) */
+ break;
+ case 0x00000804:
+ /* Chinese (Simplified) */
+ break;
+ case 0x00000C04:
+ /* Chinese (Traditional, Hong Kong S.A.R.) */
+ break;
+ case 0x00001004:
+ /* Chinese (Simplified, Singapore) */
+ break;
+ case 0x00001404:
+ /* Chinese (Traditional, Macao S.A.R.) */
+ break;
+ case 0x0000040D:
+ /* Hebrew */
+ break;
+ case 0x00000447:
+ /* Gujarati */
+ break;
+ case 0x00000468:
+ /* Hausa */
+ break;
+ case 0x00010439:
+ /* Hindi Traditional */
+ break;
+ case 0x00000439:
+ /* Devanagari - INSCRIPT */
+ break;
+ case 0x00000465:
+ /* Divehi Phonetic */
+ break;
+ case 0x00010465:
+ /* Divehi Typewriter */
+ break;
+ case 0x00000437:
+ /* Georgian */
+ break;
+ case 0x00010437:
+ /* Georgian (QWERTY) */
+ break;
+ case 0x00020437:
+ /* Georgian (Ergonomic) */
+ break;
+ case 0x00000470:
+ /* Igbo */
+ break;
+ case 0x00000411:
+ /* Japanese */
+ /* MyVkMapA[??] = ??; */
+ break;
+ case 0x00000412:
+ /* Korean */
+ /* MyVkMapA[VK_ZOOM] = ??; */
+ /* MyVkMapA[VK_HELP] = VK_ZOOM; */
+ /* MyVkMapA[??] = VK_HELP; */
+ /* MyVkMapA[??] = ??; */
+ break;
+ case 0x0000044B:
+ /* Kannada */
+ break;
+ case 0x00000453:
+ /* Khmer */
+ break;
+ case 0x00000454:
+ /* Lao */
+ break;
+ case 0x00000448:
+ /* Oriya */
+ break;
+ case 0x0000044E:
+ /* Marathi */
+ break;
+ case 0x00000850:
+ /* Mongolian (Mongolian Script) */
+ break;
+ case 0x00000429:
+ /* Persion */
+ break;
+ case 0x00000446:
+ /* Punjabi */
+ break;
+ case 0x0000046C:
+ /* Sesotho sa Leboa */
+ break;
+ case 0x00000432:
+ /* Setswana */
+ break;
+ case 0x0000045B:
+ /* Sinhala */
+ break;
+ case 0x0001045B:
+ /* Sinhala - Wij 9 */
+ break;
+ case 0x0000045A:
+ /* Syriac */
+ break;
+ case 0x0001045A:
+ /* Syriac Phonetic */
+ break;
+ case 0x00000428:
+ /* Tajik */
+ break;
+ case 0x00000449:
+ /* Tamil */
+ break;
+ case 0x0000044A:
+ /* Telugu */
+ break;
+ case 0x0000041E:
+ /* Thai Kedmanee */
+ break;
+ case 0x0001041E:
+ /* Thai Pattachote */
+ break;
+ case 0x0002041E:
+ /* Thai Kedmanee (non-ShiftLock) */
+ break;
+ case 0x0003041E:
+ /* Thai Pattachote (non-ShiftLock) */
+ break;
+ case 0x00000451:
+ /* Tibetan (PRC) */
+ break;
+ case 0x00000442:
+ /* Turkmen */
+ break;
+ case 0x00020422:
+ /* Ukrainian (Enhanced) */
+ break;
+ case 0x00000420:
+ /* Urdu */
+ break;
+ case 0x00050409:
+ /* US English Table for IBM Arabic 238_L */
+ break;
+ case 0x00000480:
+ /* Uyghur (Legacy) */
+ break;
+ case 0x00010480:
+ /* Uyghur */
+ break;
+ case 0x0000042A:
+ /* Vietnamese */
+ break;
+ case 0x00000485:
+ /* Yakut */
+ break;
+ case 0x0000046A:
+ /* Yoruba */
+ break;
+#endif
+ }
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALVAR uimr CurKyBdLytNm = 0;
+#endif
+
+#if ItnlKyBdFix
+LOCALFUNC blnr tStrIsHex(TCHAR *s, int n, uimr *r)
+{
+ short i;
+ TCHAR c1;
+ TCHAR *p = s;
+ uimr v = 0;
+
+ for (i = n; --i >= 0; ) {
+ v <<= 4;
+ c1 = *p++;
+ if ((c1 >= '0') && (c1 <= '9')) {
+ v += c1 - '0';
+ } else if ((c1 >= 'A') && (c1 <= 'F')) {
+ v += c1 - ('A' - 10);
+ } else if ((c1 >= 'a') && (c1 <= 'f')) {
+ v += c1 - ('a' - 10);
+ } else {
+ return falseblnr;
+ }
+ }
+
+ *r = v;
+ return trueblnr;
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALFUNC blnr MyGetKeyboardLayoutHex(uimr *r)
+{
+ TCHAR s[KL_NAMELENGTH];
+ blnr IsOk = falseblnr;
+
+ if (! GetKeyboardLayoutName(s)) {
+ /* ReportWinLastError(); */
+ } else {
+ size_t n = _tcslen(s);
+
+ if (8 != n) {
+ /* fail */
+ } else {
+ IsOk = tStrIsHex(s, n, r);
+ }
+ }
+
+ return IsOk;
+}
+#endif
+
+#if ItnlKyBdFix && ! UseWinCE
+LOCALPROC MyCheckKeyboardLayout(void)
+{
+ uimr sv;
+
+ if (! MyGetKeyboardLayoutHex(&sv)) {
+ } else if (sv == CurKyBdLytNm) {
+ /* no change */
+ } else {
+ CurKyBdLytNm = sv;
+
+ MyVkMapFromLayout(sv);
+ }
+}
+#endif
+
+#if ItnlKyBdFix
+LOCALPROC MyInitCheckKeyboardLayout(void)
+{
+ uimr sv;
+
+ if (! MyGetKeyboardLayoutHex(&sv)) {
+ sv = 0x00000409;
+ }
+
+ CurKyBdLytNm = sv;
+
+ MyVkMapFromLayout(sv);
+}
+#endif
+
+LOCALVAR ui3b WinKey2Mac[256];
+
+LOCALPROC AssignOneMacKey(ui3b WinKey, ui3r MacKey)
+{
+ WinKey2Mac[WinKey] = MacKey;
+}
+
+LOCALFUNC blnr InitWinKey2Mac(void)
+{
+ int i;
+
+ for (i = 0; i < 256; ++i) {
+ WinKey2Mac[i] = MKC_None;
+ }
+
+ AssignOneMacKey('A', MKC_A);
+ AssignOneMacKey('S', MKC_S);
+ AssignOneMacKey('D', MKC_D);
+ AssignOneMacKey('F', MKC_F);
+ AssignOneMacKey('H', MKC_H);
+ AssignOneMacKey('G', MKC_G);
+ AssignOneMacKey('Z', MKC_Z);
+ AssignOneMacKey('X', MKC_X);
+ AssignOneMacKey('C', MKC_C);
+ AssignOneMacKey('V', MKC_V);
+ AssignOneMacKey('B', MKC_B);
+ AssignOneMacKey('Q', MKC_Q);
+ AssignOneMacKey('W', MKC_W);
+ AssignOneMacKey('E', MKC_E);
+ AssignOneMacKey('R', MKC_R);
+ AssignOneMacKey('Y', MKC_Y);
+ AssignOneMacKey('T', MKC_T);
+ AssignOneMacKey('1', MKC_1);
+ AssignOneMacKey('2', MKC_2);
+ AssignOneMacKey('3', MKC_3);
+ AssignOneMacKey('4', MKC_4);
+ AssignOneMacKey('6', MKC_6);
+ AssignOneMacKey('5', MKC_5);
+ AssignOneMacKey(myVK_Equal, MKC_Equal);
+ AssignOneMacKey('9', MKC_9);
+ AssignOneMacKey('7', MKC_7);
+ AssignOneMacKey(myVK_Subtract, MKC_Minus);
+ AssignOneMacKey('8', MKC_8);
+ AssignOneMacKey('0', MKC_0);
+ AssignOneMacKey(myVK_RightBracket, MKC_RightBracket);
+ AssignOneMacKey('O', MKC_O);
+ AssignOneMacKey('U', MKC_U);
+ AssignOneMacKey(myVK_LeftBracket, MKC_LeftBracket);
+ AssignOneMacKey('I', MKC_I);
+ AssignOneMacKey('P', MKC_P);
+ AssignOneMacKey(VK_RETURN, MKC_Return);
+ AssignOneMacKey('L', MKC_L);
+ AssignOneMacKey('J', MKC_J);
+ AssignOneMacKey(myVK_SingleQuote, MKC_SingleQuote);
+ AssignOneMacKey('K', MKC_K);
+ AssignOneMacKey(myVK_SemiColon, MKC_SemiColon);
+ AssignOneMacKey(myVK_BackSlash, MKC_formac_BackSlash);
+ AssignOneMacKey(myVK_Comma, MKC_Comma);
+ AssignOneMacKey(myVK_Slash, MKC_formac_Slash);
+ AssignOneMacKey('N', MKC_N);
+ AssignOneMacKey('M', MKC_M);
+ AssignOneMacKey(myVK_Period, MKC_Period);
+
+ AssignOneMacKey(VK_TAB, MKC_Tab);
+ AssignOneMacKey(VK_SPACE, MKC_Space);
+ AssignOneMacKey(myVK_Grave, MKC_formac_Grave);
+ AssignOneMacKey(VK_BACK, MKC_BackSpace);
+ AssignOneMacKey(VK_ESCAPE, MKC_formac_Escape);
+
+ AssignOneMacKey(VK_MENU, MKC_formac_Command);
+
+ AssignOneMacKey(VK_LMENU, MKC_formac_Command);
+
+ AssignOneMacKey(VK_RMENU, MKC_formac_RCommand);
+
+ AssignOneMacKey(VK_SHIFT, MKC_formac_Shift);
+ AssignOneMacKey(VK_LSHIFT, MKC_formac_Shift);
+ AssignOneMacKey(VK_RSHIFT, MKC_formac_RShift);
+
+ AssignOneMacKey(VK_CAPITAL, MKC_formac_CapsLock);
+
+ AssignOneMacKey(VK_APPS, MKC_formac_ROption);
+
+ AssignOneMacKey(VK_LWIN, MKC_formac_Option);
+
+ AssignOneMacKey(VK_RWIN, MKC_formac_ROption);
+
+ AssignOneMacKey(VK_CONTROL, MKC_formac_Control);
+
+ AssignOneMacKey(VK_LCONTROL, MKC_formac_Control);
+
+ AssignOneMacKey(VK_RCONTROL, MKC_formac_RControl);
+
+ AssignOneMacKey(VK_F1, MKC_formac_F1);
+ AssignOneMacKey(VK_F2, MKC_formac_F2);
+ AssignOneMacKey(VK_F3, MKC_formac_F3);
+ AssignOneMacKey(VK_F4, MKC_formac_F4);
+ AssignOneMacKey(VK_F5, MKC_formac_F5);
+ AssignOneMacKey(VK_F6, MKC_F6);
+ AssignOneMacKey(VK_F7, MKC_F7);
+ AssignOneMacKey(VK_F8, MKC_F8);
+ AssignOneMacKey(VK_F9, MKC_F9);
+ AssignOneMacKey(VK_F10, MKC_F10);
+ AssignOneMacKey(VK_F11, MKC_F11);
+ AssignOneMacKey(VK_F12, MKC_F12);
+
+ AssignOneMacKey(VK_DECIMAL, MKC_Decimal);
+ AssignOneMacKey(VK_DELETE, MKC_Decimal);
+ /* AssignOneMacKey(VK_RIGHT, 0x42); */
+ AssignOneMacKey(VK_MULTIPLY, MKC_KPMultiply);
+ AssignOneMacKey(VK_ADD, MKC_KPAdd);
+ /* AssignOneMacKey(VK_LEFT, 0x46); */
+ AssignOneMacKey(VK_NUMLOCK, MKC_Clear);
+
+ /* AssignOneMacKey(VK_DOWN, 0x48); */
+ AssignOneMacKey(VK_DIVIDE, MKC_KPDevide);
+ /* AssignOneMacKey(VK_RETURN, MKC_formac_Enter); */
+ /* AssignOneMacKey(VK_UP, 0x4D); */
+ AssignOneMacKey(VK_DIVIDE, MKC_KPDevide);
+ AssignOneMacKey(VK_SUBTRACT, MKC_KPSubtract);
+
+ AssignOneMacKey(VK_SEPARATOR, MKC_KPEqual);
+ AssignOneMacKey(VK_NUMPAD0, MKC_KP0);
+ AssignOneMacKey(VK_NUMPAD1, MKC_KP1);
+ AssignOneMacKey(VK_NUMPAD2, MKC_KP2);
+ AssignOneMacKey(VK_NUMPAD3, MKC_KP3);
+ AssignOneMacKey(VK_NUMPAD4, MKC_KP4);
+ AssignOneMacKey(VK_NUMPAD5, MKC_KP5);
+
+ AssignOneMacKey(VK_NUMPAD6, MKC_KP6);
+ AssignOneMacKey(VK_NUMPAD7, MKC_KP7);
+ AssignOneMacKey(VK_NUMPAD8, MKC_KP8);
+ AssignOneMacKey(VK_NUMPAD9, MKC_KP9);
+
+ AssignOneMacKey(VK_LEFT, MKC_Left);
+ AssignOneMacKey(VK_RIGHT, MKC_Right);
+ AssignOneMacKey(VK_DOWN, MKC_Down);
+ AssignOneMacKey(VK_UP, MKC_Up);
+
+ AssignOneMacKey(myVK_PRIOR, MKC_formac_PageUp);
+ AssignOneMacKey(myVK_NEXT, MKC_formac_PageDown);
+ AssignOneMacKey(myVK_END, MKC_formac_End);
+ AssignOneMacKey(myVK_HOME, MKC_formac_Home);
+ AssignOneMacKey(myVK_INSERT, MKC_formac_Help);
+ AssignOneMacKey(myVK_DELETE, MKC_formac_ForwardDel);
+ AssignOneMacKey(myVK_HELP, MKC_formac_Help);
+ AssignOneMacKey(myVK_SNAPSHOT, MKC_Print);
+ AssignOneMacKey(myVK_SCROLL, MKC_ScrollLock);
+ AssignOneMacKey(myVK_PAUSE, MKC_Pause);
+
+ AssignOneMacKey(myVK_OEM_102, MKC_AngleBracket);
+
+ InitKeyCodes();
+
+#if ItnlKyBdFix
+ MyInitCheckKeyboardLayout();
+#endif
+
+ return trueblnr;
+}
+
+LOCALPROC DoKeyCode(int i, blnr down)
+{
+ ui3r key = WinKey2Mac[
+#if ItnlKyBdFix
+ MyVkMapA[i]
+#else
+ i
+#endif
+ ];
+ if (MKC_None != key) {
+ Keyboard_UpdateKeyMap2(key, down);
+ }
+}
+
+#ifndef EnableGrabSpecialKeys
+#if UseWinCE
+#define EnableGrabSpecialKeys 0
+#else
+#define EnableGrabSpecialKeys (MayFullScreen && GrabKeysFullScreen)
+#endif
+#endif /* EnableGrabSpecialKeys */
+
+#if EnableGrabSpecialKeys
+LOCALVAR blnr HaveSetSysParam = falseblnr;
+#endif
+
+LOCALPROC CheckTheCapsLock(void)
+{
+ DoKeyCode(VK_CAPITAL, (GetKeyState(VK_CAPITAL) & 1) != 0);
+}
+
+#if EnableGrabSpecialKeys
+LOCALVAR blnr VK_LWIN_pressed = falseblnr;
+LOCALVAR blnr VK_RWIN_pressed = falseblnr;
+#endif
+
+#if EnableGrabSpecialKeys
+LOCALPROC CheckForLostKeyUps(void)
+{
+ if (HaveSetSysParam) {
+ /* check for lost key ups */
+ if (VK_LWIN_pressed) {
+ if ((GetAsyncKeyState(VK_LWIN) & 0x8000) == 0) {
+ DoKeyCode(VK_LWIN, falseblnr);
+ VK_LWIN_pressed = falseblnr;
+ }
+ }
+ if (VK_RWIN_pressed) {
+ if ((GetAsyncKeyState(VK_RWIN) & 0x8000) == 0) {
+ DoKeyCode(VK_RWIN, falseblnr);
+ VK_RWIN_pressed = falseblnr;
+ }
+ }
+ }
+}
+#endif
+
+LOCALPROC DoVKcode0(int i, blnr down)
+{
+#if EnableGrabSpecialKeys
+ if (HaveSetSysParam) {
+ /* will need to check for lost key ups */
+ if (VK_LWIN == i) {
+ VK_LWIN_pressed = down;
+ } else if (VK_RWIN == i) {
+ VK_RWIN_pressed = down;
+ }
+ }
+#endif
+ DoKeyCode(i, down);
+}
+
+LOCALPROC DoVKcode(int i, ui3r flags, blnr down)
+{
+ switch (i) {
+#if MKC_formac_Control != MKC_formac_RControl
+ case VK_CONTROL:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_formac_RControl : MKC_formac_Control,
+ down);
+ break;
+#endif
+#if MKC_formac_RCommand != MKC_formac_Command
+ case VK_MENU:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_formac_RCommand : MKC_formac_Command,
+ down);
+ break;
+#endif
+ case VK_RETURN:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_formac_Enter : MKC_Return,
+ down);
+ break;
+ case myVK_HOME:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_formac_Home : MKC_KP7,
+ down);
+ break;
+ case VK_UP:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_Up : MKC_KP8,
+ down);
+ break;
+ case myVK_PRIOR:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_formac_PageUp : MKC_KP9,
+ down);
+ break;
+ case VK_LEFT:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_Left : MKC_KP4,
+ down);
+ break;
+ case myVK_CLEAR:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_Clear : MKC_KP5,
+ down);
+ break;
+ case VK_RIGHT:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_Right : MKC_KP6,
+ down);
+ break;
+ case myVK_END:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_formac_End : MKC_KP1,
+ down);
+ break;
+ case VK_DOWN:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_Down : MKC_KP2,
+ down);
+ break;
+ case myVK_NEXT:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_formac_PageDown : MKC_KP3,
+ down);
+ break;
+ case myVK_INSERT:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_formac_Help : MKC_KP0,
+ down);
+ break;
+ case myVK_DELETE:
+ Keyboard_UpdateKeyMap2(TestBit(flags, 0)
+ ? MKC_formac_ForwardDel : MKC_Decimal,
+ down);
+ break;
+ case VK_CAPITAL:
+ CheckTheCapsLock();
+ break;
+ default:
+ if ((i >= 0) && (i < 256)) {
+ DoVKcode0(i, down);
+ }
+ break;
+ }
+}
+
+LOCALVAR blnr WantCmdOptOnReconnect = falseblnr;
+
+LOCALPROC ReconnectKeyCodes3(void)
+{
+ int i;
+
+ CheckTheCapsLock();
+
+ if (WantCmdOptOnReconnect) {
+ WantCmdOptOnReconnect = falseblnr;
+
+ for (i = 0; i < 256; ++i) {
+ if ((GetKeyState(i) & 0x8000) != 0) {
+ if ((VK_CAPITAL != i)
+ && (VK_RETURN != i))
+ {
+ DoVKcode0(i, trueblnr);
+ }
+ }
+ }
+ }
+}
+
+LOCALPROC DisconnectKeyCodes3(void)
+{
+ DisconnectKeyCodes2();
+ SetCurMouseButton(falseblnr);
+}
+
+#if EnableGrabSpecialKeys
+static HHOOK hKeyHook = NULL;
+#endif
+
+#if EnableGrabSpecialKeys
+typedef struct {
+ DWORD vkCode;
+ DWORD scanCode;
+ DWORD flags;
+ DWORD time;
+ DWORD dwExtraInfo;
+} My_KBDLLHOOKSTRUCT;
+#endif
+
+#if EnableGrabSpecialKeys
+LRESULT CALLBACK LowLevelKeyboardProc(
+ int nCode, /* hook code */
+ WPARAM wParam, /* message identifier */
+ LPARAM lParam /* pointer to structure with message data */
+);
+#endif
+
+#if EnableGrabSpecialKeys
+LRESULT CALLBACK LowLevelKeyboardProc(
+ int nCode, /* hook code */
+ WPARAM wParam, /* message identifier */
+ LPARAM lParam /* pointer to structure with message data */
+)
+{
+ if (nCode == HC_ACTION) {
+ My_KBDLLHOOKSTRUCT *p = (My_KBDLLHOOKSTRUCT *)lParam;
+ if (p->vkCode != VK_CAPITAL) {
+ switch (wParam) {
+ case WM_KEYDOWN:
+ case WM_SYSKEYDOWN:
+ DoVKcode(p->vkCode, p->flags, trueblnr);
+ return 1;
+ break;
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ DoVKcode(p->vkCode, p->flags, falseblnr);
+ return 1;
+ break;
+ }
+ }
+ }
+ return CallNextHookEx(hKeyHook, /* handle to current hook */
+ nCode, /* hook code passed to hook procedure */
+ wParam, /* value passed to hook procedure */
+ lParam /* value passed to hook procedure */
+ );
+
+}
+#endif
+
+#if EnableGrabSpecialKeys
+#define My_WH_KEYBOARD_LL 13
+#define My_SPI_SETSCREENSAVERRUNNING 0x0061
+#endif
+
+#if EnableGrabSpecialKeys
+LOCALVAR UINT nPreviousState;
+#endif
+
+#if EnableGrabSpecialKeys
+LOCALPROC GrabSpecialKeys(void)
+{
+ if ((hKeyHook == NULL) && ! HaveSetSysParam) {
+ /* this works on Windows XP */
+ hKeyHook = SetWindowsHookEx(
+ My_WH_KEYBOARD_LL, /* type of hook to install */
+ (HOOKPROC)LowLevelKeyboardProc,
+ /* address of hook procedure */
+ AppInstance, /* handle to application instance */
+ 0 /* identity of thread to install hook for */
+ );
+ if (hKeyHook == NULL) {
+ /* this works on Windows 95/98 */
+ SystemParametersInfo(My_SPI_SETSCREENSAVERRUNNING, TRUE,
+ &nPreviousState, 0);
+ HaveSetSysParam = trueblnr;
+ }
+ }
+}
+#endif
+
+#if EnableGrabSpecialKeys
+LOCALPROC UnGrabSpecialKeys(void)
+{
+ if (hKeyHook != NULL) {
+ (void) UnhookWindowsHookEx(hKeyHook);
+ hKeyHook = NULL;
+ }
+ if (HaveSetSysParam) {
+ SystemParametersInfo(My_SPI_SETSCREENSAVERRUNNING, FALSE,
+ &nPreviousState, 0);
+ HaveSetSysParam = falseblnr;
+ }
+}
+#endif
+
+/* --- priority --- */
+
+#ifndef EnableChangePriority
+#if UseWinCE
+#define EnableChangePriority 0
+#else
+#define EnableChangePriority MayFullScreen
+#endif
+#endif /* EnableChangePriority */
+
+#if EnableChangePriority
+LOCALVAR blnr MyPriorityRaised = falseblnr;
+#endif
+
+#if EnableChangePriority
+LOCALPROC RaiseMyPriority(void)
+{
+ if (! MyPriorityRaised) {
+ if (! SetPriorityClass(
+ GetCurrentProcess(), /* handle to the process */
+ HIGH_PRIORITY_CLASS
+ /* REALTIME_PRIORITY_CLASS (not, killer) */
+ /* priority class value */
+ ))
+ {
+ /*
+ not recursive:
+ MacMsg("SetPriorityClass failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ */
+ }
+ MyPriorityRaised = trueblnr;
+ }
+}
+#endif
+
+#if EnableChangePriority
+LOCALPROC LowerMyPriority(void)
+{
+ if (MyPriorityRaised) {
+ if (! SetPriorityClass(
+ GetCurrentProcess(), /* handle to the process */
+ NORMAL_PRIORITY_CLASS /* priority class value */
+ ))
+ {
+ /*
+ not recursive:
+ MacMsg("SetPriorityClass failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ */
+ }
+ MyPriorityRaised = falseblnr;
+ }
+}
+#endif
+
+
+/* --- time, date, location --- */
+
+#define dbglog_TimeStuff (0 && dbglog_HAVE)
+
+LOCALVAR ui5b TrueEmulatedTime = 0;
+
+#define MyInvTimeDivPow 16
+#define MyInvTimeDiv (1 << MyInvTimeDivPow)
+#define MyInvTimeDivMask (MyInvTimeDiv - 1)
+#define MyInvTimeStep 1089590 /* 1000 / 60.14742 * MyInvTimeDiv */
+
+LOCALVAR DWORD LastTime;
+
+LOCALVAR DWORD NextIntTime;
+LOCALVAR ui5b NextFracTime;
+
+LOCALPROC IncrNextTime(void)
+{
+ NextFracTime += MyInvTimeStep;
+ NextIntTime += (NextFracTime >> MyInvTimeDivPow);
+ NextFracTime &= MyInvTimeDivMask;
+}
+
+LOCALPROC InitNextTime(void)
+{
+ NextIntTime = LastTime;
+ NextFracTime = 0;
+ IncrNextTime();
+}
+
+LOCALFUNC blnr UpdateTrueEmulatedTime(void)
+{
+ DWORD LatestTime;
+ si5b TimeDiff;
+
+ LatestTime = timeGetTime();
+ if (LatestTime != LastTime) {
+ LastTime = LatestTime;
+ TimeDiff = (LatestTime - NextIntTime);
+ /* this should work even when time wraps */
+ if (TimeDiff >= 0) {
+ if (TimeDiff > 256) {
+ /* emulation interrupted, forget it */
+ ++TrueEmulatedTime;
+ InitNextTime();
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("emulation interrupted",
+ TrueEmulatedTime);
+#endif
+ } else {
+ do {
+ ++TrueEmulatedTime;
+ IncrNextTime();
+ TimeDiff = (LatestTime - NextIntTime);
+ } while (TimeDiff >= 0);
+ }
+ return trueblnr;
+ } else if (TimeDiff < -256) {
+ /* clock goofed if ever get here, reset */
+#if dbglog_TimeStuff
+ dbglog_writeln("clock set back");
+#endif
+
+ InitNextTime();
+ }
+ }
+ return falseblnr;
+}
+
+LOCALVAR ui5b TimeSecBase;
+LOCALVAR DWORD TimeMilliBase;
+
+#include "DATE2SEC.h"
+
+LOCALFUNC blnr CheckDateTime(void)
+{
+ ui5b NewMacDateInSecond;
+
+ NewMacDateInSecond =
+ ((ui5b)(LastTime - TimeMilliBase)) / 1000 + TimeSecBase;
+ if (CurMacDateInSeconds != NewMacDateInSecond) {
+ CurMacDateInSeconds = NewMacDateInSecond;
+
+ return trueblnr;
+ } else {
+ return falseblnr;
+ }
+}
+
+LOCALFUNC blnr Init60thCheck(void)
+{
+ SYSTEMTIME s;
+#if AutoTimeZone
+ TIME_ZONE_INFORMATION r;
+ DWORD v;
+#endif
+ DWORD t;
+
+ GetLocalTime(&s);
+ t = timeGetTime();
+ TimeSecBase = Date2MacSeconds(s.wSecond, s.wMinute, s.wHour,
+ s.wDay, s.wMonth, s.wYear);
+ TimeMilliBase = t - s.wMilliseconds;
+
+#if AutoTimeZone
+ v = GetTimeZoneInformation(&r);
+ if ((v != 0xFFFFFFFF) && (v != TIME_ZONE_ID_UNKNOWN)) {
+ si5b dlsBias = (v != TIME_ZONE_ID_DAYLIGHT)
+ ? r.StandardBias : r.DaylightBias;
+ CurMacDelta = (((ui5b)(- (r.Bias + dlsBias) * 60))
+ & 0x00FFFFFF)
+ | (((v != TIME_ZONE_ID_DAYLIGHT) ? 0 : 0x80)
+ << 24);
+ }
+#endif
+
+ LastTime = timeGetTime();
+ InitNextTime();
+
+ OnTrueTime = TrueEmulatedTime;
+
+ (void) CheckDateTime();
+
+ return trueblnr;
+}
+
+#ifndef MyTimeResolution
+#define MyTimeResolution 3
+#endif
+ /*
+ Setting MyTimeResolution to 1 seems to drastically slow down
+ the clock in Virtual PC 7.0.2 for Mac. Using 3 is more polite
+ anyway, and should not cause much observable difference.
+ */
+
+#if (MyTimeResolution != 0)
+LOCALVAR blnr HaveSetTimeResolution = falseblnr;
+#endif
+
+#if (MyTimeResolution != 0)
+LOCALPROC MyTimer_Suspend(void)
+{
+ if (HaveSetTimeResolution) {
+ (void) timeEndPeriod(MyTimeResolution);
+ HaveSetTimeResolution = falseblnr;
+ }
+}
+#endif
+
+#if (MyTimeResolution != 0)
+LOCALPROC MyTimer_Resume(void)
+{
+ TIMECAPS tc;
+
+ if (timeGetDevCaps(&tc, sizeof(TIMECAPS))
+ == TIMERR_NOERROR)
+ {
+ if ((MyTimeResolution >= tc.wPeriodMin)
+ && (MyTimeResolution <= tc.wPeriodMax))
+ {
+ if (timeBeginPeriod(MyTimeResolution)
+ == TIMERR_NOERROR)
+ {
+ HaveSetTimeResolution = trueblnr;
+ }
+ }
+ }
+}
+#endif
+
+/* --- sound --- */
+
+#if MySoundEnabled
+
+
+#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */
+#define kSoundBuffers (1 << kLn2SoundBuffers)
+#define kSoundBuffMask (kSoundBuffers - 1)
+
+#define DesiredMinFilledSoundBuffs 3
+ /*
+ if too big then sound lags behind emulation.
+ if too small then sound will have pauses.
+ */
+
+#define kLnOneBuffLen 9
+#define kLnAllBuffLen (kLn2SoundBuffers + kLnOneBuffLen)
+#define kOneBuffLen (1UL << kLnOneBuffLen)
+#define kAllBuffLen (1UL << kLnAllBuffLen)
+#define kLnOneBuffSz (kLnOneBuffLen + kLn2SoundSampSz - 3)
+#define kLnAllBuffSz (kLnAllBuffLen + kLn2SoundSampSz - 3)
+#define kOneBuffSz (1UL << kLnOneBuffSz)
+#define kAllBuffSz (1UL << kLnAllBuffSz)
+#define kOneBuffMask (kOneBuffLen - 1)
+#define kAllBuffMask (kAllBuffLen - 1)
+#define dbhBufferSize (kAllBuffSz + kOneBuffSz)
+
+#define dbglog_SoundStuff (0 && dbglog_HAVE)
+#define dbglog_SoundBuffStats (0 && dbglog_HAVE)
+
+LOCALVAR tpSoundSamp TheSoundBuffer = nullpr;
+LOCALVAR ui4b ThePlayOffset;
+LOCALVAR ui4b TheFillOffset;
+LOCALVAR blnr wantplaying;
+LOCALVAR ui4b MinFilledSoundBuffs;
+LOCALVAR ui4b TheWriteOffset;
+
+#define SOUND_SAMPLERATE /* 22050 */ 22255
+ /* = round(7833600 * 2 / 704) */
+
+
+LOCALPROC FillWithSilence(tpSoundSamp p, int n, trSoundSamp v)
+{
+ int i;
+
+ for (i = n; --i >= 0; ) {
+ *p++ = v;
+ }
+}
+
+
+LOCALVAR HWAVEOUT hWaveOut = NULL;
+LOCALVAR WAVEHDR whdr[kSoundBuffers];
+
+
+LOCALPROC MySound_BeginPlaying(void)
+{
+#if dbglog_SoundStuff
+ fprintf(stderr, "MySound_BeginPlaying\n");
+#endif
+}
+
+LOCALPROC MySound_Start(void)
+{
+ if (hWaveOut == NULL) {
+ WAVEFORMATEX wfex;
+ MMRESULT mmr;
+ int i;
+ tpSoundSamp p;
+ WAVEHDR *pwh;
+
+ wfex.wFormatTag = WAVE_FORMAT_PCM;
+ wfex.nChannels = 1;
+ wfex.nSamplesPerSec = SOUND_SAMPLERATE;
+ wfex.nAvgBytesPerSec = SOUND_SAMPLERATE;
+#if 3 == kLn2SoundSampSz
+ wfex.nBlockAlign = 1;
+ wfex.wBitsPerSample = 8;
+#elif 4 == kLn2SoundSampSz
+ wfex.nBlockAlign = 2;
+ wfex.wBitsPerSample = 16;
+#else
+#error "unsupported audio format"
+#endif
+ wfex.cbSize = 0;
+ mmr = waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfex, 0,
+ 0 /* (DWORD) AppInstance */, CALLBACK_NULL);
+ if (mmr != MMSYSERR_NOERROR) {
+ /*
+ not recursive:
+ MacMsg("waveOutOpen failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ */
+ } else {
+ p = TheSoundBuffer;
+ pwh = whdr;
+ for (i = 0; i < kSoundBuffers; ++i) {
+ pwh->lpData = (LPSTR)p;
+ pwh->dwBufferLength = kOneBuffSz;
+ pwh->dwBytesRecorded = 0;
+ pwh->dwUser = 0;
+ pwh->dwFlags = 0;
+ pwh->dwLoops = 0;
+ mmr = waveOutPrepareHeader(hWaveOut, pwh,
+ sizeof(WAVEHDR));
+ if (mmr != MMSYSERR_NOERROR) {
+ /*
+ not recursive:
+ MacMsg("waveOutPrepareHeader failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ */
+ } else {
+ pwh->dwFlags |= WHDR_DONE;
+ }
+ p += kOneBuffLen;
+ ++pwh;
+ }
+
+ TheFillOffset = 0;
+ ThePlayOffset = 0;
+ TheWriteOffset = 0;
+ MinFilledSoundBuffs = kSoundBuffers;
+ wantplaying = falseblnr;
+ }
+ }
+}
+
+LOCALPROC MySound_Stop(void)
+{
+ MMRESULT mmr;
+ int i;
+
+ wantplaying = falseblnr;
+ if (hWaveOut != NULL) {
+ DWORD StartTime = GetTickCount();
+ for (i = 0; i < kSoundBuffers; ++i) {
+ while (((whdr[i].dwFlags & WHDR_DONE) == 0)
+ && ((ui5b)(GetTickCount() - StartTime) < 1000))
+ {
+ Sleep(1);
+ }
+
+ mmr = waveOutUnprepareHeader(hWaveOut, &whdr[i],
+ sizeof(WAVEHDR));
+ if (mmr != MMSYSERR_NOERROR) {
+ /*
+ not recursive:
+ MacMsg("waveOutUnprepareHeader failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ */
+ }
+ }
+
+ mmr = waveOutClose(hWaveOut);
+ if (mmr != MMSYSERR_NOERROR) {
+ /*
+ MacMsg("waveOutClose failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ */
+ }
+ hWaveOut = NULL;
+ }
+}
+
+LOCALPROC SoundCheckVeryOften(void)
+{
+ if ((hWaveOut != NULL) && (wantplaying)) {
+label_retry:
+ {
+ ui4b FilledSoundBuffs;
+ ui4b ToPlaySize = TheFillOffset - ThePlayOffset;
+ ui4b CurPlayBuffer =
+ (ThePlayOffset >> kLnOneBuffLen) & kSoundBuffMask;
+
+ if ((ToPlaySize > kOneBuffLen)
+ && ((whdr[CurPlayBuffer].dwFlags & WHDR_DONE) != 0))
+ {
+ ThePlayOffset += kOneBuffLen;
+ goto label_retry;
+ }
+ FilledSoundBuffs = ToPlaySize >> kLnOneBuffLen;
+
+ if (FilledSoundBuffs < MinFilledSoundBuffs) {
+ MinFilledSoundBuffs = FilledSoundBuffs;
+ }
+
+ if (FilledSoundBuffs < 2) {
+ MMRESULT mmr;
+ ui4b PrevPlayOffset = ThePlayOffset - kOneBuffLen;
+ ui4b PrevPlayBuffer =
+ (PrevPlayOffset >> kLnOneBuffLen) & kSoundBuffMask;
+ ui4b LastPlayedOffset =
+ ((TheFillOffset >> kLnOneBuffLen) << kLnOneBuffLen)
+ - 1;
+
+ FillWithSilence(
+ TheSoundBuffer + (PrevPlayOffset & kAllBuffMask),
+ kOneBuffLen,
+ *(TheSoundBuffer
+ + (LastPlayedOffset & kAllBuffMask)));
+ mmr = waveOutWrite(
+ hWaveOut, &whdr[PrevPlayBuffer], sizeof(WAVEHDR));
+ if (mmr != MMSYSERR_NOERROR) {
+ whdr[PrevPlayBuffer].dwFlags |= WHDR_DONE;
+ /*
+ not recursive:
+ MacMsg("waveOutWrite failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ */
+ }
+ ThePlayOffset = PrevPlayOffset;
+ goto label_retry;
+ }
+ }
+ }
+}
+
+#if 4 == kLn2SoundSampSz
+LOCALPROC ConvertSoundBlockToNative(tpSoundSamp p)
+{
+ int i;
+
+ for (i = kOneBuffLen; --i >= 0; ) {
+ *p++ -= 0x8000;
+ }
+}
+#else
+#define ConvertSoundBlockToNative(p)
+#endif
+
+LOCALPROC MySound_FilledBlocks(void)
+{
+ while (0 != ((TheWriteOffset - TheFillOffset) >> kLnOneBuffLen)) {
+ ui4b CurFillBuffer =
+ (TheFillOffset >> kLnOneBuffLen) & kSoundBuffMask;
+ blnr IsOk = falseblnr;
+
+ ConvertSoundBlockToNative((tpSoundSamp)
+ whdr[CurFillBuffer].lpData);
+
+ if (hWaveOut != NULL) {
+ MMRESULT mmr = waveOutWrite(hWaveOut,
+ &whdr[CurFillBuffer], sizeof(WAVEHDR));
+ if (mmr == MMSYSERR_NOERROR) {
+ IsOk = trueblnr;
+ }
+ }
+
+ if (! IsOk) {
+ /*
+ not recursive:
+ MacMsg("waveOutWrite failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ */
+ whdr[CurFillBuffer].dwFlags |= WHDR_DONE;
+ }
+
+ TheFillOffset += kOneBuffLen;
+ }
+}
+
+LOCALPROC MySound_WroteABlock(void)
+{
+ if (wantplaying) {
+ MySound_FilledBlocks();
+ } else if (((TheWriteOffset - ThePlayOffset) >> kLnOneBuffLen) < 12)
+ {
+ /* just wait */
+ } else {
+ MySound_FilledBlocks();
+ wantplaying = trueblnr;
+ MySound_BeginPlaying();
+ }
+}
+
+GLOBALOSGLUPROC MySound_EndWrite(ui4r actL)
+{
+ TheWriteOffset += actL;
+
+ if (0 == (TheWriteOffset & kOneBuffMask)) {
+ /* just finished a block */
+
+ MySound_WroteABlock();
+ }
+}
+
+GLOBALOSGLUFUNC tpSoundSamp MySound_BeginWrite(ui4r n, ui4r *actL)
+{
+ ui4b ToFillLen = kAllBuffLen - (TheWriteOffset - ThePlayOffset);
+ ui4b WriteBuffContig =
+ kOneBuffLen - (TheWriteOffset & kOneBuffMask);
+
+ if (WriteBuffContig < n) {
+ n = WriteBuffContig;
+ }
+ if (ToFillLen < n) {
+ /* overwrite previous buffer */
+ TheWriteOffset -= kOneBuffLen;
+ }
+
+ *actL = n;
+ return TheSoundBuffer + (TheWriteOffset & kAllBuffMask);
+}
+
+LOCALPROC MySound_SecondNotify(void)
+{
+ if (hWaveOut != NULL) {
+ if (MinFilledSoundBuffs > DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too high");
+#endif
+ IncrNextTime();
+ } else if (MinFilledSoundBuffs < DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too low");
+#endif
+ ++TrueEmulatedTime;
+ }
+ MinFilledSoundBuffs = kSoundBuffers;
+ }
+}
+
+#endif
+
+/* --- overall grab --- */
+
+#if MayFullScreen
+LOCALPROC GrabTheMachine(void)
+{
+#if EnableFSMouseMotion
+ StartSaveMouseMotion();
+#endif
+#if EnableChangePriority
+ if ((ui3b) -1 == SpeedValue) {
+ RaiseMyPriority();
+ }
+#endif
+#if EnableGrabSpecialKeys
+ GrabSpecialKeys();
+#endif
+}
+#endif
+
+#if MayFullScreen
+LOCALPROC UnGrabTheMachine(void)
+{
+#if EnableGrabSpecialKeys
+ UnGrabSpecialKeys();
+#endif
+#if EnableFSMouseMotion
+ StopSaveMouseMotion();
+#endif
+#if EnableChangePriority
+ LowerMyPriority();
+#endif
+}
+#endif
+
+#if MayFullScreen
+LOCALVAR blnr GrabMachine = falseblnr;
+#endif
+
+#if MayFullScreen
+LOCALPROC AdjustMachineGrab(void)
+{
+ if (GrabMachine) {
+ if (MainWnd != NULL) {
+ GrabTheMachine();
+ }
+ } else {
+ UnGrabTheMachine();
+ }
+}
+#endif
+
+/* --- basic dialogs --- */
+
+LOCALPROC MyBeginDialog(void)
+{
+ DisconnectKeyCodes3();
+#if MayFullScreen
+ GrabMachine = falseblnr;
+ UnGrabTheMachine();
+#endif
+ ForceShowCursor();
+}
+
+LOCALPROC MyEndDialog(void)
+{
+ ReconnectKeyCodes3();
+}
+
+LOCALPROC CheckSavedMacMsg(void)
+{
+ if (nullpr != SavedBriefMsg) {
+ TCHAR briefMsg0[ClStrMaxLength + 1];
+ TCHAR longMsg0[ClStrMaxLength + 1];
+
+ NativeStrFromCStr(briefMsg0, SavedBriefMsg, falseblnr);
+ NativeStrFromCStr(longMsg0, SavedLongMsg, falseblnr);
+
+ MessageBox(MainWnd, longMsg0, briefMsg0,
+ MB_APPLMODAL | MB_OK | (SavedFatalMsg ? MB_ICONSTOP : 0));
+
+ SavedBriefMsg = nullpr;
+ }
+}
+
+/* --- main window --- */
+
+enum {
+ ID_MENU_NULL = 256,
+ ID_FILE_INSERTDISK1,
+ ID_FILE_QUIT,
+ ID_SPECIAL_MORECOMMANDS,
+ ID_HELP_ABOUT,
+
+ kNum_ID_MENU
+};
+
+
+#if (1 == vMacScreenDepth) || (vMacScreenDepth >= 4)
+#define EnableScalingBuff 1
+#else
+#define EnableScalingBuff (1 && EnableMagnify && (MyWindowScale == 2))
+#endif
+
+#if EnableScalingBuff
+LOCALVAR ui3p ScalingBuff = NULL;
+#endif
+
+LOCALVAR HDC MainWndDC = NULL;
+
+LOCALVAR si5b CmdShow;
+
+LOCALVAR TCHAR WndTitle[_MAX_PATH];
+LOCALVAR const TCHAR WndClassName[] = TEXT("minivmac");
+
+LOCALVAR blnr gBackgroundFlag = falseblnr;
+LOCALVAR blnr gTrueBackgroundFlag = falseblnr;
+LOCALVAR blnr CurSpeedStopped = trueblnr;
+
+LOCALPROC GetWndTitle(void)
+{
+ TCHAR pathName[_MAX_PATH];
+ WIN32_FIND_DATA fd;
+ blnr IsOk = falseblnr;
+
+ if (GetModuleFileName(AppInstance, pathName, _MAX_PATH) != 0) {
+ HANDLE hf = FindFirstFile(pathName, &fd);
+
+ if (hf != INVALID_HANDLE_VALUE) {
+ /* get rid of extension, presumably '.exe' */
+ LPTSTR p = FindLastTerm(fd.cFileName,
+ (TCHAR)('.'));
+ if (p != nullpr) {
+ *--p = (TCHAR)('\0');
+ }
+
+ _tcscpy(WndTitle, fd.cFileName);
+ IsOk = trueblnr;
+ FindClose(hf);
+ }
+ }
+ if (! IsOk) {
+ _tcscpy(WndTitle, TEXT(kStrAppName));
+ }
+}
+
+LOCALPROC DisposeMainWindow(void)
+{
+#if UseWinCE
+ /* Show the taskbar */
+ SHFullScreen(MainWnd, SHFS_SHOWTASKBAR);
+#endif
+
+ if (MainWndDC != NULL) {
+ ReleaseDC(MainWnd, MainWndDC);
+ }
+ if (MainWnd != NULL) {
+ DestroyWindow(MainWnd);
+ MainWnd = NULL; /* so MacMsg will still work */
+ }
+}
+
+enum {
+ kMagStateNormal,
+#if EnableMagnify
+ kMagStateMagnifgy,
+#endif
+ kNumMagStates
+};
+
+#define kMagStateAuto kNumMagStates
+
+#if MayNotFullScreen
+LOCALVAR int CurWinIndx;
+LOCALVAR blnr HavePositionWins[kNumMagStates];
+LOCALVAR POINT WinPositionWins[kNumMagStates];
+#endif
+
+#if MayNotFullScreen
+LOCALPROC MyAppendConvertMenuItem(HMENU hMenu,
+ UINT uIDNewItem, char *s, blnr AddEllipsis)
+{
+ TCHAR ts[ClStrMaxLength + 1];
+
+ NativeStrFromCStr(ts, s, AddEllipsis);
+
+ (void) AppendMenu(hMenu, MF_ENABLED + MF_STRING,
+ uIDNewItem, ts);
+}
+#endif
+
+#if MayNotFullScreen
+LOCALPROC MyAppendSubmenuConvertName(HMENU hMenu,
+ HMENU hSubMenu, char *s)
+{
+ TCHAR ts[ClStrMaxLength + 1];
+ MENUITEMINFO mii;
+
+ NativeStrFromCStr(ts, s, falseblnr);
+
+#if 0
+ (void) InsertMenu(hMenu, 0xFFFFFFFF,
+ MF_BYPOSITION + MF_POPUP + MF_STRING + MF_ENABLED,
+ (UINT)hSubMenu, ts);
+#endif
+
+ memset(&mii, 0, sizeof(MENUITEMINFO));
+ mii.cbSize = sizeof(MENUITEMINFO);
+ mii.fMask = MIIM_TYPE | MIIM_SUBMENU;
+ mii.fType = MFT_STRING;
+ mii.hSubMenu = hSubMenu;
+ mii.dwTypeData = ts;
+ mii.cch = (UINT)_tcslen(ts);
+ (void) InsertMenuItem(hMenu, (UINT) -1, TRUE,
+ &mii);
+}
+#endif
+
+#ifndef kStrMenuFile_win
+#define kStrMenuFile_win kStrMenuFile
+#endif
+
+LOCALFUNC blnr ReCreateMainWindow(void)
+{
+#if MayNotFullScreen
+ HMENU m;
+ int DfltWndX;
+ int DfltWndY;
+ int WinIndx;
+#endif
+ HMENU mb;
+ HWND NewMainWindow;
+ HDC NewMainWndDC = NULL;
+ int ScreenX = GetSystemMetrics(SM_CXSCREEN);
+ int ScreenY = GetSystemMetrics(SM_CYSCREEN);
+ short NewWindowHeight = vMacScreenHeight;
+ short NewWindowWidth = vMacScreenWidth;
+ HWND OldMainWindow = MainWnd;
+ HDC OldMainWndDC = MainWndDC;
+ RECT NewWinR;
+ DWORD MyWStyle;
+ DWORD MyWExStyle;
+
+#if VarFullScreen
+ if (! UseFullScreen)
+#endif
+#if MayNotFullScreen
+ {
+ /* save old position */
+ if (OldMainWindow != NULL) {
+ WinPositionWins[CurWinIndx].x = WndX;
+ WinPositionWins[CurWinIndx].y = WndY;
+ }
+ }
+#endif
+
+#if MayNotFullScreen
+#if EnableMagnify
+ if (WantMagnify) {
+ WinIndx = kMagStateMagnifgy;
+ } else
+#endif
+ {
+ WinIndx = kMagStateNormal;
+ }
+#endif
+
+#if EnableMagnify
+ if (WantMagnify) {
+ NewWindowHeight *= MyWindowScale;
+ NewWindowWidth *= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (WantFullScreen)
+#endif
+#if MayFullScreen
+ {
+ MyWStyle = WS_VISIBLE | WS_POPUP;
+ MyWExStyle = WS_EX_TOPMOST;
+
+ hOffset = (ScreenX - NewWindowWidth) / 2;
+ vOffset = (ScreenY - NewWindowHeight) / 2;
+ if (hOffset < 0) {
+ hOffset = 0;
+ }
+ if (vOffset < 0) {
+ vOffset = 0;
+ }
+
+ NewWinR.left = 0;
+ NewWinR.top = 0;
+ NewWinR.right = ScreenX;
+ NewWinR.bottom = ScreenY;
+ }
+#endif
+#if VarFullScreen
+ else
+#endif
+#if MayNotFullScreen
+ {
+ MyWStyle = WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU
+ | WS_MINIMIZEBOX;
+ MyWExStyle = WS_EX_ACCEPTFILES;
+
+ DfltWndX = (ScreenX - NewWindowWidth) / 2;
+ DfltWndY = (ScreenY - NewWindowHeight) / 2;
+
+ if (DfltWndX < 0) {
+ DfltWndX = 0;
+ }
+ if (DfltWndY < 0) {
+ DfltWndY = 0;
+ }
+
+ if (! HavePositionWins[WinIndx]) {
+ WinPositionWins[WinIndx].x = DfltWndX;
+ WinPositionWins[WinIndx].y = DfltWndY;
+ HavePositionWins[WinIndx] = trueblnr;
+ }
+
+ NewWinR.left = WinPositionWins[WinIndx].x;
+ NewWinR.top = WinPositionWins[WinIndx].y;
+ NewWinR.right = NewWinR.left + NewWindowWidth;
+ NewWinR.bottom = NewWinR.top + NewWindowHeight;
+
+ (void) AdjustWindowRectEx(&NewWinR, MyWStyle, TRUE, MyWExStyle);
+
+ if ((NewWinR.right <= 0)
+ || (NewWinR.left >= ScreenX)
+ || (NewWinR.bottom <= 0)
+ || (NewWinR.top >= ScreenY))
+ {
+ NewWinR.left = DfltWndX;
+ NewWinR.top = DfltWndY;
+ NewWinR.right = DfltWndX + NewWindowWidth;
+ NewWinR.bottom = DfltWndY + NewWindowHeight;
+
+ (void) AdjustWindowRectEx(&NewWinR,
+ MyWStyle, TRUE, MyWExStyle);
+ }
+ }
+#endif
+
+ if ((OldMainWindow == NULL)
+#if VarFullScreen
+ || (WantFullScreen != UseFullScreen)
+#endif
+ )
+ {
+
+#if VarFullScreen
+ if (WantFullScreen)
+#endif
+#if MayFullScreen
+ {
+ mb = NULL;
+ }
+#endif
+#if VarFullScreen
+ else
+#endif
+#if MayNotFullScreen
+ {
+ mb = CreateMenu();
+ if (mb != NULL) {
+ m = CreateMenu();
+ if (m != NULL) {
+ MyAppendConvertMenuItem(m, ID_FILE_INSERTDISK1,
+ kStrMenuItemOpen, trueblnr);
+ (void) AppendMenu(m, MF_SEPARATOR, 0, NULL);
+ MyAppendConvertMenuItem(m, ID_FILE_QUIT,
+ kStrMenuItemQuit, falseblnr);
+ MyAppendSubmenuConvertName(mb, m, kStrMenuFile_win);
+ }
+ m = CreateMenu();
+ if (m != NULL) {
+ MyAppendConvertMenuItem(m, ID_SPECIAL_MORECOMMANDS,
+ kStrMenuItemMore, trueblnr);
+ MyAppendSubmenuConvertName(mb, m, kStrMenuSpecial);
+ }
+ m = CreateMenu();
+ if (m != NULL) {
+ MyAppendConvertMenuItem(m, ID_HELP_ABOUT,
+ kStrMenuItemAbout, trueblnr);
+ MyAppendSubmenuConvertName(mb, m, kStrMenuHelp);
+ }
+ }
+ }
+#endif
+
+ NewMainWindow = CreateWindowEx(
+ MyWExStyle,
+ WndClassName,
+ WndTitle,
+ MyWStyle,
+ NewWinR.left, NewWinR.top,
+ NewWinR.right - NewWinR.left, NewWinR.bottom - NewWinR.top,
+ NULL,
+ mb,
+ AppInstance, NULL);
+ if (NewMainWindow == NULL) {
+ MacMsg("CreateWindow failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ return falseblnr;
+ }
+
+ NewMainWndDC = GetDC(NewMainWindow);
+ if (NewMainWndDC == NULL) {
+ MacMsg("GetDC failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ DestroyWindow(NewMainWindow);
+ return falseblnr;
+ }
+ } else {
+ NewMainWndDC = OldMainWndDC;
+ NewMainWindow = OldMainWindow;
+ (void) MoveWindow(NewMainWindow, NewWinR.left, NewWinR.top,
+ NewWinR.right - NewWinR.left, NewWinR.bottom - NewWinR.top,
+ TRUE);
+ }
+
+#if 0 != vMacScreenDepth
+ ColorModeWorks = trueblnr;
+#endif
+
+ {
+ POINT p;
+
+ /*
+ Find out where the window really went, on
+ the off chance that the WM_MOVE message wasn't
+ called on CreateWindowEx/MoveWindow, or that
+ the window wasn't put where asked for.
+ */
+ p.x = 0;
+ p.y = 0;
+ (void) MapWindowPoints(NewMainWindow, NULL, &p, 1);
+ WndX = (si4b)p.x;
+ WndY = (si4b)p.y;
+ }
+
+#if MayFullScreen
+ GrabMachine = falseblnr;
+ UnGrabTheMachine();
+#endif
+
+#if UseWinCE && 0
+ /* Show the taskbar */
+ SHFullScreen(MainWnd, SHFS_SHOWTASKBAR);
+#endif
+
+#if MayNotFullScreen
+ CurWinIndx = WinIndx;
+#endif
+
+ MainWnd = NewMainWindow;
+ MainWndDC = NewMainWndDC;
+ gTrueBackgroundFlag = falseblnr;
+#if VarFullScreen
+ UseFullScreen = WantFullScreen;
+#endif
+#if EnableMagnify
+ UseMagnify = WantMagnify;
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ ViewHSize = ScreenX;
+ ViewVSize = ScreenY;
+#if EnableMagnify
+ if (UseMagnify) {
+ ViewHSize /= MyWindowScale;
+ ViewVSize /= MyWindowScale;
+ }
+#endif
+ if (ViewHSize >= vMacScreenWidth) {
+ ViewHStart = 0;
+ ViewHSize = vMacScreenWidth;
+ } else {
+ ViewHSize &= ~ 1;
+ }
+ if (ViewVSize >= vMacScreenHeight) {
+ ViewVStart = 0;
+ ViewVSize = vMacScreenHeight;
+ } else {
+ ViewVSize &= ~ 1;
+ }
+ }
+#endif
+
+ if (NewMainWindow != OldMainWindow) {
+ ShowWindow(NewMainWindow, SW_SHOW /* CmdShow */);
+ if (OldMainWndDC != NULL) {
+ ReleaseDC(MainWnd, OldMainWndDC);
+ }
+ if (OldMainWindow != NULL) {
+ /* ShowWindow(OldMainWindow, SW_HIDE); */
+ DestroyWindow(OldMainWindow);
+ }
+
+ DisconnectKeyCodes3();
+ /* since key events per window */
+ } else {
+ (void) InvalidateRgn(MainWnd, NULL, FALSE);
+ }
+
+#if UseWinCE
+ /* Create and set logical palette for this window */
+ {
+ HPALETTE hpal;
+ LOGPALETTE *lppal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +
+ sizeof(PALETTEENTRY) * 2);
+
+ if (! lppal)
+ {
+ MacMsg("CreateWindow failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ return falseblnr;
+ }
+
+ lppal->palNumEntries = 2;
+ lppal->palVersion = 0x0300;
+ lppal->palPalEntry[0].peRed = 255;
+ lppal->palPalEntry[0].peGreen = 255;
+ lppal->palPalEntry[0].peBlue = 255;
+ lppal->palPalEntry[0].peFlags = 0;
+ lppal->palPalEntry[1].peRed = 0;
+ lppal->palPalEntry[1].peGreen = 0;
+ lppal->palPalEntry[1].peBlue = 0;
+ lppal->palPalEntry[1].peFlags = 0;
+
+ hpal = CreatePalette(lppal);
+
+ if (hpal == NULL) {
+ free(lppal);
+ MacMsg("CreateWindow failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ return falseblnr;
+ }
+
+ if (SelectPalette(MainWndDC, hpal, FALSE) == NULL) {
+ free(lppal);
+ MacMsg("CreateWindow failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ return falseblnr;
+ }
+
+ if (RealizePalette(MainWndDC) == GDI_ERROR) {
+ free(lppal);
+ MacMsg("CreateWindow failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ return falseblnr;
+ }
+
+ free(lppal);
+ }
+#endif
+
+#if UseWinCE
+ /* Hide the taskbar */
+ SHFullScreen(MainWnd, SHFS_HIDETASKBAR);
+ (void) MoveWindow(MainWnd, 0, 0,
+ ScreenX, ScreenY, TRUE);
+#endif
+
+ if (HaveCursorHidden) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ WantCursorHidden = trueblnr;
+ }
+
+ return trueblnr;
+}
+
+#if UseWinCE
+LOCALFUNC blnr AlreadyRunningCheck(void)
+{
+ /*
+ Adapted from example program from Microsoft eMbedded Visual C++
+ */
+
+ /* If it is already running, then focus on the window */
+ HWND hWnd = FindWindow(WndClassName, WndTitle);
+ if (hWnd == NULL) {
+ return falseblnr;
+ } else {
+ /*
+ Set focus to foremost child window.
+ The "| 0x01" is used to bring any owned
+ windows to the foreground and activate them.
+ */
+ SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));
+ return trueblnr;
+ }
+}
+#endif
+
+typedef struct BITMAPINFOHEADER256 {
+ BITMAPINFOHEADER bmi;
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ RGBQUAD colors[CLUT_size];
+#else
+ RGBQUAD colors[2];
+#endif
+} BITMAPINFOHEADER256;
+
+#if EnableMagnify
+#define MyScaledHeight (MyWindowScale * vMacScreenHeight)
+#define MyScaledWidth (MyWindowScale * vMacScreenWidth)
+#endif
+
+LOCALPROC HaveChangedScreenBuff(si4b top, si4b left,
+ si4b bottom, si4b right)
+{
+ BITMAPINFOHEADER256 bmh;
+ ui3b *cdb = GetCurDrawBuff();
+ int XDest;
+ int YDest;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ if (top < ViewVStart) {
+ top = ViewVStart;
+ }
+ if (left < ViewHStart) {
+ left = ViewHStart;
+ }
+ if (bottom > ViewVStart + ViewVSize) {
+ bottom = ViewVStart + ViewVSize;
+ }
+ if (right > ViewHStart + ViewHSize) {
+ right = ViewHStart + ViewHSize;
+ }
+
+ if ((top >= bottom) || (left >= right)) {
+ goto label_exit;
+ }
+ }
+#endif
+
+ XDest = left;
+ YDest = top;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ XDest -= ViewHStart;
+ YDest -= ViewVStart;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ XDest *= MyWindowScale;
+ YDest *= MyWindowScale;
+ }
+#endif
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ XDest += hOffset;
+ YDest += vOffset;
+ }
+#endif
+
+#if 0
+ { /* testing code */
+ if (PatBlt(MainWndDC,
+ (int)left - 1,
+ (int)top - 1,
+ (int)right - left + 2,
+ (int)bottom - top + 2, PATCOPY)) {
+ }
+ }
+#endif
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+ int i;
+ int nDestWidth = (right - left);
+ int nDestHeight = (bottom - top);
+#if 1 == vMacScreenDepth
+ ui3b *p
+ = ScalingBuff + ((ui5r)vMacScreenWidth / 4) * top;
+#elif vMacScreenDepth >= 4
+ ui3b *p = ScalingBuff + (ui5r)vMacScreenByteWidth * top;
+#else
+ ui3b *p = cdb + (ui5r)vMacScreenByteWidth * top;
+#endif
+
+ memset(&bmh, 0, sizeof (bmh));
+ bmh.bmi.biSize = sizeof(BITMAPINFOHEADER);
+ bmh.bmi.biWidth = vMacScreenWidth;
+ bmh.bmi.biHeight = - (bottom - top);
+ bmh.bmi.biPlanes = 1;
+#if 1 == vMacScreenDepth
+ bmh.bmi.biBitCount = 4;
+#else
+ bmh.bmi.biBitCount = (1 << vMacScreenDepth);
+#endif
+ bmh.bmi.biCompression= BI_RGB;
+ bmh.bmi.biSizeImage = 0;
+ bmh.bmi.biXPelsPerMeter = 0;
+ bmh.bmi.biYPelsPerMeter = 0;
+#if 1 == vMacScreenDepth
+ bmh.bmi.biClrUsed = 4;
+#else
+ bmh.bmi.biClrUsed = 0;
+#endif
+ bmh.bmi.biClrImportant = 0;
+
+#if vMacScreenDepth < 4
+ for (i = 0; i < CLUT_size; ++i) {
+ bmh.colors[i].rgbRed = CLUT_reds[i] >> 8;
+ bmh.colors[i].rgbGreen = CLUT_greens[i] >> 8;
+ bmh.colors[i].rgbBlue = CLUT_blues[i] >> 8;
+ bmh.colors[i].rgbReserved = 0;
+ }
+#endif
+
+#if 1 == vMacScreenDepth
+ {
+ int j;
+ ui3b *p1 = (ui3b *)(cdb + (ui5r)vMacScreenByteWidth * top);
+ ui4b *p2 = (ui4b *)p;
+ for (i = bottom - top; --i >= 0; ) {
+ for (j = vMacScreenWidth / 4; --j >= 0; ) {
+ ui4r t0 = *p1++;
+ *p2 ++
+ = ((t0 & 0xC0) >> 2)
+ | ((t0 & 0x30) >> 4)
+ | ((t0 & 0x0C) << 10)
+ | ((t0 & 0x03) << 8);
+ }
+ }
+ }
+#elif 4 == vMacScreenDepth
+ {
+ int j;
+ ui4b *p1 = (ui4b *)(cdb + (ui5r)vMacScreenByteWidth * top);
+ ui4b *p2 = (ui4b *)p;
+ for (i = bottom - top; --i >= 0; ) {
+ for (j = vMacScreenWidth; --j >= 0; ) {
+ ui4r t0 = *p1++;
+ *p2 ++ =
+ ((t0 & 0xFF00) >> 8) | ((t0 & 0x00FF) << 8);
+ }
+ }
+ }
+#elif 5 == vMacScreenDepth
+ {
+ int j;
+ ui5b *p1 = (ui5b *)(cdb + (ui5r)vMacScreenByteWidth * top);
+ ui5b *p2 = (ui5b *)p;
+ for (i = bottom - top; --i >= 0; ) {
+ for (j = vMacScreenWidth; --j >= 0; ) {
+ ui5r t0 = *p1++;
+ *p2++
+ = ((t0 & 0xFF000000) >> 24)
+ | ((t0 & 0x00FF0000) >> 8)
+ | ((t0 & 0x0000FF00) << 8)
+ | ((t0 & 0x000000FF) << 24);
+ }
+ }
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ nDestWidth *= MyWindowScale;
+ nDestHeight *= MyWindowScale;
+ }
+#endif
+
+ if (StretchDIBits(
+ MainWndDC, /* handle of device context */
+ XDest,
+ /* x-coordinate of upper-left corner of dest. rect. */
+ YDest,
+ /* y-coordinate of upper-left corner of dest. rect. */
+ nDestWidth, /* dest. rectangle width */
+ nDestHeight, /* dest. rectangle height */
+ left,
+ /* x-coordinate of lower-left corner of source rect. */
+ 0, /* y-coordinate of lower-left corner of source rect. */
+ (right - left), /* source rectangle width */
+ (bottom - top), /* source rectangle height */
+ (CONST VOID *)p, /* address of array with DIB bits */
+ (const struct tagBITMAPINFO *)&bmh,
+ /* address of structure with bitmap info. */
+ DIB_RGB_COLORS, /* RGB or palette indices */
+ SRCCOPY
+ ) == 0) {
+ /* ReportWinLastError(); */
+ }
+ } else
+#endif
+ {
+ ui3b *p = cdb + (ui5r)vMacScreenMonoByteWidth * top;
+
+ memset(&bmh, 0, sizeof (bmh));
+ bmh.bmi.biSize = sizeof(BITMAPINFOHEADER);
+ bmh.bmi.biWidth = vMacScreenWidth;
+ bmh.bmi.biHeight = - (bottom - top);
+ bmh.bmi.biPlanes = 1;
+ bmh.bmi.biBitCount = 1;
+ bmh.bmi.biCompression= BI_RGB;
+ bmh.bmi.biSizeImage = 0;
+ bmh.bmi.biXPelsPerMeter = 0;
+ bmh.bmi.biYPelsPerMeter = 0;
+ bmh.bmi.biClrUsed = 0;
+ bmh.bmi.biClrImportant = 0;
+#if ! UseWinCE
+ bmh.colors[0].rgbRed = 255;
+ bmh.colors[0].rgbGreen = 255;
+ bmh.colors[0].rgbBlue = 255;
+ bmh.colors[0].rgbReserved = 0;
+ bmh.colors[1].rgbRed = 0;
+ bmh.colors[1].rgbGreen = 0;
+ bmh.colors[1].rgbBlue = 0;
+ bmh.colors[1].rgbReserved = 0;
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+#if EnableScalingBuff
+ if (ScalingBuff != NULL) {
+ int i;
+ int j;
+ int k;
+ ui4r left1 = left & (~ 7);
+ ui4r right1 = (right + 7) & (~ 7);
+ ui4r jn = (right1 - left1) / 8;
+ ui3b *p1 =
+ cdb + ((left1 + vMacScreenWidth * (ui5r)top) / 8);
+ ui3b *p2 = ScalingBuff
+ /*
+ + ((left1 + vMacScreenWidth * MyWindowScale
+ * (ui5r)top)
+ * MyWindowScale / 8)
+ */
+ ;
+ ui3b *p3;
+ ui3b t0;
+ ui3b t1;
+ ui3b t2;
+ ui3b m;
+
+ for (i = bottom - top; --i >= 0; ) {
+ p3 = p2;
+ for (j = jn; --j >= 0; ) {
+ t0 = *p1++;
+ t1 = t0;
+ m = 0x80;
+ t2 = 0;
+ for (k = 4; --k >= 0; ) {
+ t2 |= t1 & m;
+ t1 >>= 1;
+ m >>= 2;
+ }
+ *p2++ = t2 | (t2 >> 1);
+
+ t1 = t0 << 4;
+ m = 0x80;
+ t2 = 0;
+ for (k = 4; --k >= 0; ) {
+ t2 |= t1 & m;
+ t1 >>= 1;
+ m >>= 2;
+ }
+ *p2++ = t2 | (t2 >> 1);
+ }
+ p1 += vMacScreenWidth / 8 - jn;
+ p2 += MyScaledWidth / 8 - (MyWindowScale * jn);
+ for (j = MyWindowScale * jn; --j >= 0; ) {
+ *p2++ = *p3++;
+ }
+ p2 += MyScaledWidth / 8 - (MyWindowScale * jn);
+ }
+
+ bmh.bmi.biWidth = vMacScreenWidth * MyWindowScale;
+ bmh.bmi.biHeight = - ((bottom - top) * MyWindowScale);
+ if (SetDIBitsToDevice(
+ MainWndDC, /* handle of device context */
+ XDest,
+ /*
+ x-coordinate of upper-left corner
+ of dest. rect.
+ */
+ YDest,
+ /*
+ y-coordinate of upper-left corner
+ of dest. rect.
+ */
+ (right - left) * MyWindowScale,
+ /* source rectangle width */
+ (bottom - top) * MyWindowScale,
+ /* source rectangle height */
+ (left & 7) * MyWindowScale,
+ /*
+ x-coordinate of lower-left corner
+ of source rect.
+ */
+ 0,
+ /*
+ y-coordinate of lower-left corner
+ of source rect.
+ */
+ 0, /* first scan line in array */
+ (bottom - top) * MyWindowScale,
+ /* number of scan lines */
+ (CONST VOID *)ScalingBuff,
+ /* address of array with DIB bits */
+ (const struct tagBITMAPINFO *)&bmh,
+ /* address of structure with bitmap info. */
+#if ! UseWinCE
+ DIB_RGB_COLORS /* RGB or palette indices */
+#else
+ DIB_PAL_COLORS /* palette indices */
+#endif
+ ) == 0) {
+ /* ReportWinLastError(); */
+ }
+ }
+#else
+ if (StretchDIBits(
+ MainWndDC, /* handle of device context */
+ XDest,
+ /*
+ x-coordinate of upper-left corner of dest. rect.
+ */
+ YDest,
+ /*
+ y-coordinate of upper-left corner of dest. rect.
+ */
+ (right - left) * MyWindowScale,
+ /* dest. rectangle width */
+ (bottom - top) * MyWindowScale,
+ /* dest. rectangle height */
+ left,
+ /*
+ x-coordinate of lower-left corner
+ of source rect.
+ */
+ 0,
+ /*
+ y-coordinate of lower-left corner
+ of source rect.
+ */
+ (right - left), /* source rectangle width */
+ (bottom - top), /* source rectangle height */
+ (CONST VOID *)p, /* address of array with DIB bits */
+ (const struct tagBITMAPINFO *)&bmh,
+ /* address of structure with bitmap info. */
+#if ! UseWinCE
+ DIB_RGB_COLORS, /* RGB or palette indices */
+#else
+ DIB_PAL_COLORS, /* palette indices */
+#endif
+ SRCCOPY
+ ) == 0) {
+ /* ReportWinLastError(); */
+ }
+#endif
+ } else
+#endif
+
+ {
+ if (SetDIBitsToDevice(
+ MainWndDC, /* handle of device context */
+ XDest,
+ /*
+ x-coordinate of upper-left corner of dest. rect.
+ */
+ YDest,
+ /*
+ y-coordinate of upper-left corner of dest. rect.
+ */
+ (right - left), /* source rectangle width */
+ (bottom - top), /* source rectangle height */
+ left,
+ /*
+ x-coordinate of lower-left corner
+ of source rect.
+ */
+ 0,
+ /*
+ y-coordinate of lower-left corner
+ of source rect.
+ */
+ 0, /* first scan line in array */
+ (bottom - top), /* number of scan lines */
+ (CONST VOID *)p, /* address of array with DIB bits */
+ (const struct tagBITMAPINFO *)&bmh,
+ /* address of structure with bitmap info. */
+#if ! UseWinCE
+ DIB_RGB_COLORS /* RGB or palette indices */
+#else
+ DIB_PAL_COLORS /* palette indices */
+#endif
+ ) == 0) {
+ /* ReportWinLastError(); */
+ }
+ }
+ }
+
+#if MayFullScreen
+label_exit:
+ ;
+#endif
+}
+
+LOCALPROC Screen_DrawAll(void)
+{
+ HaveChangedScreenBuff(0, 0, vMacScreenHeight, vMacScreenWidth);
+}
+
+LOCALPROC MyDrawChangesAndClear(void)
+{
+ if (ScreenChangedBottom > ScreenChangedTop) {
+ HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft,
+ ScreenChangedBottom, ScreenChangedRight);
+ ScreenClearChanges();
+ }
+}
+
+GLOBALOSGLUPROC DoneWithDrawingForTick(void)
+{
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ AutoScrollScreen();
+ }
+#endif
+ MyDrawChangesAndClear();
+}
+
+LOCALFUNC blnr InitTheCursor(void)
+{
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ return trueblnr;
+}
+
+#if EnableFSMouseMotion
+LOCALPROC MyMouseConstrain(void)
+{
+ si4b shiftdh;
+ si4b shiftdv;
+
+ if (SavedMouseH < ViewHStart + (ViewHSize / 4)) {
+ shiftdh = ViewHSize / 2;
+ } else if (SavedMouseH > ViewHStart + ViewHSize - (ViewHSize / 4))
+ {
+ shiftdh = - ViewHSize / 2;
+ } else {
+ shiftdh = 0;
+ }
+ if (SavedMouseV < ViewVStart + (ViewVSize / 4)) {
+ shiftdv = ViewVSize / 2;
+ } else if (SavedMouseV > ViewVStart + ViewVSize - (ViewVSize / 4))
+ {
+ shiftdv = - ViewVSize / 2;
+ } else {
+ shiftdv = 0;
+ }
+ if ((shiftdh != 0) || (shiftdv != 0)) {
+ SavedMouseH += shiftdh;
+ SavedMouseV += shiftdv;
+ if (! MyMoveMouse(SavedMouseH, SavedMouseV)) {
+ HaveMouseMotion = falseblnr;
+ }
+ }
+}
+#endif
+
+LOCALPROC MousePositionNotify(LONG NewMousePosx, LONG NewMousePosy)
+{
+ blnr ShouldHaveCursorHidden = trueblnr;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewMousePosx -= hOffset;
+ NewMousePosy -= vOffset;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ NewMousePosx /= MyWindowScale;
+ NewMousePosy /= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewMousePosx += ViewHStart;
+ NewMousePosy += ViewVStart;
+ }
+#endif
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMousePositionSetDelta(NewMousePosx - SavedMouseH,
+ NewMousePosy - SavedMouseV);
+ SavedMouseH = NewMousePosx;
+ SavedMouseV = NewMousePosy;
+ } else
+#endif
+ {
+ if (NewMousePosx < 0) {
+ NewMousePosx = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosx > vMacScreenWidth) {
+ NewMousePosx = vMacScreenWidth - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+ if (NewMousePosy < 0) {
+ NewMousePosy = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosy > vMacScreenHeight) {
+ NewMousePosy = vMacScreenHeight - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ ShouldHaveCursorHidden = trueblnr;
+ }
+#endif
+
+#if ! UseWinCE
+ /* if (ShouldHaveCursorHidden || CurMouseButton) */
+ /*
+ for a game like arkanoid, would like mouse to still
+ move even when outside window in one direction
+ */
+#endif
+ MyMousePositionSet(NewMousePosx, NewMousePosy);
+ }
+
+ WantCursorHidden = ShouldHaveCursorHidden;
+}
+
+#if ! UseWinCE
+LOCALPROC CheckMouseState(void)
+{
+ POINT NewMousePos;
+
+ GetCursorPos(&NewMousePos);
+ NewMousePos.x -= WndX;
+ NewMousePos.y -= WndY;
+ MousePositionNotify(NewMousePos.x, NewMousePos.y);
+}
+#endif
+
+LOCALVAR const ui3b Native2MacRomanTab[] = {
+ 0xAD, 0xB0, 0xE2, 0xC4, 0xE3, 0xC9, 0xA0, 0xE0,
+ 0xF6, 0xE4, 0xB6, 0xDC, 0xCE, 0xB2, 0xB3, 0xB7,
+ 0xB8, 0xD4, 0xD5, 0xD2, 0xD3, 0xA5, 0xD0, 0xD1,
+ 0xF7, 0xAA, 0xC5, 0xDD, 0xCF, 0xB9, 0xC3, 0xD9,
+ 0xCA, 0xC1, 0xA2, 0xA3, 0xDB, 0xB4, 0xBA, 0xA4,
+ 0xAC, 0xA9, 0xBB, 0xC7, 0xC2, 0xBD, 0xA8, 0xF8,
+ 0xA1, 0xB1, 0xC6, 0xD7, 0xAB, 0xB5, 0xA6, 0xE1,
+ 0xFC, 0xDA, 0xBC, 0xC8, 0xDE, 0xDF, 0xF0, 0xC0,
+ 0xCB, 0xE7, 0xE5, 0xCC, 0x80, 0x81, 0xAE, 0x82,
+ 0xE9, 0x83, 0xE6, 0xE8, 0xED, 0xEA, 0xEB, 0xEC,
+ 0xF5, 0x84, 0xF1, 0xEE, 0xEF, 0xCD, 0x85, 0xF9,
+ 0xAF, 0xF4, 0xF2, 0xF3, 0x86, 0xFA, 0xFB, 0xA7,
+ 0x88, 0x87, 0x89, 0x8B, 0x8A, 0x8C, 0xBE, 0x8D,
+ 0x8F, 0x8E, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95,
+ 0xFD, 0x96, 0x98, 0x97, 0x99, 0x9B, 0x9A, 0xD6,
+ 0xBF, 0x9D, 0x9C, 0x9E, 0x9F, 0xFE, 0xFF, 0xD8
+};
+
+#if IncludePbufs
+LOCALFUNC tMacErr NativeTextToMacRomanPbuf(HGLOBAL x, tPbuf *r)
+{
+#if MyUseUni
+#define MyUnsignedChar ui4b
+#else
+#define MyUnsignedChar ui3b
+#endif
+ HGLOBAL h;
+ LPTSTR p1;
+ ui5b n;
+ MyUnsignedChar v;
+ tMacErr err = mnvm_miscErr;
+
+ p1 = GlobalLock(x);
+ if (p1 != NULL) {
+ n = 0;
+ while ((v = *p1++) != 0) {
+ if (v != 10) {
+ ++n;
+ }
+ }
+ (void) GlobalUnlock(x);
+
+ h = GlobalAlloc(GMEM_DDESHARE, n);
+ if (h != NULL) {
+ p1 = GlobalLock(x);
+ if (p1 != NULL) {
+ ui3b *p2 = GlobalLock(h);
+ if (p2 != NULL) {
+ while ((v = (MyUnsignedChar)*p1++) != 0) {
+ if (v >= 128) {
+ *p2++ = Native2MacRomanTab[v & 0x7F];
+ /*
+ if MyUseUni, then for gives
+ garbage for v > 256.
+ */
+ } else if (v != 10) {
+ *p2++ = v;
+ }
+ }
+
+ err = mnvm_noErr;
+
+ (void) GlobalUnlock(h);
+ }
+ (void) GlobalUnlock(x);
+ }
+
+ if (mnvm_noErr != err) {
+ (void) GlobalFree(h);
+ } else {
+ err = PbufNewFromHandle(h, n, r);
+ }
+ }
+ }
+
+ return err;
+}
+#endif
+
+LOCALVAR const ui3b MacRoman2NativeTab[] = {
+ 0xC4, 0xC5, 0xC7, 0xC9, 0xD1, 0xD6, 0xDC, 0xE1,
+ 0xE0, 0xE2, 0xE4, 0xE3, 0xE5, 0xE7, 0xE9, 0xE8,
+ 0xEA, 0xEB, 0xED, 0xEC, 0xEE, 0xEF, 0xF1, 0xF3,
+ 0xF2, 0xF4, 0xF6, 0xF5, 0xFA, 0xF9, 0xFB, 0xFC,
+ 0x86, 0xB0, 0xA2, 0xA3, 0xA7, 0x95, 0xB6, 0xDF,
+ 0xAE, 0xA9, 0x99, 0xB4, 0xA8, 0x80, 0xC6, 0xD8,
+ 0x81, 0xB1, 0x8D, 0x8E, 0xA5, 0xB5, 0x8A, 0x8F,
+ 0x90, 0x9D, 0xA6, 0xAA, 0xBA, 0xAD, 0xE6, 0xF8,
+ 0xBF, 0xA1, 0xAC, 0x9E, 0x83, 0x9A, 0xB2, 0xAB,
+ 0xBB, 0x85, 0xA0, 0xC0, 0xC3, 0xD5, 0x8C, 0x9C,
+ 0x96, 0x97, 0x93, 0x94, 0x91, 0x92, 0xF7, 0xB3,
+ 0xFF, 0x9F, 0xB9, 0xA4, 0x8B, 0x9B, 0xBC, 0xBD,
+ 0x87, 0xB7, 0x82, 0x84, 0x89, 0xC2, 0xCA, 0xC1,
+ 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, 0xCC, 0xD3, 0xD4,
+ 0xBE, 0xD2, 0xDA, 0xDB, 0xD9, 0xD0, 0x88, 0x98,
+ 0xAF, 0xD7, 0xDD, 0xDE, 0xB8, 0xF0, 0xFD, 0xFE
+};
+
+#if IncludePbufs
+LOCALFUNC blnr MacRomanTextToNativeHand(tPbuf Pbuf_no,
+ blnr IsFileName, HGLOBAL *r)
+{
+ HGLOBAL h;
+ ui5b i;
+ ui5b rn = 0;
+ HGLOBAL bh = PbufDat[Pbuf_no];
+ ui5b L = PbufSize[Pbuf_no];
+ blnr IsOk = falseblnr;
+
+ if (IsFileName) {
+ if (L > 255) {
+ L = 255;
+ }
+ } else {
+ ui3b *Buffer = (ui3b *)GlobalLock(bh);
+ if (Buffer != NULL) {
+ for (i = 0; i < L; ++i) {
+ if (Buffer[i] == 13) {
+ ++rn;
+ }
+ }
+ (void) GlobalUnlock(bh);
+ }
+ }
+
+ h = GlobalAlloc(GMEM_DDESHARE, (L + rn + 1) * sizeof(TCHAR));
+ if (h != NULL) {
+ ui3b *Buffer = (ui3b *)GlobalLock(bh);
+ if (Buffer != NULL) {
+ LPTSTR p1 = GlobalLock(h);
+ if (p1 != NULL) {
+ for (i = 0; i < L; ++i) {
+ TCHAR y;
+ ui3b x = ((ui3b *)Buffer)[i];
+ if (x >= 128) {
+ y = (TCHAR)MacRoman2NativeTab[x - 128];
+ } else {
+ if (IsFileName) {
+ if ((x < 32)
+ || ('\\' == x) || ('/' == x)
+ || (':' == x) || ('*' == x)
+ || ('?' == x) || ('"' == x)
+ || ('<' == x) || ('>' == x)
+ || ('|' == x))
+ {
+ y = (TCHAR)('-');
+ } else {
+ y = (TCHAR)x;
+ }
+ } else {
+ if (13 == x) {
+ *p1++ = (TCHAR)(13);
+ y = (TCHAR)(10);
+ } else {
+ y = (TCHAR)x;
+ }
+ }
+ }
+ *p1++ = y;
+ }
+ *p1++ = (TCHAR) 0; /* null character */
+
+ *r = h;
+ IsOk = trueblnr;
+
+ (void) GlobalUnlock(h);
+ }
+ (void) GlobalUnlock(bh);
+ }
+ if (! IsOk) {
+ (void) GlobalFree(h);
+ }
+ }
+
+ return IsOk;
+}
+#endif
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEexport(tPbuf i)
+{
+ HGLOBAL h;
+ tMacErr err = mnvm_miscErr;
+
+ if (MacRomanTextToNativeHand(i, falseblnr, &h)) {
+ if (! OpenClipboard(MainWnd)) {
+ /* ReportGetLastError(); */
+ } else {
+ if (! EmptyClipboard()) {
+ /* ReportGetLastError(); */
+ }
+ if (SetClipboardData(CF_TEXT, h) == NULL) {
+ /* ReportGetLastError(); */
+ } else {
+ err = mnvm_noErr;
+ }
+ h = NULL;
+ if (! CloseClipboard()) {
+ /* ReportGetLastError(); */
+ }
+ }
+ if (h != NULL) {
+ (void) GlobalFree(h);
+ }
+ }
+
+ PbufDispose(i);
+
+ return err;
+}
+#endif
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEimport(tPbuf *r)
+{
+ tMacErr err = mnvm_miscErr;
+
+ if (IsClipboardFormatAvailable(CF_TEXT)) {
+ if (! OpenClipboard(MainWnd)) {
+ /* ReportGetLastError(); */
+ } else {
+ HGLOBAL h = GetClipboardData(CF_TEXT);
+ if (h == NULL) {
+ /* ReportGetLastError(); */
+ } else {
+ err = NativeTextToMacRomanPbuf(h, r);
+ }
+ if (! CloseClipboard()) {
+ /* ReportGetLastError(); */
+ }
+ }
+ }
+
+ return err;
+}
+#endif
+
+/* --- drives --- */
+
+#define NotAfileRef INVALID_HANDLE_VALUE
+
+LOCALVAR HANDLE Drives[NumDrives]; /* open disk image files */
+
+#define NeedDriveNames (IncludeSonyGetName || IncludeSonyNew)
+
+#if NeedDriveNames
+LOCALVAR HGLOBAL DriveNames[NumDrives];
+ /*
+ It is supposed to be possible to use
+ GetMappedFileName to get name of open file,
+ but that seems ugly kludge, so instead
+ save the name on open.
+ */
+#endif
+
+LOCALPROC InitDrives(void)
+{
+ /*
+ This isn't really needed, Drives[i] and DriveNames[i]
+ need not have valid values when not vSonyIsInserted[i].
+ */
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ Drives[i] = NotAfileRef;
+#if NeedDriveNames
+ DriveNames[i] = NULL;
+#endif
+ }
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer,
+ tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
+ ui5r *Sony_ActCount)
+{
+ HANDLE refnum;
+ DWORD newL;
+ tMacErr result;
+ DWORD BytesTransferred = 0;
+
+ refnum = Drives[Drive_No];
+ newL = SetFilePointer(
+ refnum, /* handle of file */
+ Sony_Start, /* number of bytes to move file pointer */
+ nullpr, /* address of high-order word of distance to move */
+ FILE_BEGIN /* how to move */
+ );
+ if (newL == 0xFFFFFFFF) {
+ result = mnvm_miscErr; /*& figure out what really to return &*/
+ } else if (Sony_Start != (ui5b)newL) {
+ /* not supposed to get here */
+ result = mnvm_miscErr; /*& figure out what really to return &*/
+ } else {
+ if (IsWrite) {
+ if (! WriteFile(refnum, /* handle of file to read */
+ (LPVOID)Buffer
+ , /* address of buffer that receives data */
+ (DWORD)Sony_Count, /* number of bytes to read */
+ &BytesTransferred, /* address of number of bytes read */
+ nullpr)) /* address of structure for data */
+ {
+ result = mnvm_miscErr;
+ /*& figure out what really to return &*/
+ } else if ((ui5b)BytesTransferred != Sony_Count) {
+ result = mnvm_miscErr;
+ /*& figure out what really to return &*/
+ } else {
+ result = mnvm_noErr;
+ }
+ } else {
+ if (! ReadFile(refnum, /* handle of file to read */
+ (LPVOID)Buffer,
+ /* address of buffer that receives data */
+ (DWORD)Sony_Count, /* number of bytes to read */
+ &BytesTransferred,
+ /* address of number of bytes read */
+ nullpr)) /* address of structure for data */
+ {
+ result = mnvm_miscErr;
+ /*& figure out what really to return &*/
+ } else if ((ui5b)BytesTransferred != Sony_Count) {
+ result = mnvm_miscErr;
+ /*& figure out what really to return &*/
+ } else {
+ result = mnvm_noErr;
+ }
+ }
+ }
+
+ if (nullpr != Sony_ActCount) {
+ *Sony_ActCount = BytesTransferred;
+ }
+
+ return result;
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count)
+{
+ tMacErr result;
+ DWORD L;
+
+ L = GetFileSize(Drives[Drive_No], nullpr);
+ if (L == 0xFFFFFFFF) {
+ result = mnvm_miscErr; /*& figure out what really to return &*/
+ } else {
+ *Sony_Count = L;
+ result = mnvm_noErr;
+ }
+
+ return result;
+}
+
+LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit)
+{
+ HANDLE refnum = Drives[Drive_No];
+
+#if ! NeedDriveNames
+ UnusedParam(deleteit);
+#endif
+
+ Drives[Drive_No] = NotAfileRef; /* not really needed */
+
+ DiskEjectedNotify(Drive_No);
+
+ (void) FlushFileBuffers(refnum);
+ (void) CloseHandle(refnum);
+
+#if NeedDriveNames
+ {
+ HGLOBAL h = DriveNames[Drive_No];
+ if (NULL != h) {
+ if (deleteit) {
+ LPTSTR drivepath = GlobalLock(h);
+ if (drivepath != NULL) {
+ (void) DeleteFile(drivepath);
+ (void) GlobalUnlock(h);
+ }
+ }
+ (void) GlobalFree(h);
+ DriveNames[Drive_No] = NULL; /* not really needed */
+ }
+ }
+#endif
+
+ return mnvm_noErr;
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No)
+{
+ return vSonyEject0(Drive_No, falseblnr);
+}
+
+#if IncludeSonyNew
+GLOBALOSGLUFUNC tMacErr vSonyEjectDelete(tDrive Drive_No)
+{
+ return vSonyEject0(Drive_No, trueblnr);
+}
+#endif
+
+LOCALPROC UnInitDrives(void)
+{
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ if (vSonyIsInserted(i)) {
+ (void) vSonyEject(i);
+ }
+ }
+}
+
+#if NeedDriveNames
+LOCALFUNC blnr LPTSTRtoHand(LPTSTR s, HGLOBAL *r)
+{
+ blnr IsOk = falseblnr;
+
+ size_t L = _tcslen(s);
+ HGLOBAL h = GlobalAlloc(GMEM_DDESHARE,
+ (L + 1) * sizeof(TCHAR));
+ if (h != NULL) {
+ LPTSTR p = GlobalLock(h);
+ if (p != NULL) {
+ _tcscpy(p, s);
+ IsOk = trueblnr;
+ (void) GlobalUnlock(h);
+ }
+ if (! IsOk) {
+ (void) GlobalFree(h);
+ } else {
+ *r = h;
+ }
+ }
+
+ return IsOk;
+}
+#endif
+
+#if IncludeSonyGetName
+GLOBALOSGLUFUNC tMacErr vSonyGetName(tDrive Drive_No, tPbuf *r)
+{
+ WIN32_FIND_DATA fd;
+ tMacErr err = mnvm_miscErr;
+ HGLOBAL ph = DriveNames[Drive_No];
+ if (NULL != ph) {
+ LPTSTR drivepath = GlobalLock(ph);
+ if (drivepath != NULL) {
+ HANDLE hf = FindFirstFile(drivepath, &fd);
+ (void) GlobalUnlock(ph);
+
+ if (hf != INVALID_HANDLE_VALUE) {
+ HGLOBAL h;
+ if (LPTSTRtoHand(fd.cFileName, &h)) {
+ err = NativeTextToMacRomanPbuf(h, r);
+ }
+ FindClose(hf);
+ }
+ }
+ }
+
+ return err;
+}
+#endif
+
+LOCALFUNC blnr Sony_Insert0(HANDLE refnum, blnr locked,
+ LPTSTR drivepath)
+{
+ tDrive Drive_No;
+
+#if ! NeedDriveNames
+ UnusedParam(drivepath);
+#endif
+
+ if (! FirstFreeDisk(&Drive_No)) {
+ (void) CloseHandle(refnum);
+ MacMsg(kStrTooManyImagesTitle,
+ kStrTooManyImagesMessage, falseblnr);
+ return falseblnr;
+ } else {
+ Drives[Drive_No] = refnum;
+ DiskInsertNotify(Drive_No, locked);
+#if NeedDriveNames
+ {
+ HGLOBAL h;
+
+ if (! LPTSTRtoHand(drivepath, &h)) {
+ h = NULL;
+ }
+
+ DriveNames[Drive_No] = h;
+ }
+#endif
+ return trueblnr;
+ }
+}
+
+LOCALFUNC blnr Sony_Insert1(LPTSTR drivepath, blnr SilentOnMissing)
+{
+ blnr locked = falseblnr;
+ HANDLE refnum = CreateFile(
+ drivepath, /* pointer to name of the file */
+ GENERIC_READ + GENERIC_WRITE, /* access (read-write) mode */
+ 0, /* share mode */
+ nullpr, /* pointer to security descriptor */
+ OPEN_EXISTING, /* how to create */
+ FILE_ATTRIBUTE_NORMAL, /* file attributes */
+ nullpr /* handle to file with attributes to copy */
+ );
+ if (refnum == INVALID_HANDLE_VALUE) {
+ if (ERROR_ACCESS_DENIED == GetLastError()) {
+ locked = trueblnr;
+ refnum = CreateFile(
+ drivepath, /* pointer to name of the file */
+ GENERIC_READ, /* access (read-write) mode */
+ FILE_SHARE_READ, /* share mode */
+ nullpr, /* pointer to security descriptor */
+ OPEN_EXISTING, /* how to create */
+ FILE_ATTRIBUTE_NORMAL, /* file attributes */
+ nullpr /* handle to file with attributes to copy */
+ );
+ }
+ }
+ if (refnum == INVALID_HANDLE_VALUE) {
+ DWORD err = GetLastError();
+ if (ERROR_SHARING_VIOLATION == err) {
+ MacMsg(kStrImageInUseTitle,
+ kStrImageInUseMessage, falseblnr);
+ } else if ((ERROR_FILE_NOT_FOUND == err) && SilentOnMissing) {
+ /* ignore it */
+ } else {
+ MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
+ }
+ } else {
+ return Sony_Insert0(refnum, locked, drivepath);
+ }
+ return falseblnr;
+}
+
+LOCALFUNC blnr LoadMacRomFromPath(LPTSTR drivepath)
+{
+ HANDLE refnum = INVALID_HANDLE_VALUE;
+ blnr IsOk = falseblnr;
+
+ refnum = CreateFile(
+ drivepath, /* pointer to name of the file */
+ GENERIC_READ, /* access (read-write) mode */
+ FILE_SHARE_READ, /* share mode */
+ nullpr, /* pointer to security descriptor */
+ OPEN_EXISTING, /* how to create */
+ FILE_ATTRIBUTE_NORMAL, /* file attributes */
+ nullpr /* handle to file with attributes to copy */
+ );
+
+ if (refnum == INVALID_HANDLE_VALUE) {
+ /* MacMsg(kStrNoROMTitle, kStrNoROMMessage, trueblnr); */
+ } else {
+ DWORD BytesRead;
+
+ if (! ReadFile(refnum, /* handle of file to read */
+ (LPVOID)ROM, /* address of buffer that receives data */
+ (DWORD)kROM_Size, /* number of bytes to read */
+ &BytesRead, /* address of number of bytes read */
+ nullpr)) /* address of structure for data */
+ {
+ MacMsgOverride(kStrNoReadROMTitle, kStrNoReadROMMessage);
+ } else
+ if ((ui5b)BytesRead != kROM_Size) {
+ MacMsgOverride(kStrShortROMTitle, kStrShortROMMessage);
+ } else
+ {
+ IsOk = (mnvm_noErr == ROM_IsValid());
+ }
+ (void) CloseHandle(refnum);
+ }
+
+ return IsOk;
+}
+
+#ifndef EnableShellLinks
+#define EnableShellLinks 1
+#endif
+
+#if EnableShellLinks
+LOCALVAR blnr COMinited = falseblnr;
+LOCALVAR blnr COMinitedOK;
+#endif
+
+#if EnableShellLinks
+LOCALPROC MyUninitCOM(void)
+{
+ if (COMinited) {
+ CoUninitialize();
+ }
+}
+#endif
+
+#if EnableShellLinks
+LOCALFUNC blnr MyNeedCOM(void)
+{
+ HRESULT hres;
+
+ if (! COMinited) {
+ COMinitedOK = falseblnr;
+ hres = CoInitialize(NULL);
+ if (SUCCEEDED(hres)) {
+ COMinitedOK = trueblnr;
+ }
+
+ COMinited = trueblnr;
+ }
+ return COMinitedOK;
+}
+#endif
+
+#if EnableShellLinks
+LOCALFUNC blnr MyResolveShortcut(LPTSTR FilePath, blnr *directory)
+/* adapted from Microsoft example code */
+{
+ HRESULT hres;
+ IShellLink *psl;
+ IPersistFile* ppf;
+ TCHAR szGotPath[MAX_PATH];
+ WIN32_FIND_DATA wfd;
+ blnr IsOk = falseblnr;
+
+ if (MyNeedCOM()) {
+ hres = CoCreateInstance(&CLSID_ShellLink, NULL,
+ CLSCTX_INPROC_SERVER, &IID_IShellLink,
+ (LPVOID *)(void *)&psl);
+ /*
+ the (void *) prevents a compiler warning
+ from gcc
+ */
+ if (SUCCEEDED(hres)) {
+ /* Get a pointer to the IPersistFile interface. */
+ hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile,
+ (void **)(void *)&ppf);
+ if (SUCCEEDED(hres)) {
+ /* Ensure that the string is Unicode. */
+#if MyUseUni
+#define wsz FilePath
+#else
+ WORD wsz[MAX_PATH];
+ MultiByteToWideChar(CP_ACP, 0, FilePath, -1, wsz,
+ MAX_PATH);
+#endif
+
+ /* Load the shortcut. */
+ hres = ppf->lpVtbl->Load(ppf, wsz, STGM_READ);
+ if (SUCCEEDED(hres)) {
+ /* Resolve the link. */
+ hres = psl->lpVtbl->Resolve(psl, MainWnd,
+ SLR_ANY_MATCH);
+ if (SUCCEEDED(hres)) {
+ /* Get the path to the link target. */
+ hres = psl->lpVtbl->GetPath(psl, szGotPath,
+ MAX_PATH, &wfd,
+ SLGP_SHORTPATH);
+ if (SUCCEEDED(hres)) {
+ /*
+ This is in the sample code, but doesn't
+ seem to be needed:
+ Get the description of the target.
+ char szDescription[MAX_PATH];
+ hres = psl->lpVtbl->GetDescription(psl,
+ szDescription, MAX_PATH);
+ if (SUCCEEDED(hres)) {
+ }
+ */
+ lstrcpy(FilePath, szGotPath);
+ if (NULL != directory) {
+ *directory = (0 != (wfd.dwFileAttributes
+ & FILE_ATTRIBUTE_DIRECTORY));
+ }
+ IsOk = trueblnr;
+ }
+ }
+ }
+
+ ppf->lpVtbl->Release(ppf);
+ }
+ psl->lpVtbl->Release(psl);
+ }
+ }
+ return IsOk;
+}
+#endif
+
+#if EnableShellLinks
+LOCALFUNC blnr FileIsLink(LPTSTR drivepath)
+{
+ LPTSTR p = FindLastTerm(drivepath, (TCHAR)('.'));
+
+ if (p != nullpr) {
+ if (_tcscmp(p, TEXT("lnk")) == 0) {
+ return trueblnr;
+ }
+ }
+ return falseblnr;
+}
+#endif
+
+LOCALFUNC blnr InsertDiskOrAlias(LPTSTR drivepath,
+ blnr MaybeROM, blnr MaybeAlias)
+{
+#if EnableShellLinks
+ if (MaybeAlias && FileIsLink(drivepath)) {
+ if (! MyResolveShortcut(drivepath, NULL)) {
+ return falseblnr;
+ }
+ }
+#endif
+
+ if (MaybeROM && ! ROM_loaded) {
+ return LoadMacRomFromPath(drivepath);
+ } else {
+ return Sony_Insert1(drivepath, falseblnr);
+ }
+}
+
+LOCALFUNC blnr MyFileExists(LPTSTR pathName, blnr *directory)
+{
+ WIN32_FIND_DATA fd;
+ HANDLE hf = FindFirstFile(pathName, &fd);
+ blnr IsOk = falseblnr;
+
+ if (hf != INVALID_HANDLE_VALUE) {
+ if (NULL != directory) {
+ *directory =
+ (0 != (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
+ }
+ IsOk = trueblnr;
+ FindClose(hf);
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC tMacErr ResolveNamedChild0(LPTSTR pathName,
+ LPTSTR Child, blnr *directory)
+{
+ size_t newlen;
+ size_t oldlen = _tcslen(pathName);
+ tMacErr err = mnvm_miscErr;
+
+ newlen = oldlen + 1 + _tcslen(Child);
+ if (newlen + 1 < _MAX_PATH) {
+ _tcscat(pathName, TEXT("\\"));
+ _tcscat(pathName, Child);
+
+ if (MyFileExists(pathName, directory)) {
+ err = mnvm_noErr;
+ } else {
+ err = mnvm_fnfErr;
+#if EnableShellLinks
+ if (newlen + 5 < _MAX_PATH) {
+ _tcscat(pathName, TEXT(".lnk"));
+ if (MyFileExists(pathName, NULL))
+ if (MyResolveShortcut(pathName, directory))
+ {
+ err = mnvm_noErr;
+ }
+ if (mnvm_noErr != err) {
+ pathName[newlen] = (TCHAR)('\0');
+ }
+ }
+#endif
+ }
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr ResolveNamedChild(LPTSTR pathName,
+ char *Child, blnr *directory)
+{
+ TCHAR Child0[ClStrMaxLength + 1];
+
+ NativeStrFromCStr(Child0, Child, falseblnr);
+
+ return ResolveNamedChild0(pathName, Child0, directory);
+}
+
+LOCALFUNC blnr ResolveNamedChildDir(LPTSTR pathName, char *Child)
+{
+ blnr directory;
+
+ return (mnvm_noErr == ResolveNamedChild(
+ pathName, Child, &directory))
+ && directory;
+}
+
+LOCALFUNC blnr ResolveNamedChildFile(LPTSTR pathName, char *Child)
+{
+ blnr directory;
+
+ return (mnvm_noErr == ResolveNamedChild(
+ pathName, Child, &directory))
+ && ! directory;
+}
+
+#if UseActvFile || (IncludeSonyNew && ! SaveDialogEnable)
+LOCALFUNC blnr MakeNamedChildDir(LPTSTR pathName, char *Child)
+{
+ blnr directory;
+ blnr IsOk = falseblnr;
+ tMacErr err = ResolveNamedChild(pathName, Child, &directory);
+
+ if (mnvm_noErr == err) {
+ IsOk = directory;
+ } else if (mnvm_fnfErr == err) {
+ if (CreateDirectory(pathName, NULL)) {
+ IsOk = trueblnr;
+ }
+ }
+
+ return IsOk;
+}
+#endif
+
+LOCALFUNC blnr MyGetAppDataPath(LPTSTR lpszPath,
+ BOOL fCreate)
+{
+ blnr IsOk = falseblnr;
+
+ if (HaveMySHGetSpecialFolderPath())
+ if (MySHGetSpecialFolderPath(
+ NULL /* HWND hwndOwner */,
+ lpszPath, My_CSIDL_APPDATA, fCreate))
+ {
+ IsOk = trueblnr;
+ }
+ /*
+ if not available, could perhaps
+ use GetWindowsDirectory.
+ */
+ /*
+ SHGetFolderPath is more recent,
+ could perhaps check for it first.
+ might also be in "SHFolder.dll".
+
+ SHGetKnownFolderPath is even
+ more recent.
+ */
+
+ return IsOk;
+}
+
+#if UseWinCE
+/* Are we in control mode? */
+/* Needed because you can't hold down a key with the virtual keyboard */
+LOCALVAR blnr CtrlMode = falseblnr;
+#endif
+
+LOCALPROC InsertADisk0(void)
+{
+ OPENFILENAME ofn;
+ TCHAR szDirName[256];
+ TCHAR szFile[256];
+#if ! UseWinCE
+ TCHAR szFileTitle[256];
+#endif
+ UINT i;
+ size_t cbString;
+ TCHAR chReplace;
+ TCHAR szFilter[256];
+ blnr IsOk;
+
+ szDirName[0] = (TCHAR)('\0');
+ szFile[0] = (TCHAR)('\0');
+ _tcscpy(szFilter,
+ TEXT("Disk images|*.dsk;*.HF?;*.IMG;*.IMA;*.IMAGE")
+ TEXT("|All files (*.*)|*.*|\0"));
+
+ cbString = _tcslen(szFilter);
+
+ chReplace = szFilter[cbString - 1];
+
+ for (i = 0; szFilter[i] != (TCHAR)('\0'); ++i)
+ {
+ if (szFilter[i] == chReplace) {
+ szFilter[i] = (TCHAR)('\0');
+ }
+ }
+
+ memset(&ofn, 0, sizeof(OPENFILENAME));
+
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.hwndOwner = MainWnd;
+ ofn.lpstrFilter = szFilter;
+ ofn.nFilterIndex = 2;
+ ofn.lpstrFile= szFile;
+ ofn.nMaxFile = sizeof(szFile);
+#if ! UseWinCE
+ ofn.lpstrFileTitle = szFileTitle;
+ ofn.nMaxFileTitle = sizeof(szFileTitle);
+#endif
+ ofn.lpstrInitialDir = szDirName;
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST
+ | OFN_HIDEREADONLY;
+
+ MyBeginDialog();
+ IsOk = GetOpenFileName(&ofn);
+ MyEndDialog();
+
+ if(! IsOk) {
+ /* report error */
+#if UseWinCE
+ if (szFile[0]) {
+ char wMsg[1024];
+ sprintf(wMsg, "Couldn't open %ls", szFile);
+ MacMsg("error", wMsg, falseblnr);
+ }
+#endif
+ } else {
+ (void) InsertDiskOrAlias(ofn.lpstrFile,
+ trueblnr, falseblnr);
+ }
+
+#if UseWinCE
+ CtrlMode = falseblnr;
+#endif
+}
+
+LOCALFUNC blnr LoadInitialImageFromName(char *ImageName)
+{
+ TCHAR ImageFile[_MAX_PATH];
+
+ if (GetAppDir(ImageFile))
+ if (ResolveNamedChildFile(ImageFile, ImageName))
+ if (Sony_Insert1(ImageFile, trueblnr))
+ {
+ return trueblnr;
+ }
+ return falseblnr;
+}
+
+LOCALFUNC blnr Sony_InsertIth(int i)
+{
+ blnr v;
+
+ if ((i > 9) || ! FirstFreeDisk(nullpr)) {
+ v = falseblnr;
+ } else {
+ char s[] = "disk?.dsk";
+
+ s[4] = '0' + i;
+
+ /* stop on first error (including file not found) */
+ v = LoadInitialImageFromName(s);
+ }
+
+ return v;
+}
+
+LOCALFUNC blnr LoadInitialImages(void)
+{
+ if (! AnyDiskInserted()) {
+ int i;
+
+ for (i = 1; Sony_InsertIth(i); ++i) {
+ /* stop on first error (including file not found) */
+ }
+ }
+
+ return trueblnr;
+}
+
+#if UseActvFile
+
+#define ActvCodeFileName "act_1"
+
+LOCALFUNC tMacErr ActvCodeFileLoad(ui3p p)
+{
+ TCHAR pathName[_MAX_PATH];
+ DWORD BytesRead;
+ HANDLE refnum = INVALID_HANDLE_VALUE;
+ blnr IsOk = falseblnr;
+
+ if (MyGetAppDataPath(pathName, FALSE))
+ if (ResolveNamedChildDir(pathName, "Gryphel"))
+ if (ResolveNamedChildDir(pathName, "mnvm_act"))
+ if (ResolveNamedChildFile(pathName, ActvCodeFileName))
+ {
+ refnum = CreateFile(
+ pathName, /* pointer to name of the file */
+ GENERIC_READ, /* access (read-write) mode */
+ FILE_SHARE_READ, /* share mode */
+ NULL, /* pointer to security descriptor */
+ OPEN_EXISTING, /* how to create */
+ FILE_ATTRIBUTE_NORMAL, /* file attributes */
+ NULL /* handle to file with attributes to copy */
+ );
+ if (INVALID_HANDLE_VALUE == refnum) {
+ /* report error */
+ } else {
+ if (SetFilePointer(
+ refnum, /* handle of file */
+ 0, /* number of bytes to move file pointer */
+ nullpr,
+ /* address of high-order word of distance to move */
+ FILE_BEGIN /* how to move */
+ ) != 0)
+ {
+ /* report error */
+ } else if (! ReadFile(refnum, /* handle of file to read */
+ (LPVOID)p, /* address of buffer that receives data */
+ (DWORD)ActvCodeFileLen, /* number of bytes to read */
+ &BytesRead, /* address of number of bytes read */
+ nullpr) /* address of structure for data */
+ || ((ui5b)BytesRead != ActvCodeFileLen))
+ {
+ /* report error */
+ } else {
+ IsOk = trueblnr;
+ }
+ (void) CloseHandle(refnum);
+ }
+ }
+
+ return IsOk ? mnvm_noErr : mnvm_miscErr;
+}
+
+LOCALFUNC blnr NewNamedChildFile(LPTSTR pathName, char *Child)
+{
+ blnr directory;
+ blnr IsOk = falseblnr;
+ tMacErr err = ResolveNamedChild(pathName, Child, &directory);
+
+ if (mnvm_noErr == err) {
+ IsOk = ! directory;
+ } else if (mnvm_fnfErr == err) {
+ IsOk = trueblnr;
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC tMacErr ActvCodeFileSave(ui3p p)
+{
+ TCHAR pathName[_MAX_PATH];
+ DWORD BytesWritten;
+ HANDLE refnum = INVALID_HANDLE_VALUE;
+ blnr IsOk = falseblnr;
+
+ if (MyGetAppDataPath(pathName, TRUE))
+ if (MakeNamedChildDir(pathName, "Gryphel"))
+ if (MakeNamedChildDir(pathName, "mnvm_act"))
+ if (NewNamedChildFile(pathName, ActvCodeFileName))
+ {
+ refnum = CreateFile(
+ pathName, /* pointer to name of the file */
+ GENERIC_READ + GENERIC_WRITE, /* access (read-write) mode */
+ 0, /* share mode */
+ NULL, /* pointer to security descriptor */
+ CREATE_ALWAYS, /* how to create */
+ FILE_ATTRIBUTE_NORMAL, /* file attributes */
+ NULL /* handle to file with attributes to copy */
+ );
+ if (INVALID_HANDLE_VALUE == refnum) {
+ /* report error */
+ } else {
+ if (SetFilePointer(
+ refnum, /* handle of file */
+ 0, /* number of bytes to move file pointer */
+ nullpr,
+ /* address of high-order word of distance to move */
+ FILE_BEGIN /* how to move */
+ ) != 0)
+ {
+ /* report error */
+ } else if (! WriteFile(refnum, /* handle of file to read */
+ (LPVOID)p, /* address of buffer that receives data */
+ (DWORD)ActvCodeFileLen, /* number of bytes to read */
+ &BytesWritten, /* address of number of bytes read */
+ nullpr) /* address of structure for data */
+ || ((ui5b)BytesWritten != ActvCodeFileLen))
+ {
+ /* report error */
+ } else {
+ IsOk = trueblnr;
+ }
+ (void) CloseHandle(refnum);
+ if (! IsOk) {
+ (void) DeleteFile(pathName);
+ }
+ }
+ }
+
+ return IsOk ? mnvm_noErr : mnvm_miscErr;
+}
+
+#endif /* UseActvFile */
+
+#if IncludeSonyNew
+LOCALFUNC blnr WriteZero(HANDLE refnum, ui5b L)
+{
+ if (SetFilePointer(
+ refnum, /* handle of file */
+ 0, /* number of bytes to move file pointer */
+ nullpr, /* address of high-order word of distance to move */
+ FILE_BEGIN /* how to move */
+ ) != 0)
+ {
+ return falseblnr;
+ } else {
+#define ZeroBufferSize 2048
+ ui5b i;
+ ui3b buffer[ZeroBufferSize];
+ DWORD BytesWritten;
+
+ memset(&buffer, 0, ZeroBufferSize);
+
+ while (L > 0) {
+ i = (L > ZeroBufferSize) ? ZeroBufferSize : L;
+ if (! WriteFile(refnum, /* handle of file to read */
+ (LPVOID)buffer,
+ /* address of buffer that receives data */
+ (DWORD)i, /* number of bytes to read */
+ &BytesWritten, /* address of number of bytes read */
+ nullpr) /* address of structure for data */
+ || ((ui5b)BytesWritten != i))
+ {
+ return falseblnr;
+ }
+ L -= i;
+ }
+ return trueblnr;
+ }
+}
+#endif
+
+#define MaxSavePathSize MAX_PATH
+
+#if IncludeSonyNew
+LOCALPROC MakeNewDisk0(ui5b L, LPTSTR pathName)
+{
+ blnr IsOk = falseblnr;
+ HANDLE newrefNum;
+
+ IsOk = falseblnr;
+ newrefNum = CreateFile(
+ pathName, /* pointer to name of the file */
+ GENERIC_READ + GENERIC_WRITE, /* access (read-write) mode */
+ 0, /* share mode */
+ NULL, /* pointer to security descriptor */
+ CREATE_ALWAYS, /* how to create */
+ FILE_ATTRIBUTE_NORMAL, /* file attributes */
+ NULL /* handle to file with attributes to copy */
+ );
+ if (newrefNum == INVALID_HANDLE_VALUE) {
+ /* report error */
+ } else {
+ if (SetFilePointer(
+ newrefNum, /* handle of file */
+ L, /* number of bytes to move file pointer */
+ nullpr,
+ /* address of high-order word of distance to move */
+ FILE_BEGIN /* how to move */
+ ) != L)
+ {
+ /* report error */
+ } else if (! SetEndOfFile(newrefNum)) {
+ /* report error */
+ } else if (! WriteZero(newrefNum, L)) {
+ /* report error */
+ } else {
+ IsOk =
+ Sony_Insert0(newrefNum, falseblnr, pathName);
+ newrefNum = INVALID_HANDLE_VALUE;
+ }
+ if (INVALID_HANDLE_VALUE != newrefNum) {
+ (void) CloseHandle(newrefNum);
+ }
+ if (! IsOk) {
+ (void) DeleteFile(pathName);
+ }
+ }
+}
+#endif
+
+#if IncludeSonyNew
+LOCALPROC MakeNewDisk(ui5b L, HGLOBAL NewDiskNameDat)
+{
+#if SaveDialogEnable
+ OPENFILENAME ofn;
+ blnr IsOk = falseblnr;
+ TCHAR szFile[MaxSavePathSize];
+ TCHAR szFileTitle[MaxSavePathSize];
+
+ memset(&ofn, 0, sizeof(OPENFILENAME));
+ szFile[0] = 0;
+ szFileTitle[0] = 0;
+
+#if IncludeSonyGetName
+ if (NewDiskNameDat != NULL) {
+ LPTSTR p = GlobalLock(NewDiskNameDat);
+ if (p != NULL) {
+ _tcscpy(szFile, p);
+ (void) GlobalUnlock(NewDiskNameDat);
+ }
+ } else
+#endif
+ {
+ NativeStrFromCStr(szFile, "untitled", falseblnr);
+ }
+
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.lpstrFile = szFile;
+ ofn.hwndOwner = MainWnd;
+ /* ofn.lpstrFilter = "All\0*.*\0Text\0*.txt\0Datafile\0*.dsk\0"; */
+ /* ofn.lpstrFilter = NULL; */ /* szFilter */
+ ofn.nMaxFile = MaxSavePathSize;
+ ofn.lpstrFileTitle = szFileTitle;
+ ofn.nMaxFileTitle = MaxSavePathSize;
+ ofn.lpstrInitialDir = NULL;
+ ofn.Flags = OFN_OVERWRITEPROMPT + OFN_HIDEREADONLY;
+ /* + OFN_SHOWHELP */
+
+ MyBeginDialog();
+ IsOk = GetSaveFileName(&ofn);
+ MyEndDialog();
+
+ if (! IsOk) {
+ /* report error */
+ } else {
+ MakeNewDisk0(L, ofn.lpstrFile);
+ }
+#else /* SaveDialogEnable */
+ TCHAR pathName[MaxSavePathSize];
+
+ if (GetAppDir(pathName))
+ if (MakeNamedChildDir(pathName, "out"))
+ {
+ blnr directory;
+ LPTSTR p = GlobalLock(NewDiskNameDat);
+
+ if (p != NULL) {
+ tMacErr err = ResolveNamedChild0(pathName, p,
+ &directory);
+
+ if (mnvm_fnfErr == err) {
+ err = mnvm_noErr;
+ } else if (mnvm_noErr == err) {
+ if (directory) {
+ err = mnvm_miscErr;
+ }
+ }
+
+ if (mnvm_noErr == err) {
+ MakeNewDisk0(L, pathName);
+ }
+
+ (void) GlobalUnlock(NewDiskNameDat);
+ }
+ }
+#endif /* SaveDialogEnable */
+}
+#endif
+
+LOCALFUNC blnr LoadMacRom(void)
+{
+ TCHAR ROMFile[_MAX_PATH];
+ blnr IsOk = falseblnr;
+
+ if (GetAppDir(ROMFile))
+ if (ResolveNamedChildFile(ROMFile, RomFileName))
+ {
+ IsOk = trueblnr;
+ }
+
+ if (! IsOk) {
+ if (MyGetAppDataPath(ROMFile, FALSE))
+ if (ResolveNamedChildDir(ROMFile, "Gryphel"))
+ if (ResolveNamedChildDir(ROMFile, "mnvm_rom"))
+ if (ResolveNamedChildFile(ROMFile, RomFileName))
+ {
+ IsOk = trueblnr;
+ }
+
+ }
+
+ if (IsOk) {
+ IsOk = LoadMacRomFromPath(ROMFile);
+ }
+
+ return trueblnr;
+}
+
+#if InstallFileIcons
+LOCALPROC MySetRegKey(HKEY hKeyRoot,
+ LPTSTR strRegKey, LPTSTR strRegValue)
+{
+ HKEY RegKey;
+ DWORD dwDisposition;
+
+ if (ERROR_SUCCESS == RegCreateKeyEx(hKeyRoot, strRegKey, 0, NULL,
+ REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
+ NULL, &RegKey, &dwDisposition))
+ {
+ RegSetValueEx(RegKey, NULL, 0, REG_SZ,
+ (CONST BYTE *)strRegValue,
+ (DWORD)((_tcslen(strRegValue) + 1) * sizeof(TCHAR)));
+ RegCloseKey(RegKey);
+ }
+}
+
+LOCALPROC RegisterShellFileType(LPTSTR AppPath, LPTSTR strFilterExt,
+ LPTSTR strFileTypeId, LPTSTR strFileTypeName,
+ LPTSTR strIconId, blnr CanOpen)
+{
+ TCHAR strRegKey[_MAX_PATH];
+ TCHAR strRegValue[_MAX_PATH + 2];
+ /* extra room for ","{strIconId} */
+
+ MySetRegKey(HKEY_CLASSES_ROOT, strFileTypeId, strFileTypeName);
+ MySetRegKey(HKEY_CLASSES_ROOT, strFilterExt, strFileTypeId);
+
+ _tcscpy(strRegKey, strFileTypeId);
+ _tcscat(strRegKey, TEXT("\\DefaultIcon"));
+ _tcscpy(strRegValue, TEXT("\""));
+ _tcscat(strRegValue, AppPath);
+ _tcscat(strRegValue, TEXT("\","));
+ _tcscat(strRegValue, strIconId);
+ MySetRegKey(HKEY_CLASSES_ROOT, strRegKey, strRegValue);
+
+ if (CanOpen) {
+ _tcscpy(strRegKey, strFileTypeId);
+ _tcscat(strRegKey, TEXT("\\shell\\open\\command"));
+ _tcscpy(strRegValue, TEXT("\""));
+ _tcscat(strRegValue, AppPath);
+ _tcscat(strRegValue, TEXT("\" \"%1\""));
+ MySetRegKey(HKEY_CLASSES_ROOT, strRegKey, strRegValue);
+ }
+}
+
+LOCALFUNC blnr RegisterInRegistry(void)
+{
+ TCHAR AppPath[_MAX_PATH];
+
+ GetModuleFileName(NULL, AppPath, _MAX_PATH);
+#if 0
+ GetShortPathName(AppPath, AppPath, _MAX_PATH);
+#endif
+
+ RegisterShellFileType(AppPath, TEXT(".rom"), TEXT("minivmac.rom"),
+ TEXT("Mini vMac ROM Image"), TEXT("1"), falseblnr);
+ RegisterShellFileType(AppPath, TEXT(".dsk"), TEXT("minivmac.dsk"),
+ TEXT("Mini vMac Disk Image"), TEXT("2"), trueblnr);
+
+ return trueblnr;
+}
+#endif
+
+LOCALVAR LPTSTR CommandLine;
+
+LOCALFUNC blnr ScanCommandLine(void)
+{
+ TCHAR *p = CommandLine;
+ TCHAR *p1;
+ TCHAR *p2;
+ TCHAR v;
+ size_t L;
+
+ v = *p;
+ while (0 != v) {
+ if (' ' == v) {
+ v = *++p;
+ } else {
+ if ('\"' == v) {
+ v = *++p;
+ p1 = p;
+ while (('\"' != v) && (0 != v)) {
+ v = *++p;
+ }
+ p2 = p;
+ if ('\"' == v) {
+ v = *++p;
+ }
+ } else {
+ p1 = p;
+ while ((' ' != v) && (0 != v)) {
+ v = *++p;
+ }
+ p2 = p;
+ }
+ L = p2 - p1;
+ if (L + 1 <= _MAX_PATH) {
+ TCHAR fileName[_MAX_PATH];
+ TCHAR *filePtr = fileName;
+ size_t i = L;
+
+ while (i > 0) {
+ *filePtr++ = *p1++;
+ --i;
+ }
+ *filePtr = (char)0;
+
+ if ((L > 0)
+ && (('/' == fileName[0]) || ('-' == fileName[0])))
+ {
+#if 0
+ TCHAR *p3 = &fileName[1];
+ if (0 == _tcscmp(p3, TEXT("l"))) {
+ SpeedValue = 0;
+ } else
+#endif
+ {
+ MacMsg(kStrBadArgTitle, kStrBadArgMessage,
+ falseblnr);
+ }
+ } else {
+ (void) InsertDiskOrAlias(fileName,
+ falseblnr, trueblnr);
+ }
+ }
+ }
+ }
+
+ return trueblnr;
+}
+
+#if EnableRecreateW
+LOCALPROC CheckMagnifyAndFullScreen(void)
+{
+ if (
+#if EnableMagnify
+ (UseMagnify != WantMagnify)
+#endif
+#if EnableMagnify && VarFullScreen
+ ||
+#endif
+#if VarFullScreen
+ (UseFullScreen != WantFullScreen)
+#endif
+ )
+ {
+ (void) ReCreateMainWindow();
+ }
+}
+#endif
+
+#if VarFullScreen && EnableMagnify
+enum {
+ kWinStateWindowed,
+#if EnableMagnify
+ kWinStateFullScreen,
+#endif
+ kNumWinStates
+};
+#endif
+
+#if VarFullScreen && EnableMagnify
+LOCALVAR int WinMagStates[kNumWinStates];
+#endif
+
+LOCALPROC ZapWinStateVars(void)
+{
+#if MayNotFullScreen
+ {
+ int i;
+
+ for (i = 0; i < kNumMagStates; ++i) {
+ HavePositionWins[i] = falseblnr;
+ }
+ }
+#endif
+#if VarFullScreen && EnableMagnify
+ {
+ int i;
+
+ for (i = 0; i < kNumWinStates; ++i) {
+ WinMagStates[i] = kMagStateAuto;
+ }
+ }
+#endif
+}
+
+#if VarFullScreen
+LOCALPROC ToggleWantFullScreen(void)
+{
+ WantFullScreen = ! WantFullScreen;
+
+#if EnableMagnify
+ {
+ int OldWinState =
+ UseFullScreen ? kWinStateFullScreen : kWinStateWindowed;
+ int OldMagState =
+ UseMagnify ? kMagStateMagnifgy : kMagStateNormal;
+ int NewWinState =
+ WantFullScreen ? kWinStateFullScreen : kWinStateWindowed;
+ int NewMagState = WinMagStates[NewWinState];
+
+ WinMagStates[OldWinState] = OldMagState;
+ if (kMagStateAuto != NewMagState) {
+ WantMagnify = (kMagStateMagnifgy == NewMagState);
+ } else {
+ WantMagnify = falseblnr;
+ if (WantFullScreen) {
+ if ((GetSystemMetrics(SM_CXSCREEN)
+ >= vMacScreenWidth * MyWindowScale)
+ && (GetSystemMetrics(SM_CYSCREEN)
+ >= vMacScreenHeight * MyWindowScale)
+ )
+ {
+ WantMagnify = trueblnr;
+ }
+ }
+ }
+ }
+#endif
+}
+#endif
+
+#if EnableDragDrop
+LOCALPROC DragFunc(HDROP hDrop)
+{
+ WORD n;
+ WORD i;
+ TCHAR a[_MAX_PATH];
+
+ n = DragQueryFile(hDrop, (UINT) -1, NULL, 0);
+ for (i = 0; i < n; ++i) {
+ if (DragQueryFile(hDrop, i, NULL, 0) < _MAX_PATH - 1) {
+ (void) DragQueryFile(hDrop, i, a, _MAX_PATH);
+ (void) InsertDiskOrAlias(a, trueblnr, trueblnr);
+ }
+ }
+
+ DragFinish(hDrop);
+
+ if (gTrueBackgroundFlag) {
+ if (! SetForegroundWindow(MainWnd)) {
+ /* error message here ? */
+ }
+
+ WantCmdOptOnReconnect = trueblnr;
+ }
+}
+#endif
+
+GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void)
+{
+#if MySoundEnabled
+ SoundCheckVeryOften();
+#endif
+ (void) UpdateTrueEmulatedTime();
+ return (TrueEmulatedTime == OnTrueTime);
+}
+
+/* --- platform independent code can be thought of as going here --- */
+
+LOCALPROC LeaveBackground(void)
+{
+ ReconnectKeyCodes3();
+}
+
+LOCALPROC EnterBackground(void)
+{
+ DisconnectKeyCodes3();
+
+#if VarFullScreen
+ if (WantFullScreen) {
+ ToggleWantFullScreen();
+ }
+#endif
+}
+
+LOCALPROC LeaveSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Start();
+#endif
+#if (MyTimeResolution != 0)
+ MyTimer_Resume();
+#endif
+}
+
+LOCALPROC EnterSpeedStopped(void)
+{
+#if (MyTimeResolution != 0)
+ MyTimer_Suspend();
+#endif
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+}
+
+LOCALPROC CheckForSavedTasks(void)
+{
+ /*
+ Check for things to do that rather wouldn't
+ have done at an awkward time.
+ */
+
+ if (MyEvtQNeedRecover) {
+ MyEvtQNeedRecover = falseblnr;
+
+ /* attempt cleanup, MyEvtQNeedRecover may get set again */
+ MyEvtQTryRecoverFromFull();
+ }
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMouseConstrain();
+ }
+#endif
+
+ if (RequestMacOff) {
+ RequestMacOff = falseblnr;
+ if (AnyDiskInserted()) {
+ MacMsgOverride(kStrQuitWarningTitle,
+ kStrQuitWarningMessage);
+ } else {
+ ForceMacOff = trueblnr;
+ }
+ }
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (gTrueBackgroundFlag != gBackgroundFlag) {
+ gBackgroundFlag = gTrueBackgroundFlag;
+ if (gTrueBackgroundFlag) {
+ EnterBackground();
+ } else {
+ LeaveBackground();
+ }
+ }
+
+ if (CurSpeedStopped != (SpeedStopped ||
+ (gBackgroundFlag && ! RunInBackground
+#if EnableAutoSlow && 0
+ && (QuietSubTicks >= 4092)
+#endif
+ )))
+ {
+ CurSpeedStopped = ! CurSpeedStopped;
+ if (CurSpeedStopped) {
+ EnterSpeedStopped();
+ } else {
+ LeaveSpeedStopped();
+ }
+ }
+
+#if EnableRecreateW
+ if (! (gTrueBackgroundFlag)) {
+ CheckMagnifyAndFullScreen();
+ }
+#endif
+
+#if MayFullScreen
+ if (GrabMachine != (
+#if VarFullScreen
+ UseFullScreen &&
+#endif
+ ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ GrabMachine = ! GrabMachine;
+ AdjustMachineGrab();
+ }
+#endif
+
+ if (gTrueBackgroundFlag) {
+ /*
+ wait til later
+ */
+ } else {
+#if IncludeSonyNew
+ if (vSonyNewDiskWanted) {
+#if IncludeSonyNameNew
+ if (vSonyNewDiskName != NotAPbuf) {
+ HGLOBAL NewDiskNameDat;
+ if (MacRomanTextToNativeHand(vSonyNewDiskName, trueblnr,
+ &NewDiskNameDat))
+ {
+ MakeNewDisk(vSonyNewDiskSize, NewDiskNameDat);
+ GlobalFree(NewDiskNameDat);
+ }
+ PbufDispose(vSonyNewDiskName);
+ vSonyNewDiskName = NotAPbuf;
+ } else
+#endif
+ {
+ MakeNewDisk(vSonyNewDiskSize, NULL);
+ }
+ vSonyNewDiskWanted = falseblnr;
+ /* must be done after may have gotten disk */
+ }
+#endif
+ if (RequestInsertDisk) {
+ RequestInsertDisk = falseblnr;
+ InsertADisk0();
+ }
+ }
+
+#if NeedRequestIthDisk
+ if (0 != RequestIthDisk) {
+ Sony_InsertIth(RequestIthDisk);
+ RequestIthDisk = 0;
+ }
+#endif
+
+ if (HaveCursorHidden != (WantCursorHidden
+ && ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ HaveCursorHidden = ! HaveCursorHidden;
+ if (HaveCursorHidden) {
+ (void) ShowCursor(FALSE);
+ } else {
+ (void) ShowCursor(TRUE);
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+ }
+ }
+
+ if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) {
+ MacMsgDisplayOn();
+ }
+
+ if (NeedWholeScreenDraw) {
+ NeedWholeScreenDraw = falseblnr;
+ ScreenChangedAll();
+ }
+}
+
+#if UseWinCE
+/* Sip Status ON/OFF */
+LOCALVAR blnr SipOn = falseblnr;
+#endif
+
+LRESULT CALLBACK Win32WMProc(HWND hwnd,
+ UINT uMessage, WPARAM wparam, LPARAM lparam);
+
+LRESULT CALLBACK Win32WMProc(HWND hwnd,
+ UINT uMessage, WPARAM wparam, LPARAM lparam)
+{
+ switch (uMessage)
+ {
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+
+ BeginPaint(hwnd, (LPPAINTSTRUCT)&ps);
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ if (! FillRect(ps.hdc,
+ &ps.rcPaint,
+ GetStockObject(BLACK_BRUSH)))
+ {
+ /* ReportGetLastError(); */
+ }
+ }
+#endif
+ if (MainWnd == hwnd) {
+ Screen_DrawAll();
+ }
+ EndPaint(hwnd, (LPPAINTSTRUCT)&ps);
+ }
+ break;
+
+ case WM_KEYDOWN:
+ case WM_SYSKEYDOWN:
+#if UseWinCE
+ SipOn = falseblnr;
+
+ {
+ SIPINFO r;
+
+ memset(&r, 0 , sizeof(SIPINFO));
+ r.cbSize = sizeof(SIPINFO);
+ if (SipGetInfo(&r)) {
+ SipOn = 0 != (r.fdwFlags & SIPF_ON);
+ }
+ }
+
+ if (wparam == 0xAE) {
+ break;
+ } else if ((! SipOn) && (wparam == VK_RETURN)) {
+ break;
+ } else if ((! SipOn)
+ && (wparam >= VK_LEFT) && (wparam <= VK_DOWN))
+ {
+ break;
+ } else if (wparam == VK_CONTROL && CtrlMode) {
+ DoVKcode0(wparam, falseblnr);
+ CtrlMode = falseblnr;
+ break;
+ } else if (wparam == VK_CONTROL) {
+ DoVKcode0(wparam, trueblnr);
+ CtrlMode = trueblnr;
+ break;
+ }
+#endif
+ if (! TestBit(lparam, 30)) { /* ignore repeats */
+ DoVKcode(wparam, lparam >> 24, trueblnr);
+ }
+
+#if UseWinCE
+ return TRUE;
+ /*
+ So that hardware keys won't be
+ processed by the default handler
+ */
+#endif
+
+ break;
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+#if UseWinCE
+ SipOn = falseblnr;
+
+ {
+ SIPINFO r;
+
+ memset(&r, 0 , sizeof(SIPINFO));
+ r.cbSize = sizeof(SIPINFO);
+ if (SipGetInfo(&r)) {
+ SipOn = 0 != (r.fdwFlags & SIPF_ON);
+ }
+ }
+
+ if (wparam == 0xAE) { /* to hide SoftInput panel */
+ SipShowIM(SIPF_OFF);
+ break;
+ } else if ((! SipOn) && (wparam == VK_RETURN)) {
+ /* DPad Action to show SIP */
+ /* Show SoftInput Panel */
+ SipShowIM(SIPF_ON);
+ break;
+ } else if ((! SipOn)
+ && (wparam >= VK_LEFT) && (wparam <= VK_DOWN))
+ {
+ switch (wparam) {
+ case VK_LEFT:
+ if (ViewHStart < (ViewHSize / 2)) {
+ ViewHStart = 0;
+ } else {
+ ViewHStart -= (ViewHSize / 2);
+ }
+ break;
+ case VK_UP:
+ if (ViewVStart < (ViewVSize / 2)) {
+ ViewVStart = 0;
+ } else {
+ ViewVStart -= (ViewVSize / 2);
+ }
+ break;
+ case VK_RIGHT:
+ ViewHStart += (ViewHSize / 2);
+ if (ViewHStart >= (vMacScreenWidth - ViewHSize))
+ {
+ ViewHStart = vMacScreenWidth - ViewHSize;
+ }
+ break;
+ case VK_DOWN:
+ ViewVStart += (ViewVSize / 2);
+ if (ViewVStart
+ >= (vMacScreenHeight - ViewVSize))
+ {
+ ViewVStart = vMacScreenHeight - ViewVSize;
+ }
+ break;
+ }
+ Screen_DrawAll();
+ } else
+ if (wparam == VK_CONTROL && CtrlMode) {
+ break;
+ }
+#endif
+ DoVKcode(wparam, lparam >> 24, falseblnr);
+
+#if UseWinCE
+ return TRUE;
+ /*
+ So that hardware keys won't be
+ processed by the default handler
+ */
+#endif
+
+ break;
+#if ItnlKyBdFix && ! UseWinCE
+ case WM_INPUTLANGCHANGE:
+ MyCheckKeyboardLayout();
+ return TRUE;
+ break;
+#endif
+
+ case WM_CLOSE:
+ RequestMacOff = trueblnr;
+ break;
+#if ! UseWinCE
+ case WM_QUERYENDSESSION:
+ if (AnyDiskInserted()) {
+ RequestMacOff = trueblnr;
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+ break;
+#endif
+ case WM_ACTIVATE:
+ if (MainWnd == hwnd) {
+ gTrueBackgroundFlag = (LOWORD(wparam) == WA_INACTIVE);
+ }
+ break;
+ case WM_COMMAND:
+ switch(LOWORD(wparam))
+ {
+ case ID_FILE_INSERTDISK1:
+ RequestInsertDisk = trueblnr;
+ break;
+ case ID_FILE_QUIT:
+ RequestMacOff = trueblnr;
+ break;
+ case ID_SPECIAL_MORECOMMANDS:
+ DoMoreCommandsMsg();
+ break;
+ case ID_HELP_ABOUT:
+ DoAboutMsg();
+ break;
+ }
+ break;
+ case WM_MOVE:
+ WndX = (si4b) LOWORD(lparam);
+ WndY = (si4b) HIWORD(lparam);
+ break;
+ case WM_SYSCHAR:
+ case WM_CHAR:
+ /* prevent any further processing */
+ break;
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ MousePositionNotify(LOWORD (lparam), HIWORD (lparam));
+ SetCurMouseButton(trueblnr);
+ break;
+ case WM_LBUTTONUP:
+ case WM_RBUTTONUP:
+ MousePositionNotify(LOWORD (lparam), HIWORD (lparam));
+ SetCurMouseButton(falseblnr);
+ break;
+ case WM_MOUSEMOVE:
+#if UseWinCE
+ MousePositionNotify(LOWORD (lparam), HIWORD (lparam));
+#endif
+ /* windows may have messed up cursor */
+ /*
+ there is no notification when the mouse moves
+ outside the window, and the cursor is automatically
+ changed
+ */
+ if (! HaveCursorHidden) {
+ /* SetCursor(LoadCursor(NULL, IDC_ARROW)); */
+ }
+ break;
+#if EnableDragDrop
+ case WM_CREATE:
+ DragAcceptFiles(hwnd, TRUE);
+ break;
+ case WM_DROPFILES:
+ DragFunc((HDROP) wparam);
+ break;
+ case WM_DESTROY:
+ DragAcceptFiles(hwnd, FALSE);
+ break;
+#endif
+ default:
+ return DefWindowProc(hwnd, uMessage, wparam, lparam);
+ }
+ return 0;
+}
+
+LOCALFUNC blnr RegisterOurClass(void)
+{
+ WNDCLASS wc;
+
+ wc.style = CS_HREDRAW | CS_VREDRAW
+#if ! UseWinCE
+ | CS_OWNDC
+#endif
+ ;
+ wc.lpfnWndProc = (WNDPROC)Win32WMProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = AppInstance;
+ wc.hIcon = LoadIcon(AppInstance, MAKEINTRESOURCE(IDI_VMAC));
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = GetStockObject(BLACK_BRUSH);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = WndClassName;
+
+ if (! RegisterClass(&wc)) {
+ MacMsg("RegisterClass failed",
+ "Sorry, Mini vMac encountered errors"
+ " and cannot continue.", trueblnr);
+ return falseblnr;
+ } else {
+ return trueblnr;
+ }
+}
+
+LOCALPROC WaitForTheNextEvent(void)
+{
+ MSG msg;
+
+ if (-1 != GetMessage(&msg, NULL, 0, 0)) {
+ DispatchMessage(&msg);
+ }
+}
+
+LOCALPROC CheckForSystemEvents(void)
+{
+ MSG msg;
+ ui3r i = 0;
+
+ while ((i < 32) && (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))) {
+ DispatchMessage(&msg);
+ ++i;
+ }
+}
+
+GLOBALOSGLUPROC WaitForNextTick(void)
+{
+label_retry:
+ CheckForSystemEvents();
+ CheckForSavedTasks();
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (CurSpeedStopped) {
+ DoneWithDrawingForTick();
+ WaitForTheNextEvent();
+ goto label_retry;
+ }
+
+ if (ExtraTimeNotOver()) {
+ Sleep(NextIntTime - LastTime);
+ goto label_retry;
+ }
+
+ if (CheckDateTime()) {
+#if MySoundEnabled
+ MySound_SecondNotify();
+#endif
+#if EnableDemoMsg
+ DemoModeSecondNotify();
+#endif
+ }
+
+ if (! (gBackgroundFlag)) {
+#if ! UseWinCE
+ CheckMouseState();
+#endif
+
+#if EnableGrabSpecialKeys
+ CheckForLostKeyUps();
+#endif
+ }
+
+ OnTrueTime = TrueEmulatedTime;
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("WaitForNextTick, OnTrueTime", OnTrueTime);
+#endif
+}
+
+#if UseWinCE
+LOCALFUNC blnr Init_ChangeOrientation(void)
+{
+ DEVMODE dm;
+
+ /* initialize the DEVMODE structure */
+ ZeroMemory(&dm, sizeof (dm));
+ dm.dmSize = sizeof (dm);
+
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
+
+ /* Backup old values */
+ oldOrientation = dm.dmOrientation;
+ oldDisplayOrientation = dm.dmDisplayOrientation;
+
+
+ /* Hide SIP (you can never tell...) */
+ SipShowIM(SIPF_OFF);
+
+ /* Switch to Landscape mode if possible */
+ dm.dmOrientation = DMORIENT_LANDSCAPE;
+ dm.dmDisplayOrientation = DMDO_90;
+ dm.dmFields = DM_ORIENTATION | DM_DISPLAYORIENTATION;
+ (void) ChangeDisplaySettingsEx(NULL, &dm, NULL, 0, 0);
+ /*
+ if (ChangeDisplaySettingsEx(NULL, &dm, NULL, 0, 0) !=
+ DISP_CHANGE_SUCCESSFUL)
+ {
+ MacMsg ("warning",
+ "Couldn't switch to Landscape mode.", falseblnr);
+ }
+ */
+
+ return trueblnr;
+}
+#endif
+
+#if UseWinCE
+LOCALPROC Uninit_ChangeOrientation(void)
+{
+ DEVMODE dm;
+
+ /* Restore old display orientation */
+ ZeroMemory(&dm, sizeof (dm));
+ dm.dmSize = sizeof(dm);
+
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
+
+ dm.dmOrientation = oldOrientation;
+ dm.dmDisplayOrientation = oldDisplayOrientation;
+ dm.dmFields = DM_ORIENTATION | DM_DISPLAYORIENTATION;
+
+ ChangeDisplaySettingsEx(NULL, &dm, 0, 0, 0);
+}
+#endif
+
+
+/* ** code for handling hardware keys in Pocket PC devices ** */
+
+#if UseWinCE
+typedef BOOL (__stdcall *UnregisterFunc1Proc)(UINT, UINT);
+LOCALVAR HINSTANCE hCoreDLL = NULL;
+#endif
+
+#if UseWinCE
+LOCALFUNC blnr InitHotKeys(void)
+{
+ UnregisterFunc1Proc procUndergisterFunc;
+ int i;
+
+ hCoreDLL = LoadLibrary(TEXT("coredll.dll"));
+ if (! hCoreDLL) {
+ MacMsg ("Fatal", "Could not load coredll.dll", trueblnr);
+ } else {
+ procUndergisterFunc =
+ (UnregisterFunc1Proc) GetProcAddress(hCoreDLL,
+ TEXT("UnregisterFunc1"));
+ if (! procUndergisterFunc) {
+ MacMsg ("Fatal",
+ "Could not get UnregisterFunc1 procedure", trueblnr);
+ } else {
+ for (i = 0xc1; i <= 0xcf; ++i) {
+ procUndergisterFunc(MOD_WIN, i);
+ RegisterHotKey(MainWnd, i, MOD_WIN, i);
+ }
+ }
+ }
+ return trueblnr;
+}
+#endif
+
+#if UseWinCE
+LOCALPROC UninitHotKeys(void)
+{
+ if (! hCoreDLL) {
+ FreeLibrary(hCoreDLL);
+ }
+}
+#endif
+
+#include "PROGMAIN.h"
+
+/* ************************ */
+
+LOCALPROC ZapOSGLUVars(void)
+{
+ InitDrives();
+ ZapWinStateVars();
+}
+
+LOCALPROC ReserveAllocAll(void)
+{
+#if dbglog_HAVE
+ dbglog_ReserveAlloc();
+#endif
+ ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr);
+ ReserveAllocOneBlock(&screencomparebuff,
+ vMacScreenNumBytes, 5, trueblnr);
+#if UseControlKeys
+ ReserveAllocOneBlock(&CntrlDisplayBuff,
+ vMacScreenNumBytes, 5, falseblnr);
+#endif
+#if EnableScalingBuff
+ {
+ ui5r n = vMacScreenMonoNumBytes
+#if EnableMagnify
+ * MyWindowScale * MyWindowScale
+#endif
+ ;
+#if 1 == vMacScreenDepth
+ if (vMacScreenNumBytes * 2 > n) {
+ n = vMacScreenNumBytes * 2;
+ }
+#elif vMacScreenDepth >= 4
+ if (vMacScreenNumBytes > n) {
+ n = vMacScreenNumBytes;
+ }
+#endif
+ ReserveAllocOneBlock(&ScalingBuff, n, 5, falseblnr);
+ }
+#endif
+#if MySoundEnabled
+ ReserveAllocOneBlock((ui3p *)&TheSoundBuffer,
+ dbhBufferSize, 5, falseblnr);
+#endif
+
+ EmulationReserveAlloc();
+}
+
+LOCALFUNC blnr AllocMyMemory(void)
+{
+ uimr n;
+ blnr IsOk = falseblnr;
+
+ ReserveAllocOffset = 0;
+ ReserveAllocBigBlock = nullpr;
+ ReserveAllocAll();
+ n = ReserveAllocOffset;
+ ReserveAllocBigBlock =
+ (ui3p)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, n);
+ if (NULL == ReserveAllocBigBlock) {
+ MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr);
+ } else {
+ ReserveAllocOffset = 0;
+ ReserveAllocAll();
+ if (n != ReserveAllocOffset) {
+ /* oops, program error */
+ } else {
+ IsOk = trueblnr;
+ }
+ }
+
+ return IsOk;
+}
+
+LOCALPROC UnallocMyMemory(void)
+{
+ if (nullpr != ReserveAllocBigBlock) {
+ if (GlobalFree(ReserveAllocBigBlock) != NULL) {
+ MacMsg("error", "GlobalFree failed", falseblnr);
+ }
+ }
+}
+
+LOCALFUNC blnr InitOSGLU(void)
+{
+ if (AllocMyMemory())
+#if dbglog_HAVE
+ if (dbglog_open())
+#endif
+ if (RegisterOurClass())
+ if (ScanCommandLine())
+ if (LoadInitialImages())
+#if InstallFileIcons
+ if (RegisterInRegistry())
+#endif
+ if (LoadMacRom())
+#if UseActvCode
+ if (ActvCodeInit())
+#endif
+#if UseWinCE
+ if (Init_ChangeOrientation())
+#endif
+ if (ReCreateMainWindow())
+ if (InitWinKey2Mac())
+ if (InitTheCursor())
+#if UseWinCE
+ if (InitHotKeys())
+#endif
+ if (Init60thCheck())
+ if (WaitForRom())
+ {
+ return trueblnr;
+ }
+ return falseblnr;
+}
+
+LOCALPROC UnInitOSGLU(void)
+{
+#if (MyTimeResolution != 0)
+ MyTimer_Suspend();
+#endif
+ MyMouseCaptureSet(falseblnr);
+
+ if (MacMsgDisplayed) {
+ MacMsgDisplayOff();
+ }
+
+#if MayFullScreen
+ UnGrabTheMachine();
+#endif
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+#if IncludePbufs
+ UnInitPbufs();
+#endif
+ UnInitDrives();
+
+ ForceShowCursor();
+#if UseWinCE
+ Uninit_ChangeOrientation();
+ UninitHotKeys();
+#endif
+
+#if EnableShellLinks
+ MyUninitCOM();
+#endif
+
+ if (! gTrueBackgroundFlag) {
+ CheckSavedMacMsg();
+ }
+
+ DisposeMainWindow();
+
+#if dbglog_HAVE
+ dbglog_close();
+#endif
+
+ UnallocMyMemory();
+}
+
+int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ LPTSTR lpCmdLine, int nCmdShow)
+{
+ UnusedParam(hPrevInstance);
+ AppInstance = hInstance;
+ CmdShow = nCmdShow;
+ CommandLine = lpCmdLine;
+
+ GetWndTitle();
+#if UseWinCE
+ if (AlreadyRunningCheck()) {
+ return 0;
+ }
+#endif
+
+ ZapOSGLUVars();
+ if (InitOSGLU()) {
+ ProgramMain();
+ }
+ UnInitOSGLU();
+
+ return(0);
+}
--- /dev/null
+++ b/src/OSGLUXWN.c
@@ -1,0 +1,4839 @@
+/*
+ OSGLUXWN.c
+
+ Copyright (C) 2009 Michael Hanni, Christian Bauer,
+ Stephan Kochen, Paul C. Pratt, and others
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Operating System GLUe for X WiNdow system
+
+ All operating system dependent code for the
+ X Window System should go here.
+
+ This code is descended from Michael Hanni's X
+ port of vMac, by Philip Cummins.
+ I learned more about how X programs work by
+ looking at other programs such as Basilisk II,
+ the UAE Amiga Emulator, Bochs, QuakeForge,
+ DooM Legacy, and the FLTK. A few snippets
+ from them are used here.
+
+ Drag and Drop support is based on the specification
+ "XDND: Drag-and-Drop Protocol for the X Window System"
+ developed by John Lindal at New Planet Software, and
+ looking at included examples, one by Paul Sheer.
+*/
+
+#include "CNFGRAPI.h"
+#include "SYSDEPNS.h"
+#include "ENDIANAC.h"
+
+#include "MYOSGLUE.h"
+
+#include "STRCONST.h"
+
+/* --- some simple utilities --- */
+
+GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount)
+{
+ (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount);
+}
+
+/* --- control mode and internationalization --- */
+
+#define NeedCell2PlainAsciiMap 1
+
+#include "INTLCHAR.h"
+
+
+LOCALVAR char *d_arg = NULL;
+LOCALVAR char *n_arg = NULL;
+
+#if CanGetAppPath
+LOCALVAR char *app_parent = NULL;
+LOCALVAR char *app_name = NULL;
+#endif
+
+LOCALFUNC tMacErr ChildPath(char *x, char *y, char **r)
+{
+ tMacErr err = mnvm_miscErr;
+ int nx = strlen(x);
+ int ny = strlen(y);
+ {
+ if ((nx > 0) && ('/' == x[nx - 1])) {
+ --nx;
+ }
+ {
+ int nr = nx + 1 + ny;
+ char *p = malloc(nr + 1);
+ if (p != NULL) {
+ char *p2 = p;
+ (void) memcpy(p2, x, nx);
+ p2 += nx;
+ *p2++ = '/';
+ (void) memcpy(p2, y, ny);
+ p2 += ny;
+ *p2 = 0;
+ *r = p;
+ err = mnvm_noErr;
+ }
+ }
+ }
+
+ return err;
+}
+
+#if UseActvFile || IncludeSonyNew
+LOCALFUNC tMacErr FindOrMakeChild(char *x, char *y, char **r)
+{
+ tMacErr err;
+ struct stat folder_info;
+ char *r0;
+
+ if (mnvm_noErr == (err = ChildPath(x, y, &r0))) {
+ if (0 != stat(r0, &folder_info)) {
+ if (0 != mkdir(r0, S_IRWXU)) {
+ err = mnvm_miscErr;
+ } else {
+ *r = r0;
+ err = mnvm_noErr;
+ }
+ } else {
+ if (! S_ISDIR(folder_info.st_mode)) {
+ err = mnvm_miscErr;
+ } else {
+ *r = r0;
+ err = mnvm_noErr;
+ }
+ }
+ }
+
+ return err;
+}
+#endif
+
+LOCALPROC MyMayFree(char *p)
+{
+ if (NULL != p) {
+ free(p);
+ }
+}
+
+/* --- sending debugging info to file --- */
+
+#if dbglog_HAVE
+
+#define dbglog_ToStdErr 0
+
+#if ! dbglog_ToStdErr
+LOCALVAR FILE *dbglog_File = NULL;
+#endif
+
+LOCALFUNC blnr dbglog_open0(void)
+{
+#if dbglog_ToStdErr
+ return trueblnr;
+#else
+ dbglog_File = fopen("dbglog.txt", "w");
+ return (NULL != dbglog_File);
+#endif
+}
+
+LOCALPROC dbglog_write0(char *s, uimr L)
+{
+#if dbglog_ToStdErr
+ (void) fwrite(s, 1, L, stderr);
+#else
+ if (dbglog_File != NULL) {
+ (void) fwrite(s, 1, L, dbglog_File);
+ }
+#endif
+}
+
+LOCALPROC dbglog_close0(void)
+{
+#if ! dbglog_ToStdErr
+ if (dbglog_File != NULL) {
+ fclose(dbglog_File);
+ dbglog_File = NULL;
+ }
+#endif
+}
+
+#endif
+
+/* --- debug settings and utilities --- */
+
+#if ! dbglog_HAVE
+#define WriteExtraErr(s)
+#else
+LOCALPROC WriteExtraErr(char *s)
+{
+ dbglog_writeCStr("*** error: ");
+ dbglog_writeCStr(s);
+ dbglog_writeReturn();
+}
+#endif
+
+LOCALVAR Display *x_display = NULL;
+
+#define MyDbgEvents (dbglog_HAVE && 0)
+
+#if MyDbgEvents
+LOCALPROC WriteDbgAtom(char *s, Atom x)
+{
+ char *name = XGetAtomName(x_display, x);
+ if (name != NULL) {
+ dbglog_writeCStr("Atom ");
+ dbglog_writeCStr(s);
+ dbglog_writeCStr(": ");
+ dbglog_writeCStr(name);
+ dbglog_writeReturn();
+ XFree(name);
+ }
+}
+#endif
+
+/* --- information about the environment --- */
+
+LOCALVAR Atom MyXA_DeleteW = (Atom)0;
+#if EnableDragDrop
+LOCALVAR Atom MyXA_UriList = (Atom)0;
+LOCALVAR Atom MyXA_DndAware = (Atom)0;
+LOCALVAR Atom MyXA_DndEnter = (Atom)0;
+LOCALVAR Atom MyXA_DndLeave = (Atom)0;
+LOCALVAR Atom MyXA_DndDrop = (Atom)0;
+LOCALVAR Atom MyXA_DndPosition = (Atom)0;
+LOCALVAR Atom MyXA_DndStatus = (Atom)0;
+LOCALVAR Atom MyXA_DndActionCopy = (Atom)0;
+LOCALVAR Atom MyXA_DndActionPrivate = (Atom)0;
+LOCALVAR Atom MyXA_DndSelection = (Atom)0;
+LOCALVAR Atom MyXA_DndFinished = (Atom)0;
+LOCALVAR Atom MyXA_MinivMac_DndXchng = (Atom)0;
+LOCALVAR Atom MyXA_NetActiveWindow = (Atom)0;
+LOCALVAR Atom MyXA_NetSupported = (Atom)0;
+#endif
+#if IncludeHostTextClipExchange
+LOCALVAR Atom MyXA_CLIPBOARD = (Atom)0;
+LOCALVAR Atom MyXA_TARGETS = (Atom)0;
+LOCALVAR Atom MyXA_MinivMac_Clip = (Atom)0;
+#endif
+
+LOCALPROC LoadMyXA(void)
+{
+ MyXA_DeleteW = XInternAtom(x_display, "WM_DELETE_WINDOW", False);
+#if EnableDragDrop
+ MyXA_UriList = XInternAtom (x_display, "text/uri-list", False);
+ MyXA_DndAware = XInternAtom (x_display, "XdndAware", False);
+ MyXA_DndEnter = XInternAtom(x_display, "XdndEnter", False);
+ MyXA_DndLeave = XInternAtom(x_display, "XdndLeave", False);
+ MyXA_DndDrop = XInternAtom(x_display, "XdndDrop", False);
+ MyXA_DndPosition = XInternAtom(x_display, "XdndPosition", False);
+ MyXA_DndStatus = XInternAtom(x_display, "XdndStatus", False);
+ MyXA_DndActionCopy = XInternAtom(x_display,
+ "XdndActionCopy", False);
+ MyXA_DndActionPrivate = XInternAtom(x_display,
+ "XdndActionPrivate", False);
+ MyXA_DndSelection = XInternAtom(x_display, "XdndSelection", False);
+ MyXA_DndFinished = XInternAtom(x_display, "XdndFinished", False);
+ MyXA_MinivMac_DndXchng = XInternAtom(x_display,
+ "_MinivMac_DndXchng", False);
+ MyXA_NetActiveWindow = XInternAtom(x_display,
+ "_NET_ACTIVE_WINDOW", False);
+ MyXA_NetSupported = XInternAtom(x_display,
+ "_NET_SUPPORTED", False);
+#endif
+#if IncludeHostTextClipExchange
+ MyXA_CLIPBOARD = XInternAtom(x_display, "CLIPBOARD", False);
+ MyXA_TARGETS = XInternAtom(x_display, "TARGETS", False);
+ MyXA_MinivMac_Clip = XInternAtom(x_display,
+ "_MinivMac_Clip", False);
+#endif
+}
+
+#if EnableDragDrop
+LOCALFUNC blnr NetSupportedContains(Atom x)
+{
+ /*
+ Note that the window manager could be replaced at
+ any time, so don't cache results of this function.
+ */
+ Atom ret_type;
+ int ret_format;
+ unsigned long ret_item;
+ unsigned long remain_byte;
+ unsigned long i;
+ unsigned char *s = 0;
+ blnr foundit = falseblnr;
+ Window rootwin = XRootWindow(x_display,
+ DefaultScreen(x_display));
+
+ if (Success != XGetWindowProperty(x_display, rootwin,
+ MyXA_NetSupported,
+ 0, 65535, False, XA_ATOM, &ret_type, &ret_format,
+ &ret_item, &remain_byte, &s))
+ {
+ WriteExtraErr("XGetWindowProperty failed");
+ } else if (! s) {
+ WriteExtraErr("XGetWindowProperty failed");
+ } else if (ret_type != XA_ATOM) {
+ WriteExtraErr("XGetWindowProperty returns wrong type");
+ } else {
+ Atom *v = (Atom *)s;
+
+ for (i = 0; i < ret_item; ++i) {
+ if (v[i] == x) {
+ foundit = trueblnr;
+ /* fprintf(stderr, "found the hint\n"); */
+ }
+ }
+ }
+ if (s) {
+ XFree(s);
+ }
+ return foundit;
+}
+#endif
+
+#define WantColorTransValid 1
+
+#include "COMOSGLU.h"
+
+#include "PBUFSTDC.h"
+
+#include "CONTROLM.h"
+
+/* --- text translation --- */
+
+#if IncludePbufs
+/* this is table for Windows, any changes needed for X? */
+LOCALVAR const ui3b Native2MacRomanTab[] = {
+ 0xAD, 0xB0, 0xE2, 0xC4, 0xE3, 0xC9, 0xA0, 0xE0,
+ 0xF6, 0xE4, 0xB6, 0xDC, 0xCE, 0xB2, 0xB3, 0xB7,
+ 0xB8, 0xD4, 0xD5, 0xD2, 0xD3, 0xA5, 0xD0, 0xD1,
+ 0xF7, 0xAA, 0xC5, 0xDD, 0xCF, 0xB9, 0xC3, 0xD9,
+ 0xCA, 0xC1, 0xA2, 0xA3, 0xDB, 0xB4, 0xBA, 0xA4,
+ 0xAC, 0xA9, 0xBB, 0xC7, 0xC2, 0xBD, 0xA8, 0xF8,
+ 0xA1, 0xB1, 0xC6, 0xD7, 0xAB, 0xB5, 0xA6, 0xE1,
+ 0xFC, 0xDA, 0xBC, 0xC8, 0xDE, 0xDF, 0xF0, 0xC0,
+ 0xCB, 0xE7, 0xE5, 0xCC, 0x80, 0x81, 0xAE, 0x82,
+ 0xE9, 0x83, 0xE6, 0xE8, 0xED, 0xEA, 0xEB, 0xEC,
+ 0xF5, 0x84, 0xF1, 0xEE, 0xEF, 0xCD, 0x85, 0xF9,
+ 0xAF, 0xF4, 0xF2, 0xF3, 0x86, 0xFA, 0xFB, 0xA7,
+ 0x88, 0x87, 0x89, 0x8B, 0x8A, 0x8C, 0xBE, 0x8D,
+ 0x8F, 0x8E, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95,
+ 0xFD, 0x96, 0x98, 0x97, 0x99, 0x9B, 0x9A, 0xD6,
+ 0xBF, 0x9D, 0x9C, 0x9E, 0x9F, 0xFE, 0xFF, 0xD8
+};
+#endif
+
+#if IncludePbufs
+LOCALFUNC tMacErr NativeTextToMacRomanPbuf(char *x, tPbuf *r)
+{
+ if (NULL == x) {
+ return mnvm_miscErr;
+ } else {
+ ui3p p;
+ ui5b L = strlen(x);
+
+ p = (ui3p)malloc(L);
+ if (NULL == p) {
+ return mnvm_miscErr;
+ } else {
+ ui3b *p0 = (ui3b *)x;
+ ui3b *p1 = (ui3b *)p;
+ int i;
+
+ for (i = L; --i >= 0; ) {
+ ui3b v = *p0++;
+ if (v >= 128) {
+ v = Native2MacRomanTab[v - 128];
+ } else if (10 == v) {
+ v = 13;
+ }
+ *p1++ = v;
+ }
+
+ return PbufNewFromPtr(p, L, r);
+ }
+ }
+}
+#endif
+
+#if IncludePbufs
+/* this is table for Windows, any changes needed for X? */
+LOCALVAR const ui3b MacRoman2NativeTab[] = {
+ 0xC4, 0xC5, 0xC7, 0xC9, 0xD1, 0xD6, 0xDC, 0xE1,
+ 0xE0, 0xE2, 0xE4, 0xE3, 0xE5, 0xE7, 0xE9, 0xE8,
+ 0xEA, 0xEB, 0xED, 0xEC, 0xEE, 0xEF, 0xF1, 0xF3,
+ 0xF2, 0xF4, 0xF6, 0xF5, 0xFA, 0xF9, 0xFB, 0xFC,
+ 0x86, 0xB0, 0xA2, 0xA3, 0xA7, 0x95, 0xB6, 0xDF,
+ 0xAE, 0xA9, 0x99, 0xB4, 0xA8, 0x80, 0xC6, 0xD8,
+ 0x81, 0xB1, 0x8D, 0x8E, 0xA5, 0xB5, 0x8A, 0x8F,
+ 0x90, 0x9D, 0xA6, 0xAA, 0xBA, 0xAD, 0xE6, 0xF8,
+ 0xBF, 0xA1, 0xAC, 0x9E, 0x83, 0x9A, 0xB2, 0xAB,
+ 0xBB, 0x85, 0xA0, 0xC0, 0xC3, 0xD5, 0x8C, 0x9C,
+ 0x96, 0x97, 0x93, 0x94, 0x91, 0x92, 0xF7, 0xB3,
+ 0xFF, 0x9F, 0xB9, 0xA4, 0x8B, 0x9B, 0xBC, 0xBD,
+ 0x87, 0xB7, 0x82, 0x84, 0x89, 0xC2, 0xCA, 0xC1,
+ 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, 0xCC, 0xD3, 0xD4,
+ 0xBE, 0xD2, 0xDA, 0xDB, 0xD9, 0xD0, 0x88, 0x98,
+ 0xAF, 0xD7, 0xDD, 0xDE, 0xB8, 0xF0, 0xFD, 0xFE
+};
+#endif
+
+#if IncludePbufs
+LOCALFUNC blnr MacRomanTextToNativePtr(tPbuf i, blnr IsFileName,
+ ui3p *r)
+{
+ ui3p p;
+ void *Buffer = PbufDat[i];
+ ui5b L = PbufSize[i];
+
+ p = (ui3p)malloc(L + 1);
+ if (p != NULL) {
+ ui3b *p0 = (ui3b *)Buffer;
+ ui3b *p1 = (ui3b *)p;
+ int j;
+
+ if (IsFileName) {
+ for (j = L; --j >= 0; ) {
+ ui3b x = *p0++;
+ if (x < 32) {
+ x = '-';
+ } else if (x >= 128) {
+ x = MacRoman2NativeTab[x - 128];
+ } else {
+ switch (x) {
+ case '/':
+ case '<':
+ case '>':
+ case '|':
+ case ':':
+ x = '-';
+ default:
+ break;
+ }
+ }
+ *p1++ = x;
+ }
+ if ('.' == p[0]) {
+ p[0] = '-';
+ }
+ } else {
+ for (j = L; --j >= 0; ) {
+ ui3b x = *p0++;
+ if (x >= 128) {
+ x = MacRoman2NativeTab[x - 128];
+ } else if (13 == x) {
+ x = '\n';
+ }
+ *p1++ = x;
+ }
+ }
+ *p1 = 0;
+
+ *r = p;
+ return trueblnr;
+ }
+ return falseblnr;
+}
+#endif
+
+LOCALPROC NativeStrFromCStr(char *r, char *s)
+{
+ ui3b ps[ClStrMaxLength];
+ int i;
+ int L;
+
+ ClStrFromSubstCStr(&L, ps, s);
+
+ for (i = 0; i < L; ++i) {
+ r[i] = Cell2PlainAsciiMap[ps[i]];
+ }
+
+ r[L] = 0;
+}
+
+/* --- drives --- */
+
+#define NotAfileRef NULL
+
+LOCALVAR FILE *Drives[NumDrives]; /* open disk image files */
+#if IncludeSonyGetName || IncludeSonyNew
+LOCALVAR char *DriveNames[NumDrives];
+#endif
+
+LOCALPROC InitDrives(void)
+{
+ /*
+ This isn't really needed, Drives[i] and DriveNames[i]
+ need not have valid values when not vSonyIsInserted[i].
+ */
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ Drives[i] = NotAfileRef;
+#if IncludeSonyGetName || IncludeSonyNew
+ DriveNames[i] = NULL;
+#endif
+ }
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer,
+ tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
+ ui5r *Sony_ActCount)
+{
+ tMacErr err = mnvm_miscErr;
+ FILE *refnum = Drives[Drive_No];
+ ui5r NewSony_Count = 0;
+
+ if (0 == fseek(refnum, Sony_Start, SEEK_SET)) {
+ if (IsWrite) {
+ NewSony_Count = fwrite(Buffer, 1, Sony_Count, refnum);
+ } else {
+ NewSony_Count = fread(Buffer, 1, Sony_Count, refnum);
+ }
+
+ if (NewSony_Count == Sony_Count) {
+ err = mnvm_noErr;
+ }
+ }
+
+ if (nullpr != Sony_ActCount) {
+ *Sony_ActCount = NewSony_Count;
+ }
+
+ return err; /*& figure out what really to return &*/
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count)
+{
+ tMacErr err = mnvm_miscErr;
+ FILE *refnum = Drives[Drive_No];
+ long v;
+
+ if (0 == fseek(refnum, 0, SEEK_END)) {
+ v = ftell(refnum);
+ if (v >= 0) {
+ *Sony_Count = v;
+ err = mnvm_noErr;
+ }
+ }
+
+ return err; /*& figure out what really to return &*/
+}
+
+#ifndef HaveAdvisoryLocks
+#define HaveAdvisoryLocks 1
+#endif
+
+/*
+ What is the difference between fcntl(fd, F_SETLK ...
+ and flock(fd ... ?
+*/
+
+#if HaveAdvisoryLocks
+LOCALFUNC blnr MyLockFile(FILE *refnum)
+{
+ blnr IsOk = falseblnr;
+
+#if 1
+ struct flock fl;
+ int fd = fileno(refnum);
+
+ fl.l_start = 0; /* starting offset */
+ fl.l_len = 0; /* len = 0 means until end of file */
+ /* fl.pid_t l_pid; */ /* lock owner, don't need to set */
+ fl.l_type = F_WRLCK; /* lock type: read/write, etc. */
+ fl.l_whence = SEEK_SET; /* type of l_start */
+ if (-1 == fcntl(fd, F_SETLK, &fl)) {
+ MacMsg(kStrImageInUseTitle, kStrImageInUseMessage,
+ falseblnr);
+ } else {
+ IsOk = trueblnr;
+ }
+#else
+ int fd = fileno(refnum);
+
+ if (-1 == flock(fd, LOCK_EX | LOCK_NB)) {
+ MacMsg(kStrImageInUseTitle, kStrImageInUseMessage,
+ falseblnr);
+ } else {
+ IsOk = trueblnr;
+ }
+#endif
+
+ return IsOk;
+}
+#endif
+
+#if HaveAdvisoryLocks
+LOCALPROC MyUnlockFile(FILE *refnum)
+{
+#if 1
+ struct flock fl;
+ int fd = fileno(refnum);
+
+ fl.l_start = 0; /* starting offset */
+ fl.l_len = 0; /* len = 0 means until end of file */
+ /* fl.pid_t l_pid; */ /* lock owner, don't need to set */
+ fl.l_type = F_UNLCK; /* lock type: read/write, etc. */
+ fl.l_whence = SEEK_SET; /* type of l_start */
+ if (-1 == fcntl(fd, F_SETLK, &fl)) {
+ /* an error occurred */
+ }
+#else
+ int fd = fileno(refnum);
+
+ if (-1 == flock(fd, LOCK_UN)) {
+ }
+#endif
+}
+#endif
+
+LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit)
+{
+ FILE *refnum = Drives[Drive_No];
+
+ DiskEjectedNotify(Drive_No);
+
+#if HaveAdvisoryLocks
+ MyUnlockFile(refnum);
+#endif
+
+ fclose(refnum);
+ Drives[Drive_No] = NotAfileRef; /* not really needed */
+
+#if IncludeSonyGetName || IncludeSonyNew
+ {
+ char *s = DriveNames[Drive_No];
+ if (NULL != s) {
+ if (deleteit) {
+ remove(s);
+ }
+ free(s);
+ DriveNames[Drive_No] = NULL; /* not really needed */
+ }
+ }
+#endif
+
+ return mnvm_noErr;
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No)
+{
+ return vSonyEject0(Drive_No, falseblnr);
+}
+
+#if IncludeSonyNew
+GLOBALOSGLUFUNC tMacErr vSonyEjectDelete(tDrive Drive_No)
+{
+ return vSonyEject0(Drive_No, trueblnr);
+}
+#endif
+
+LOCALPROC UnInitDrives(void)
+{
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ if (vSonyIsInserted(i)) {
+ (void) vSonyEject(i);
+ }
+ }
+}
+
+#if IncludeSonyGetName
+GLOBALOSGLUFUNC tMacErr vSonyGetName(tDrive Drive_No, tPbuf *r)
+{
+ char *drivepath = DriveNames[Drive_No];
+ if (NULL == drivepath) {
+ return mnvm_miscErr;
+ } else {
+ char *s = strrchr(drivepath, '/');
+ if (NULL == s) {
+ s = drivepath;
+ } else {
+ ++s;
+ }
+ return NativeTextToMacRomanPbuf(s, r);
+ }
+}
+#endif
+
+LOCALFUNC blnr Sony_Insert0(FILE *refnum, blnr locked,
+ char *drivepath)
+{
+ tDrive Drive_No;
+ blnr IsOk = falseblnr;
+
+ if (! FirstFreeDisk(&Drive_No)) {
+ MacMsg(kStrTooManyImagesTitle, kStrTooManyImagesMessage,
+ falseblnr);
+ } else {
+ /* printf("Sony_Insert0 %d\n", (int)Drive_No); */
+
+#if HaveAdvisoryLocks
+ if (locked || MyLockFile(refnum))
+#endif
+ {
+ Drives[Drive_No] = refnum;
+ DiskInsertNotify(Drive_No, locked);
+
+#if IncludeSonyGetName || IncludeSonyNew
+ {
+ ui5b L = strlen(drivepath);
+ char *p = malloc(L + 1);
+ if (p != NULL) {
+ (void) memcpy(p, drivepath, L + 1);
+ }
+ DriveNames[Drive_No] = p;
+ }
+#endif
+
+ IsOk = trueblnr;
+ }
+ }
+
+ if (! IsOk) {
+ fclose(refnum);
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr Sony_Insert1(char *drivepath, blnr silentfail)
+{
+ blnr locked = falseblnr;
+ /* printf("Sony_Insert1 %s\n", drivepath); */
+ FILE *refnum = fopen(drivepath, "rb+");
+ if (NULL == refnum) {
+ locked = trueblnr;
+ refnum = fopen(drivepath, "rb");
+ }
+ if (NULL == refnum) {
+ if (! silentfail) {
+ MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
+ }
+ } else {
+ return Sony_Insert0(refnum, locked, drivepath);
+ }
+ return falseblnr;
+}
+
+LOCALFUNC tMacErr LoadMacRomFrom(char *path)
+{
+ tMacErr err;
+ FILE *ROM_File;
+ int File_Size;
+
+ ROM_File = fopen(path, "rb");
+ if (NULL == ROM_File) {
+ err = mnvm_fnfErr;
+ } else {
+ File_Size = fread(ROM, 1, kROM_Size, ROM_File);
+ if (kROM_Size != File_Size) {
+ if (feof(ROM_File)) {
+ MacMsgOverride(kStrShortROMTitle,
+ kStrShortROMMessage);
+ err = mnvm_eofErr;
+ } else {
+ MacMsgOverride(kStrNoReadROMTitle,
+ kStrNoReadROMMessage);
+ err = mnvm_miscErr;
+ }
+ } else {
+ err = ROM_IsValid();
+ }
+ fclose(ROM_File);
+ }
+
+ return err;
+}
+
+LOCALFUNC blnr Sony_Insert1a(char *drivepath, blnr silentfail)
+{
+ blnr v;
+
+ if (! ROM_loaded) {
+ v = (mnvm_noErr == LoadMacRomFrom(drivepath));
+ } else {
+ v = Sony_Insert1(drivepath, silentfail);
+ }
+
+ return v;
+}
+
+LOCALFUNC blnr Sony_Insert2(char *s)
+{
+ char *d =
+#if CanGetAppPath
+ (NULL == d_arg) ? app_parent :
+#endif
+ d_arg;
+ blnr IsOk = falseblnr;
+
+ if (NULL == d) {
+ IsOk = Sony_Insert1(s, trueblnr);
+ } else {
+ char *t;
+
+ if (mnvm_noErr == ChildPath(d, s, &t)) {
+ IsOk = Sony_Insert1(t, trueblnr);
+ free(t);
+ }
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr Sony_InsertIth(int i)
+{
+ blnr v;
+
+ if ((i > 9) || ! FirstFreeDisk(nullpr)) {
+ v = falseblnr;
+ } else {
+ char s[] = "disk?.dsk";
+
+ s[4] = '0' + i;
+
+ v = Sony_Insert2(s);
+ }
+
+ return v;
+}
+
+LOCALFUNC blnr LoadInitialImages(void)
+{
+ if (! AnyDiskInserted()) {
+ int i;
+
+ for (i = 1; Sony_InsertIth(i); ++i) {
+ /* stop on first error (including file not found) */
+ }
+ }
+
+ return trueblnr;
+}
+
+#if IncludeSonyNew
+LOCALFUNC blnr WriteZero(FILE *refnum, ui5b L)
+{
+#define ZeroBufferSize 2048
+ ui5b i;
+ ui3b buffer[ZeroBufferSize];
+
+ memset(&buffer, 0, ZeroBufferSize);
+
+ while (L > 0) {
+ i = (L > ZeroBufferSize) ? ZeroBufferSize : L;
+ if (fwrite(buffer, 1, i, refnum) != i) {
+ return falseblnr;
+ }
+ L -= i;
+ }
+ return trueblnr;
+}
+#endif
+
+#if IncludeSonyNew
+LOCALPROC MakeNewDisk0(ui5b L, char *drivepath)
+{
+ blnr IsOk = falseblnr;
+ FILE *refnum = fopen(drivepath, "wb+");
+ if (NULL == refnum) {
+ MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
+ } else {
+ if (WriteZero(refnum, L)) {
+ IsOk = Sony_Insert0(refnum, falseblnr, drivepath);
+ refnum = NULL;
+ }
+ if (refnum != NULL) {
+ fclose(refnum);
+ }
+ if (! IsOk) {
+ (void) remove(drivepath);
+ }
+ }
+}
+#endif
+
+#if IncludeSonyNew
+LOCALPROC MakeNewDisk(ui5b L, char *drivename)
+{
+ char *d =
+#if CanGetAppPath
+ (NULL == d_arg) ? app_parent :
+#endif
+ d_arg;
+
+ if (NULL == d) {
+ MakeNewDisk0(L, drivename); /* in current directory */
+ } else {
+ tMacErr err;
+ char *t = NULL;
+ char *t2 = NULL;
+
+ if (mnvm_noErr == (err = FindOrMakeChild(d, "out", &t)))
+ if (mnvm_noErr == (err = ChildPath(t, drivename, &t2)))
+ {
+ MakeNewDisk0(L, t2);
+ }
+
+ MyMayFree(t2);
+ MyMayFree(t);
+ }
+}
+#endif
+
+#if IncludeSonyNew
+LOCALPROC MakeNewDiskAtDefault(ui5b L)
+{
+ char s[ClStrMaxLength + 1];
+
+ NativeStrFromCStr(s, "untitled.dsk");
+ MakeNewDisk(L, s);
+}
+#endif
+
+/* --- ROM --- */
+
+LOCALVAR char *rom_path = NULL;
+
+#if 0
+#include <pwd.h>
+#include <unistd.h>
+#endif
+
+LOCALFUNC tMacErr FindUserHomeFolder(char **r)
+{
+ tMacErr err;
+ char *s;
+#if 0
+ struct passwd *user;
+#endif
+
+ if (NULL != (s = getenv("HOME"))) {
+ *r = s;
+ err = mnvm_noErr;
+ } else
+#if 0
+ if ((NULL != (user = getpwuid(getuid())))
+ && (NULL != (s = user->pw_dir)))
+ {
+ /*
+ From getpwuid man page:
+ "An application that wants to determine its user's
+ home directory should inspect the value of HOME
+ (rather than the value getpwuid(getuid())->pw_dir)
+ since this allows the user to modify their notion of
+ "the home directory" during a login session."
+
+ But it is possible for HOME to not be set.
+ Some sources say to use getpwuid in that case.
+ */
+ *r = s;
+ err = mnvm_noErr;
+ } else
+#endif
+ {
+ err = mnvm_fnfErr;
+ }
+
+ return err;
+}
+
+LOCALFUNC tMacErr LoadMacRomFromHome(void)
+{
+ tMacErr err;
+ char *s;
+ char *t = NULL;
+ char *t2 = NULL;
+ char *t3 = NULL;
+
+ if (mnvm_noErr == (err = FindUserHomeFolder(&s)))
+ if (mnvm_noErr == (err = ChildPath(s, ".gryphel", &t)))
+ if (mnvm_noErr == (err = ChildPath(t, "mnvm_rom", &t2)))
+ if (mnvm_noErr == (err = ChildPath(t2, RomFileName, &t3)))
+ {
+ err = LoadMacRomFrom(t3);
+ }
+
+ MyMayFree(t3);
+ MyMayFree(t2);
+ MyMayFree(t);
+
+ return err;
+}
+
+#if CanGetAppPath
+LOCALFUNC tMacErr LoadMacRomFromAppPar(void)
+{
+ tMacErr err;
+ char *d =
+#if CanGetAppPath
+ (NULL == d_arg) ? app_parent :
+#endif
+ d_arg;
+ char *t = NULL;
+
+ if (NULL == d) {
+ err = mnvm_fnfErr;
+ } else {
+ if (mnvm_noErr == (err = ChildPath(d, RomFileName,
+ &t)))
+ {
+ err = LoadMacRomFrom(t);
+ }
+ }
+
+ MyMayFree(t);
+
+ return err;
+}
+#endif
+
+LOCALFUNC blnr LoadMacRom(void)
+{
+ tMacErr err;
+
+ if ((NULL == rom_path)
+ || (mnvm_fnfErr == (err = LoadMacRomFrom(rom_path))))
+#if CanGetAppPath
+ if (mnvm_fnfErr == (err = LoadMacRomFromAppPar()))
+#endif
+ if (mnvm_fnfErr == (err = LoadMacRomFromHome()))
+ if (mnvm_fnfErr == (err = LoadMacRomFrom(RomFileName)))
+ {
+ }
+
+ return trueblnr; /* keep launching Mini vMac, regardless */
+}
+
+#if UseActvFile
+
+#define ActvCodeFileName "act_1"
+
+LOCALFUNC tMacErr ActvCodeFileLoad(ui3p p)
+{
+ tMacErr err;
+ char *s;
+ char *t = NULL;
+ char *t2 = NULL;
+ char *t3 = NULL;
+
+ if (mnvm_noErr == (err = FindUserHomeFolder(&s)))
+ if (mnvm_noErr == (err = ChildPath(s, ".gryphel", &t)))
+ if (mnvm_noErr == (err = ChildPath(t, "mnvm_act", &t2)))
+ if (mnvm_noErr == (err = ChildPath(t2, ActvCodeFileName, &t3)))
+ {
+ FILE *Actv_File;
+ int File_Size;
+
+ Actv_File = fopen(t3, "rb");
+ if (NULL == Actv_File) {
+ err = mnvm_fnfErr;
+ } else {
+ File_Size = fread(p, 1, ActvCodeFileLen, Actv_File);
+ if (File_Size != ActvCodeFileLen) {
+ if (feof(Actv_File)) {
+ err = mnvm_eofErr;
+ } else {
+ err = mnvm_miscErr;
+ }
+ } else {
+ err = mnvm_noErr;
+ }
+ fclose(Actv_File);
+ }
+ }
+
+ MyMayFree(t3);
+ MyMayFree(t2);
+ MyMayFree(t);
+
+ return err;
+}
+
+LOCALFUNC tMacErr ActvCodeFileSave(ui3p p)
+{
+ tMacErr err;
+ char *s;
+ char *t = NULL;
+ char *t2 = NULL;
+ char *t3 = NULL;
+
+ if (mnvm_noErr == (err = FindUserHomeFolder(&s)))
+ if (mnvm_noErr == (err = FindOrMakeChild(s, ".gryphel", &t)))
+ if (mnvm_noErr == (err = FindOrMakeChild(t, "mnvm_act", &t2)))
+ if (mnvm_noErr == (err = ChildPath(t2, ActvCodeFileName, &t3)))
+ {
+ FILE *Actv_File;
+ int File_Size;
+
+ Actv_File = fopen(t3, "wb+");
+ if (NULL == Actv_File) {
+ err = mnvm_fnfErr;
+ } else {
+ File_Size = fwrite(p, 1, ActvCodeFileLen, Actv_File);
+ if (File_Size != ActvCodeFileLen) {
+ err = mnvm_miscErr;
+ } else {
+ err = mnvm_noErr;
+ }
+ fclose(Actv_File);
+ }
+ }
+
+ MyMayFree(t3);
+ MyMayFree(t2);
+ MyMayFree(t);
+
+ return err;
+}
+
+#endif /* UseActvFile */
+
+/* --- video out --- */
+
+LOCALVAR Window my_main_wind = 0;
+LOCALVAR GC my_gc = NULL;
+LOCALVAR blnr NeedFinishOpen1 = falseblnr;
+LOCALVAR blnr NeedFinishOpen2 = falseblnr;
+
+LOCALVAR XColor x_black;
+LOCALVAR XColor x_white;
+
+#if MayFullScreen
+LOCALVAR short hOffset;
+LOCALVAR short vOffset;
+#endif
+
+#if VarFullScreen
+LOCALVAR blnr UseFullScreen = (WantInitFullScreen != 0);
+#endif
+
+#if EnableMagnify
+LOCALVAR blnr UseMagnify = (WantInitMagnify != 0);
+#endif
+
+LOCALVAR blnr gBackgroundFlag = falseblnr;
+LOCALVAR blnr gTrueBackgroundFlag = falseblnr;
+LOCALVAR blnr CurSpeedStopped = trueblnr;
+
+#ifndef UseColorImage
+#define UseColorImage (0 != vMacScreenDepth)
+#endif
+
+LOCALVAR XImage *my_image = NULL;
+
+#if EnableMagnify
+LOCALVAR XImage *my_Scaled_image = NULL;
+#endif
+
+#if EnableMagnify
+#define MaxScale MyWindowScale
+#else
+#define MaxScale 1
+#endif
+
+#define WantScalingTabl (EnableMagnify || UseColorImage)
+
+#if WantScalingTabl
+
+LOCALVAR ui3p ScalingTabl = nullpr;
+
+#define ScalingTablsz1 (256 * MaxScale)
+
+#if UseColorImage
+#define ScalingTablsz (ScalingTablsz1 << 5)
+#else
+#define ScalingTablsz ScalingTablsz1
+#endif
+
+#endif /* WantScalingTabl */
+
+
+#define WantScalingBuff (EnableMagnify || UseColorImage)
+
+#if WantScalingBuff
+
+LOCALVAR ui3p ScalingBuff = nullpr;
+
+
+#if UseColorImage
+#define ScalingBuffsz \
+ (vMacScreenNumPixels * 4 * MaxScale * MaxScale)
+#else
+#define ScalingBuffsz ((long)vMacScreenMonoNumBytes \
+ * MaxScale * MaxScale)
+#endif
+
+#endif /* WantScalingBuff */
+
+
+#if EnableMagnify && ! UseColorImage
+LOCALPROC SetUpScalingTabl(void)
+{
+ ui3b *p4;
+ int i;
+ int j;
+ int k;
+ ui3r bitsRemaining;
+ ui3b t1;
+ ui3b t2;
+
+ p4 = ScalingTabl;
+ for (i = 0; i < 256; ++i) {
+ bitsRemaining = 8;
+ t2 = 0;
+ for (j = 8; --j >= 0; ) {
+ t1 = (i >> j) & 1;
+ for (k = MyWindowScale; --k >= 0; ) {
+ t2 = (t2 << 1) | t1;
+ if (--bitsRemaining == 0) {
+ *p4++ = t2;
+ bitsRemaining = 8;
+ t2 = 0;
+ }
+ }
+ }
+ }
+}
+#endif
+
+#if EnableMagnify && (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+LOCALPROC SetUpColorScalingTabl(void)
+{
+ int i;
+ int j;
+ int k;
+ int a;
+ ui5r v;
+ ui5p p4;
+
+ p4 = (ui5p)ScalingTabl;
+ for (i = 0; i < 256; ++i) {
+ for (k = 1 << (3 - vMacScreenDepth); --k >= 0; ) {
+ j = (i >> (k << vMacScreenDepth)) & (CLUT_size - 1);
+ v = (((long)CLUT_reds[j] & 0xFF00) << 8)
+ | ((long)CLUT_greens[j] & 0xFF00)
+ | (((long)CLUT_blues[j] & 0xFF00) >> 8);
+ for (a = MyWindowScale; --a >= 0; ) {
+ *p4++ = v;
+ }
+ }
+ }
+}
+#endif
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+LOCALPROC SetUpColorTabl(void)
+{
+ int i;
+ int j;
+ int k;
+ ui5p p4;
+
+ p4 = (ui5p)ScalingTabl;
+ for (i = 0; i < 256; ++i) {
+ for (k = 1 << (3 - vMacScreenDepth); --k >= 0; ) {
+ j = (i >> (k << vMacScreenDepth)) & (CLUT_size - 1);
+ *p4++ = (((long)CLUT_reds[j] & 0xFF00) << 8)
+ | ((long)CLUT_greens[j] & 0xFF00)
+ | (((long)CLUT_blues[j] & 0xFF00) >> 8);
+ }
+ }
+}
+#endif
+
+#if EnableMagnify && UseColorImage
+LOCALPROC SetUpBW2ColorScalingTabl(void)
+{
+ int i;
+ int k;
+ int a;
+ ui5r v;
+ ui5p p4;
+
+ p4 = (ui5p)ScalingTabl;
+ for (i = 0; i < 256; ++i) {
+ for (k = 8; --k >= 0; ) {
+ if (0 != ((i >> k) & 1)) {
+ v = 0;
+ } else {
+ v = 0xFFFFFF;
+ }
+
+ for (a = MyWindowScale; --a >= 0; ) {
+ *p4++ = v;
+ }
+ }
+ }
+}
+#endif
+
+#if UseColorImage
+LOCALPROC SetUpBW2ColorTabl(void)
+{
+ int i;
+ int k;
+ ui5r v;
+ ui5p p4;
+
+ p4 = (ui5p)ScalingTabl;
+ for (i = 0; i < 256; ++i) {
+ for (k = 8; --k >= 0; ) {
+ if (0 != ((i >> k) & 1)) {
+ v = 0;
+ } else {
+ v = 0xFFFFFF;
+ }
+ *p4++ = v;
+ }
+ }
+}
+#endif
+
+
+#if EnableMagnify && ! UseColorImage
+
+#define ScrnMapr_DoMap UpdateScaledBWCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 0
+#define ScrnMapr_Map ScalingTabl
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#endif
+
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+
+#define ScrnMapr_DoMap UpdateMappedColorCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map ScalingTabl
+
+#include "SCRNMAPR.h"
+
+#endif
+
+
+#if EnableMagnify && (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+
+#define ScrnMapr_DoMap UpdateMappedScaledColorCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map ScalingTabl
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#endif
+
+
+#if vMacScreenDepth >= 4
+
+#define ScrnTrns_DoTrans UpdateTransColorCopy
+#define ScrnTrns_Src GetCurDrawBuff()
+#define ScrnTrns_Dst ScalingBuff
+#define ScrnTrns_SrcDepth vMacScreenDepth
+#define ScrnTrns_DstDepth 5
+
+#include "SCRNTRNS.h"
+
+#endif
+
+#if EnableMagnify && (vMacScreenDepth >= 4)
+
+#define ScrnTrns_DoTrans UpdateTransScaledColorCopy
+#define ScrnTrns_Src GetCurDrawBuff()
+#define ScrnTrns_Dst ScalingBuff
+#define ScrnTrns_SrcDepth vMacScreenDepth
+#define ScrnTrns_DstDepth 5
+#define ScrnTrns_Scale MyWindowScale
+
+#include "SCRNTRNS.h"
+
+#endif
+
+
+#if EnableMagnify && UseColorImage
+
+#define ScrnMapr_DoMap UpdateMappedScaledBW2ColorCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map ScalingTabl
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#endif
+
+
+#if UseColorImage
+
+#define ScrnMapr_DoMap UpdateMappedBW2ColorCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map ScalingTabl
+
+#include "SCRNMAPR.h"
+
+#endif
+
+
+LOCALPROC HaveChangedScreenBuff(ui4r top, ui4r left,
+ ui4r bottom, ui4r right)
+{
+ int XDest;
+ int YDest;
+ char *the_data;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ if (top < ViewVStart) {
+ top = ViewVStart;
+ }
+ if (left < ViewHStart) {
+ left = ViewHStart;
+ }
+ if (bottom > ViewVStart + ViewVSize) {
+ bottom = ViewVStart + ViewVSize;
+ }
+ if (right > ViewHStart + ViewHSize) {
+ right = ViewHStart + ViewHSize;
+ }
+
+ if ((top >= bottom) || (left >= right)) {
+ goto label_exit;
+ }
+ }
+#endif
+
+ XDest = left;
+ YDest = top;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ XDest -= ViewHStart;
+ YDest -= ViewVStart;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ XDest *= MyWindowScale;
+ YDest *= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ XDest += hOffset;
+ YDest += vOffset;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+#if UseColorImage
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+#if vMacScreenDepth < 4
+ if (! ColorTransValid) {
+ SetUpColorScalingTabl();
+ ColorTransValid = trueblnr;
+ }
+
+ UpdateMappedScaledColorCopy(top, left, bottom, right);
+#else
+ UpdateTransScaledColorCopy(top, left, bottom, right);
+#endif
+ } else
+#endif /* 0 != vMacScreenDepth */
+ {
+ if (! ColorTransValid) {
+ SetUpBW2ColorScalingTabl();
+ ColorTransValid = trueblnr;
+ }
+
+ UpdateMappedScaledBW2ColorCopy(top, left, bottom, right);
+ }
+#else /* ! UseColorImage */
+ /* assume 0 == vMacScreenDepth */
+ {
+ if (! ColorTransValid) {
+ SetUpScalingTabl();
+ ColorTransValid = trueblnr;
+ }
+
+ UpdateScaledBWCopy(top, left, bottom, right);
+ }
+#endif /* UseColorImage */
+
+ {
+ char *saveData = my_Scaled_image->data;
+ my_Scaled_image->data = (char *)ScalingBuff;
+
+ XPutImage(x_display, my_main_wind, my_gc, my_Scaled_image,
+ left * MyWindowScale, top * MyWindowScale,
+ XDest, YDest,
+ (right - left) * MyWindowScale,
+ (bottom - top) * MyWindowScale);
+
+ my_Scaled_image->data = saveData;
+ }
+ } else
+#endif /* EnableMagnify */
+ {
+#if UseColorImage
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+#if vMacScreenDepth < 4
+
+ if (! ColorTransValid) {
+ SetUpColorTabl();
+ ColorTransValid = trueblnr;
+ }
+
+ UpdateMappedColorCopy(top, left, bottom, right);
+
+ the_data = (char *)ScalingBuff;
+#else
+ /*
+ if vMacScreenDepth == 5 and MSBFirst, could
+ copy directly with the_data = (char *)GetCurDrawBuff();
+ */
+ UpdateTransColorCopy(top, left, bottom, right);
+
+ the_data = (char *)ScalingBuff;
+#endif
+ } else
+#endif /* 0 != vMacScreenDepth */
+ {
+ if (! ColorTransValid) {
+ SetUpBW2ColorTabl();
+ ColorTransValid = trueblnr;
+ }
+
+ UpdateMappedBW2ColorCopy(top, left, bottom, right);
+
+ the_data = (char *)ScalingBuff;
+ }
+#else /* ! UseColorImage */
+ {
+ the_data = (char *)GetCurDrawBuff();
+ }
+#endif /* UseColorImage */
+
+ {
+ char *saveData = my_image->data;
+ my_image->data = the_data;
+
+ XPutImage(x_display, my_main_wind, my_gc, my_image,
+ left, top, XDest, YDest,
+ right - left, bottom - top);
+
+ my_image->data = saveData;
+ }
+ }
+
+#if MayFullScreen
+label_exit:
+ ;
+#endif
+}
+
+LOCALPROC MyDrawChangesAndClear(void)
+{
+ if (ScreenChangedBottom > ScreenChangedTop) {
+ HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft,
+ ScreenChangedBottom, ScreenChangedRight);
+ ScreenClearChanges();
+ }
+}
+
+/* --- mouse --- */
+
+/* cursor hiding */
+
+LOCALVAR blnr HaveCursorHidden = falseblnr;
+LOCALVAR blnr WantCursorHidden = falseblnr;
+
+LOCALPROC ForceShowCursor(void)
+{
+ if (HaveCursorHidden) {
+ HaveCursorHidden = falseblnr;
+ if (my_main_wind) {
+ XUndefineCursor(x_display, my_main_wind);
+ }
+ }
+}
+
+LOCALVAR Cursor blankCursor = None;
+
+LOCALFUNC blnr CreateMyBlankCursor(Window rootwin)
+/*
+ adapted from X11_CreateNullCursor in context.x11.c
+ in quakeforge 0.5.5, copyright Id Software, Inc.
+ Zephaniah E. Hull, and Jeff Teunissen.
+*/
+{
+ Pixmap cursormask;
+ XGCValues xgc;
+ GC gc;
+ blnr IsOk = falseblnr;
+
+ cursormask = XCreatePixmap(x_display, rootwin, 1, 1, 1);
+ if (None == cursormask) {
+ WriteExtraErr("XCreatePixmap failed.");
+ } else {
+ xgc.function = GXclear;
+ gc = XCreateGC(x_display, cursormask, GCFunction, &xgc);
+ if (None == gc) {
+ WriteExtraErr("XCreateGC failed.");
+ } else {
+ XFillRectangle(x_display, cursormask, gc, 0, 0, 1, 1);
+ XFreeGC(x_display, gc);
+
+ blankCursor = XCreatePixmapCursor(x_display, cursormask,
+ cursormask, &x_black, &x_white, 0, 0);
+ if (None == blankCursor) {
+ WriteExtraErr("XCreatePixmapCursor failed.");
+ } else {
+ IsOk = trueblnr;
+ }
+ }
+
+ XFreePixmap(x_display, cursormask);
+ /*
+ assuming that XCreatePixmapCursor doesn't think it
+ owns the pixmaps passed to it. I've seen code that
+ assumes this, and other code that seems to assume
+ the opposite.
+ */
+ }
+ return IsOk;
+}
+
+/* cursor moving */
+
+#if EnableMoveMouse
+LOCALFUNC blnr MyMoveMouse(si4b h, si4b v)
+{
+ int NewMousePosh;
+ int NewMousePosv;
+ int root_x_return;
+ int root_y_return;
+ Window root_return;
+ Window child_return;
+ unsigned int mask_return;
+ blnr IsOk;
+ int attempts = 0;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ h -= ViewHStart;
+ v -= ViewVStart;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ h *= MyWindowScale;
+ v *= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ h += hOffset;
+ v += vOffset;
+ }
+#endif
+
+ do {
+ XWarpPointer(x_display, None, my_main_wind, 0, 0, 0, 0, h, v);
+ XQueryPointer(x_display, my_main_wind,
+ &root_return, &child_return,
+ &root_x_return, &root_y_return,
+ &NewMousePosh, &NewMousePosv,
+ &mask_return);
+ IsOk = (h == NewMousePosh) && (v == NewMousePosv);
+ ++attempts;
+ } while ((! IsOk) && (attempts < 10));
+ return IsOk;
+}
+#endif
+
+#if EnableFSMouseMotion
+LOCALPROC StartSaveMouseMotion(void)
+{
+ if (! HaveMouseMotion) {
+ if (MyMoveMouse(ViewHStart + (ViewHSize / 2),
+ ViewVStart + (ViewVSize / 2)))
+ {
+ SavedMouseH = ViewHStart + (ViewHSize / 2);
+ SavedMouseV = ViewVStart + (ViewVSize / 2);
+ HaveMouseMotion = trueblnr;
+ }
+ }
+}
+#endif
+
+#if EnableFSMouseMotion
+LOCALPROC StopSaveMouseMotion(void)
+{
+ if (HaveMouseMotion) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ HaveMouseMotion = falseblnr;
+ }
+}
+#endif
+
+/* cursor state */
+
+#if EnableFSMouseMotion
+LOCALPROC MyMouseConstrain(void)
+{
+ si4b shiftdh;
+ si4b shiftdv;
+
+ if (SavedMouseH < ViewHStart + (ViewHSize / 4)) {
+ shiftdh = ViewHSize / 2;
+ } else if (SavedMouseH > ViewHStart + ViewHSize - (ViewHSize / 4)) {
+ shiftdh = - ViewHSize / 2;
+ } else {
+ shiftdh = 0;
+ }
+ if (SavedMouseV < ViewVStart + (ViewVSize / 4)) {
+ shiftdv = ViewVSize / 2;
+ } else if (SavedMouseV > ViewVStart + ViewVSize - (ViewVSize / 4)) {
+ shiftdv = - ViewVSize / 2;
+ } else {
+ shiftdv = 0;
+ }
+ if ((shiftdh != 0) || (shiftdv != 0)) {
+ SavedMouseH += shiftdh;
+ SavedMouseV += shiftdv;
+ if (! MyMoveMouse(SavedMouseH, SavedMouseV)) {
+ HaveMouseMotion = falseblnr;
+ }
+ }
+}
+#endif
+
+LOCALPROC MousePositionNotify(int NewMousePosh, int NewMousePosv)
+{
+ blnr ShouldHaveCursorHidden = trueblnr;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewMousePosh -= hOffset;
+ NewMousePosv -= vOffset;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ NewMousePosh /= MyWindowScale;
+ NewMousePosv /= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ NewMousePosh += ViewHStart;
+ NewMousePosv += ViewVStart;
+ }
+#endif
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMousePositionSetDelta(NewMousePosh - SavedMouseH,
+ NewMousePosv - SavedMouseV);
+ SavedMouseH = NewMousePosh;
+ SavedMouseV = NewMousePosv;
+ } else
+#endif
+ {
+ if (NewMousePosh < 0) {
+ NewMousePosh = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosh >= vMacScreenWidth) {
+ NewMousePosh = vMacScreenWidth - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+ if (NewMousePosv < 0) {
+ NewMousePosv = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosv >= vMacScreenHeight) {
+ NewMousePosv = vMacScreenHeight - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ ShouldHaveCursorHidden = trueblnr;
+ }
+#endif
+
+ /* if (ShouldHaveCursorHidden || CurMouseButton) */
+ /*
+ for a game like arkanoid, would like mouse to still
+ move even when outside window in one direction
+ */
+ MyMousePositionSet(NewMousePosh, NewMousePosv);
+ }
+
+ WantCursorHidden = ShouldHaveCursorHidden;
+}
+
+LOCALPROC CheckMouseState(void)
+{
+ int NewMousePosh;
+ int NewMousePosv;
+ int root_x_return;
+ int root_y_return;
+ Window root_return;
+ Window child_return;
+ unsigned int mask_return;
+
+ XQueryPointer(x_display, my_main_wind,
+ &root_return, &child_return,
+ &root_x_return, &root_y_return,
+ &NewMousePosh, &NewMousePosv,
+ &mask_return);
+ MousePositionNotify(NewMousePosh, NewMousePosv);
+}
+
+/* --- keyboard input --- */
+
+LOCALVAR KeyCode TheCapsLockCode;
+
+LOCALVAR ui3b KC2MKC[256];
+
+LOCALPROC KC2MKCAssignOne(KeySym ks, ui3r key)
+{
+ KeyCode code = XKeysymToKeycode(x_display, ks);
+ if (code != NoSymbol) {
+ KC2MKC[code] = key;
+ }
+#if 0
+ fprintf(stderr, "%d %d %d\n", (int)ks, key, (int)code);
+#endif
+}
+
+LOCALFUNC blnr KC2MKCInit(void)
+{
+ int i;
+
+ for (i = 0; i < 256; ++i) {
+ KC2MKC[i] = MKC_None;
+ }
+
+#if 0 /* find Keysym for a code */
+ for (i = 0; i < 64 * 1024; ++i) {
+ KeyCode code = XKeysymToKeycode(x_display, i);
+ if (115 == code) {
+ fprintf(stderr, "i %d\n", i);
+ }
+ }
+#endif
+
+ /*
+ start with redundant mappings, should get overwritten
+ by main mappings but define them just in case
+ */
+
+#ifdef XK_KP_Insert
+ KC2MKCAssignOne(XK_KP_Insert, MKC_KP0);
+#endif
+#ifdef XK_KP_End
+ KC2MKCAssignOne(XK_KP_End, MKC_KP1);
+#endif
+#ifdef XK_KP_Down
+ KC2MKCAssignOne(XK_KP_Down, MKC_KP2);
+#endif
+#ifdef XK_KP_Next
+ KC2MKCAssignOne(XK_KP_Next, MKC_KP3);
+#endif
+#ifdef XK_KP_Left
+ KC2MKCAssignOne(XK_KP_Left, MKC_KP4);
+#endif
+#ifdef XK_KP_Begin
+ KC2MKCAssignOne(XK_KP_Begin, MKC_KP5);
+#endif
+#ifdef XK_KP_Right
+ KC2MKCAssignOne(XK_KP_Right, MKC_KP6);
+#endif
+#ifdef XK_KP_Home
+ KC2MKCAssignOne(XK_KP_Home, MKC_KP7);
+#endif
+#ifdef XK_KP_Up
+ KC2MKCAssignOne(XK_KP_Up, MKC_KP8);
+#endif
+#ifdef XK_KP_Prior
+ KC2MKCAssignOne(XK_KP_Prior, MKC_KP9);
+#endif
+#ifdef XK_KP_Delete
+ KC2MKCAssignOne(XK_KP_Delete, MKC_Decimal);
+#endif
+
+ KC2MKCAssignOne(XK_asciitilde, MKC_formac_Grave);
+ KC2MKCAssignOne(XK_underscore, MKC_Minus);
+ KC2MKCAssignOne(XK_plus, MKC_Equal);
+ KC2MKCAssignOne(XK_braceleft, MKC_LeftBracket);
+ KC2MKCAssignOne(XK_braceright, MKC_RightBracket);
+ KC2MKCAssignOne(XK_bar, MKC_formac_BackSlash);
+ KC2MKCAssignOne(XK_colon, MKC_SemiColon);
+ KC2MKCAssignOne(XK_quotedbl, MKC_SingleQuote);
+ KC2MKCAssignOne(XK_less, MKC_Comma);
+ KC2MKCAssignOne(XK_greater, MKC_Period);
+ KC2MKCAssignOne(XK_question, MKC_formac_Slash);
+
+ KC2MKCAssignOne(XK_a, MKC_A);
+ KC2MKCAssignOne(XK_b, MKC_B);
+ KC2MKCAssignOne(XK_c, MKC_C);
+ KC2MKCAssignOne(XK_d, MKC_D);
+ KC2MKCAssignOne(XK_e, MKC_E);
+ KC2MKCAssignOne(XK_f, MKC_F);
+ KC2MKCAssignOne(XK_g, MKC_G);
+ KC2MKCAssignOne(XK_h, MKC_H);
+ KC2MKCAssignOne(XK_i, MKC_I);
+ KC2MKCAssignOne(XK_j, MKC_J);
+ KC2MKCAssignOne(XK_k, MKC_K);
+ KC2MKCAssignOne(XK_l, MKC_L);
+ KC2MKCAssignOne(XK_m, MKC_M);
+ KC2MKCAssignOne(XK_n, MKC_N);
+ KC2MKCAssignOne(XK_o, MKC_O);
+ KC2MKCAssignOne(XK_p, MKC_P);
+ KC2MKCAssignOne(XK_q, MKC_Q);
+ KC2MKCAssignOne(XK_r, MKC_R);
+ KC2MKCAssignOne(XK_s, MKC_S);
+ KC2MKCAssignOne(XK_t, MKC_T);
+ KC2MKCAssignOne(XK_u, MKC_U);
+ KC2MKCAssignOne(XK_v, MKC_V);
+ KC2MKCAssignOne(XK_w, MKC_W);
+ KC2MKCAssignOne(XK_x, MKC_X);
+ KC2MKCAssignOne(XK_y, MKC_Y);
+ KC2MKCAssignOne(XK_z, MKC_Z);
+
+ /*
+ main mappings
+ */
+
+ KC2MKCAssignOne(XK_F1, MKC_formac_F1);
+ KC2MKCAssignOne(XK_F2, MKC_formac_F2);
+ KC2MKCAssignOne(XK_F3, MKC_formac_F3);
+ KC2MKCAssignOne(XK_F4, MKC_formac_F4);
+ KC2MKCAssignOne(XK_F5, MKC_formac_F5);
+ KC2MKCAssignOne(XK_F6, MKC_F6);
+ KC2MKCAssignOne(XK_F7, MKC_F7);
+ KC2MKCAssignOne(XK_F8, MKC_F8);
+ KC2MKCAssignOne(XK_F9, MKC_F9);
+ KC2MKCAssignOne(XK_F10, MKC_F10);
+ KC2MKCAssignOne(XK_F11, MKC_F11);
+ KC2MKCAssignOne(XK_F12, MKC_F12);
+
+#ifdef XK_Delete
+ KC2MKCAssignOne(XK_Delete, MKC_formac_ForwardDel);
+#endif
+#ifdef XK_Insert
+ KC2MKCAssignOne(XK_Insert, MKC_formac_Help);
+#endif
+#ifdef XK_Help
+ KC2MKCAssignOne(XK_Help, MKC_formac_Help);
+#endif
+#ifdef XK_Home
+ KC2MKCAssignOne(XK_Home, MKC_formac_Home);
+#endif
+#ifdef XK_End
+ KC2MKCAssignOne(XK_End, MKC_formac_End);
+#endif
+
+#ifdef XK_Page_Up
+ KC2MKCAssignOne(XK_Page_Up, MKC_formac_PageUp);
+#else
+#ifdef XK_Prior
+ KC2MKCAssignOne(XK_Prior, MKC_formac_PageUp);
+#endif
+#endif
+
+#ifdef XK_Page_Down
+ KC2MKCAssignOne(XK_Page_Down, MKC_formac_PageDown);
+#else
+#ifdef XK_Next
+ KC2MKCAssignOne(XK_Next, MKC_formac_PageDown);
+#endif
+#endif
+
+#ifdef XK_Print
+ KC2MKCAssignOne(XK_Print, MKC_Print);
+#endif
+#ifdef XK_Scroll_Lock
+ KC2MKCAssignOne(XK_Scroll_Lock, MKC_ScrollLock);
+#endif
+#ifdef XK_Pause
+ KC2MKCAssignOne(XK_Pause, MKC_Pause);
+#endif
+
+ KC2MKCAssignOne(XK_KP_Add, MKC_KPAdd);
+ KC2MKCAssignOne(XK_KP_Subtract, MKC_KPSubtract);
+ KC2MKCAssignOne(XK_KP_Multiply, MKC_KPMultiply);
+ KC2MKCAssignOne(XK_KP_Divide, MKC_KPDevide);
+ KC2MKCAssignOne(XK_KP_Enter, MKC_formac_Enter);
+ KC2MKCAssignOne(XK_KP_Equal, MKC_KPEqual);
+
+ KC2MKCAssignOne(XK_KP_0, MKC_KP0);
+ KC2MKCAssignOne(XK_KP_1, MKC_KP1);
+ KC2MKCAssignOne(XK_KP_2, MKC_KP2);
+ KC2MKCAssignOne(XK_KP_3, MKC_KP3);
+ KC2MKCAssignOne(XK_KP_4, MKC_KP4);
+ KC2MKCAssignOne(XK_KP_5, MKC_KP5);
+ KC2MKCAssignOne(XK_KP_6, MKC_KP6);
+ KC2MKCAssignOne(XK_KP_7, MKC_KP7);
+ KC2MKCAssignOne(XK_KP_8, MKC_KP8);
+ KC2MKCAssignOne(XK_KP_9, MKC_KP9);
+ KC2MKCAssignOne(XK_KP_Decimal, MKC_Decimal);
+
+ KC2MKCAssignOne(XK_Left, MKC_Left);
+ KC2MKCAssignOne(XK_Right, MKC_Right);
+ KC2MKCAssignOne(XK_Up, MKC_Up);
+ KC2MKCAssignOne(XK_Down, MKC_Down);
+
+ KC2MKCAssignOne(XK_grave, MKC_formac_Grave);
+ KC2MKCAssignOne(XK_minus, MKC_Minus);
+ KC2MKCAssignOne(XK_equal, MKC_Equal);
+ KC2MKCAssignOne(XK_bracketleft, MKC_LeftBracket);
+ KC2MKCAssignOne(XK_bracketright, MKC_RightBracket);
+ KC2MKCAssignOne(XK_backslash, MKC_formac_BackSlash);
+ KC2MKCAssignOne(XK_semicolon, MKC_SemiColon);
+ KC2MKCAssignOne(XK_apostrophe, MKC_SingleQuote);
+ KC2MKCAssignOne(XK_comma, MKC_Comma);
+ KC2MKCAssignOne(XK_period, MKC_Period);
+ KC2MKCAssignOne(XK_slash, MKC_formac_Slash);
+
+ KC2MKCAssignOne(XK_Escape, MKC_formac_Escape);
+
+ KC2MKCAssignOne(XK_Tab, MKC_Tab);
+ KC2MKCAssignOne(XK_Return, MKC_Return);
+ KC2MKCAssignOne(XK_space, MKC_Space);
+ KC2MKCAssignOne(XK_BackSpace, MKC_BackSpace);
+
+ KC2MKCAssignOne(XK_Caps_Lock, MKC_formac_CapsLock);
+ KC2MKCAssignOne(XK_Num_Lock, MKC_Clear);
+
+ KC2MKCAssignOne(XK_Meta_L, MKC_formac_Command);
+
+ KC2MKCAssignOne(XK_Meta_R, MKC_formac_RCommand);
+
+ KC2MKCAssignOne(XK_Mode_switch, MKC_formac_Option);
+ KC2MKCAssignOne(XK_Menu, MKC_formac_Option);
+ KC2MKCAssignOne(XK_Super_L, MKC_formac_Option);
+ KC2MKCAssignOne(XK_Super_R, MKC_formac_ROption);
+ KC2MKCAssignOne(XK_Hyper_L, MKC_formac_Option);
+ KC2MKCAssignOne(XK_Hyper_R, MKC_formac_ROption);
+
+ KC2MKCAssignOne(XK_F13, MKC_formac_Option);
+ /*
+ seen being used in Mandrake Linux 9.2
+ for windows key
+ */
+
+ KC2MKCAssignOne(XK_Shift_L, MKC_formac_Shift);
+ KC2MKCAssignOne(XK_Shift_R, MKC_formac_RShift);
+
+ KC2MKCAssignOne(XK_Alt_L, MKC_formac_Command);
+
+ KC2MKCAssignOne(XK_Alt_R, MKC_formac_RCommand);
+
+ KC2MKCAssignOne(XK_Control_L, MKC_formac_Control);
+
+ KC2MKCAssignOne(XK_Control_R, MKC_formac_RControl);
+
+ KC2MKCAssignOne(XK_1, MKC_1);
+ KC2MKCAssignOne(XK_2, MKC_2);
+ KC2MKCAssignOne(XK_3, MKC_3);
+ KC2MKCAssignOne(XK_4, MKC_4);
+ KC2MKCAssignOne(XK_5, MKC_5);
+ KC2MKCAssignOne(XK_6, MKC_6);
+ KC2MKCAssignOne(XK_7, MKC_7);
+ KC2MKCAssignOne(XK_8, MKC_8);
+ KC2MKCAssignOne(XK_9, MKC_9);
+ KC2MKCAssignOne(XK_0, MKC_0);
+
+ KC2MKCAssignOne(XK_A, MKC_A);
+ KC2MKCAssignOne(XK_B, MKC_B);
+ KC2MKCAssignOne(XK_C, MKC_C);
+ KC2MKCAssignOne(XK_D, MKC_D);
+ KC2MKCAssignOne(XK_E, MKC_E);
+ KC2MKCAssignOne(XK_F, MKC_F);
+ KC2MKCAssignOne(XK_G, MKC_G);
+ KC2MKCAssignOne(XK_H, MKC_H);
+ KC2MKCAssignOne(XK_I, MKC_I);
+ KC2MKCAssignOne(XK_J, MKC_J);
+ KC2MKCAssignOne(XK_K, MKC_K);
+ KC2MKCAssignOne(XK_L, MKC_L);
+ KC2MKCAssignOne(XK_M, MKC_M);
+ KC2MKCAssignOne(XK_N, MKC_N);
+ KC2MKCAssignOne(XK_O, MKC_O);
+ KC2MKCAssignOne(XK_P, MKC_P);
+ KC2MKCAssignOne(XK_Q, MKC_Q);
+ KC2MKCAssignOne(XK_R, MKC_R);
+ KC2MKCAssignOne(XK_S, MKC_S);
+ KC2MKCAssignOne(XK_T, MKC_T);
+ KC2MKCAssignOne(XK_U, MKC_U);
+ KC2MKCAssignOne(XK_V, MKC_V);
+ KC2MKCAssignOne(XK_W, MKC_W);
+ KC2MKCAssignOne(XK_X, MKC_X);
+ KC2MKCAssignOne(XK_Y, MKC_Y);
+ KC2MKCAssignOne(XK_Z, MKC_Z);
+
+ TheCapsLockCode = XKeysymToKeycode(x_display, XK_Caps_Lock);
+
+ InitKeyCodes();
+
+ return trueblnr;
+}
+
+LOCALPROC CheckTheCapsLock(void)
+{
+ int NewMousePosh;
+ int NewMousePosv;
+ int root_x_return;
+ int root_y_return;
+ Window root_return;
+ Window child_return;
+ unsigned int mask_return;
+
+ XQueryPointer(x_display, my_main_wind,
+ &root_return, &child_return,
+ &root_x_return, &root_y_return,
+ &NewMousePosh, &NewMousePosv,
+ &mask_return);
+
+ Keyboard_UpdateKeyMap2(MKC_formac_CapsLock,
+ (mask_return & LockMask) != 0);
+}
+
+LOCALPROC DoKeyCode0(int i, blnr down)
+{
+ ui3r key = KC2MKC[i];
+ if (MKC_None != key) {
+ Keyboard_UpdateKeyMap2(key, down);
+ }
+}
+
+LOCALPROC DoKeyCode(int i, blnr down)
+{
+ if (i == TheCapsLockCode) {
+ CheckTheCapsLock();
+ } else if (i >= 0 && i < 256) {
+ DoKeyCode0(i, down);
+ }
+}
+
+#if MayFullScreen && GrabKeysFullScreen
+LOCALVAR blnr KeyboardIsGrabbed = falseblnr;
+#endif
+
+#if MayFullScreen && GrabKeysFullScreen
+LOCALPROC MyGrabKeyboard(void)
+{
+ if (! KeyboardIsGrabbed) {
+ (void) XGrabKeyboard(x_display, my_main_wind,
+ False, GrabModeAsync, GrabModeAsync,
+ CurrentTime);
+ KeyboardIsGrabbed = trueblnr;
+ }
+}
+#endif
+
+#if MayFullScreen && GrabKeysFullScreen
+LOCALPROC MyUnGrabKeyboard(void)
+{
+ if (KeyboardIsGrabbed && my_main_wind) {
+ XUngrabKeyboard(x_display, CurrentTime);
+ KeyboardIsGrabbed = falseblnr;
+ }
+}
+#endif
+
+LOCALVAR blnr NoKeyRepeat = falseblnr;
+LOCALVAR int SaveKeyRepeat;
+
+LOCALPROC DisableKeyRepeat(void)
+{
+ XKeyboardState r;
+ XKeyboardControl k;
+
+ if ((! NoKeyRepeat) && (x_display != NULL)) {
+ NoKeyRepeat = trueblnr;
+
+ XGetKeyboardControl(x_display, &r);
+ SaveKeyRepeat = r.global_auto_repeat;
+
+ k.auto_repeat_mode = AutoRepeatModeOff;
+ XChangeKeyboardControl(x_display, KBAutoRepeatMode, &k);
+ }
+}
+
+LOCALPROC RestoreKeyRepeat(void)
+{
+ XKeyboardControl k;
+
+ if (NoKeyRepeat && (x_display != NULL)) {
+ NoKeyRepeat = falseblnr;
+
+ k.auto_repeat_mode = SaveKeyRepeat;
+ XChangeKeyboardControl(x_display, KBAutoRepeatMode, &k);
+ }
+}
+
+LOCALVAR blnr WantCmdOptOnReconnect = falseblnr;
+
+LOCALPROC GetTheDownKeys(void)
+{
+ char keys_return[32];
+ int i;
+ int v;
+ int j;
+
+ XQueryKeymap(x_display, keys_return);
+
+ for (i = 0; i < 32; ++i) {
+ v = keys_return[i];
+ for (j = 0; j < 8; ++j) {
+ if (0 != ((1 << j) & v)) {
+ int k = i * 8 + j;
+ if (k != TheCapsLockCode) {
+ DoKeyCode0(k, trueblnr);
+ }
+ }
+ }
+ }
+}
+
+LOCALPROC ReconnectKeyCodes3(void)
+{
+ CheckTheCapsLock();
+
+ if (WantCmdOptOnReconnect) {
+ WantCmdOptOnReconnect = falseblnr;
+
+ GetTheDownKeys();
+ }
+}
+
+LOCALPROC DisconnectKeyCodes3(void)
+{
+ DisconnectKeyCodes2();
+ MyMouseButtonSet(falseblnr);
+}
+
+/* --- time, date, location --- */
+
+#define dbglog_TimeStuff (0 && dbglog_HAVE)
+
+LOCALVAR ui5b TrueEmulatedTime = 0;
+
+#include "DATE2SEC.h"
+
+#define TicksPerSecond 1000000
+
+LOCALVAR blnr HaveTimeDelta = falseblnr;
+LOCALVAR ui5b TimeDelta;
+
+LOCALVAR ui5b NewMacDateInSeconds;
+
+LOCALVAR ui5b LastTimeSec;
+LOCALVAR ui5b LastTimeUsec;
+
+LOCALPROC GetCurrentTicks(void)
+{
+ struct timeval t;
+
+ gettimeofday(&t, NULL);
+ if (! HaveTimeDelta) {
+ time_t Current_Time;
+ struct tm *s;
+
+ (void) time(&Current_Time);
+ s = localtime(&Current_Time);
+ TimeDelta = Date2MacSeconds(s->tm_sec, s->tm_min, s->tm_hour,
+ s->tm_mday, 1 + s->tm_mon, 1900 + s->tm_year) - t.tv_sec;
+#if 0 && AutoTimeZone /* how portable is this ? */
+ CurMacDelta = ((ui5b)(s->tm_gmtoff) & 0x00FFFFFF)
+ | ((s->tm_isdst ? 0x80 : 0) << 24);
+#endif
+ HaveTimeDelta = trueblnr;
+ }
+
+ NewMacDateInSeconds = t.tv_sec + TimeDelta;
+ LastTimeSec = (ui5b)t.tv_sec;
+ LastTimeUsec = (ui5b)t.tv_usec;
+}
+
+#define MyInvTimeStep 16626 /* TicksPerSecond / 60.14742 */
+
+LOCALVAR ui5b NextTimeSec;
+LOCALVAR ui5b NextTimeUsec;
+
+LOCALPROC IncrNextTime(void)
+{
+ NextTimeUsec += MyInvTimeStep;
+ if (NextTimeUsec >= TicksPerSecond) {
+ NextTimeUsec -= TicksPerSecond;
+ NextTimeSec += 1;
+ }
+}
+
+LOCALPROC InitNextTime(void)
+{
+ NextTimeSec = LastTimeSec;
+ NextTimeUsec = LastTimeUsec;
+ IncrNextTime();
+}
+
+LOCALPROC StartUpTimeAdjust(void)
+{
+ GetCurrentTicks();
+ InitNextTime();
+}
+
+LOCALFUNC si5b GetTimeDiff(void)
+{
+ return ((si5b)(LastTimeSec - NextTimeSec)) * TicksPerSecond
+ + ((si5b)(LastTimeUsec - NextTimeUsec));
+}
+
+LOCALPROC UpdateTrueEmulatedTime(void)
+{
+ si5b TimeDiff;
+
+ GetCurrentTicks();
+
+ TimeDiff = GetTimeDiff();
+ if (TimeDiff >= 0) {
+ if (TimeDiff > 16 * MyInvTimeStep) {
+ /* emulation interrupted, forget it */
+ ++TrueEmulatedTime;
+ InitNextTime();
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("emulation interrupted",
+ TrueEmulatedTime);
+#endif
+ } else {
+ do {
+ ++TrueEmulatedTime;
+ IncrNextTime();
+ TimeDiff -= TicksPerSecond;
+ } while (TimeDiff >= 0);
+ }
+ } else if (TimeDiff < - 16 * MyInvTimeStep) {
+ /* clock goofed if ever get here, reset */
+#if dbglog_TimeStuff
+ dbglog_writeln("clock set back");
+#endif
+
+ InitNextTime();
+ }
+}
+
+LOCALFUNC blnr CheckDateTime(void)
+{
+ if (CurMacDateInSeconds != NewMacDateInSeconds) {
+ CurMacDateInSeconds = NewMacDateInSeconds;
+ return trueblnr;
+ } else {
+ return falseblnr;
+ }
+}
+
+LOCALFUNC blnr InitLocationDat(void)
+{
+ GetCurrentTicks();
+ CurMacDateInSeconds = NewMacDateInSeconds;
+
+ return trueblnr;
+}
+
+/* --- sound --- */
+
+#if MySoundEnabled
+
+#define kLn2SoundBuffers 4 /* kSoundBuffers must be a power of two */
+#define kSoundBuffers (1 << kLn2SoundBuffers)
+#define kSoundBuffMask (kSoundBuffers - 1)
+
+#define DesiredMinFilledSoundBuffs 3
+ /*
+ if too big then sound lags behind emulation.
+ if too small then sound will have pauses.
+ */
+
+#define kLnOneBuffLen 9
+#define kLnAllBuffLen (kLn2SoundBuffers + kLnOneBuffLen)
+#define kOneBuffLen (1UL << kLnOneBuffLen)
+#define kAllBuffLen (1UL << kLnAllBuffLen)
+#define kLnOneBuffSz (kLnOneBuffLen + kLn2SoundSampSz - 3)
+#define kLnAllBuffSz (kLnAllBuffLen + kLn2SoundSampSz - 3)
+#define kOneBuffSz (1UL << kLnOneBuffSz)
+#define kAllBuffSz (1UL << kLnAllBuffSz)
+#define kOneBuffMask (kOneBuffLen - 1)
+#define kAllBuffMask (kAllBuffLen - 1)
+#define dbhBufferSize (kAllBuffSz + kOneBuffSz)
+
+#define dbglog_SoundStuff (0 && dbglog_HAVE)
+#define dbglog_SoundBuffStats (0 && dbglog_HAVE)
+
+LOCALVAR tpSoundSamp TheSoundBuffer = nullpr;
+LOCALVAR ui4b ThePlayOffset;
+LOCALVAR ui4b TheFillOffset;
+LOCALVAR ui4b TheWriteOffset;
+LOCALVAR ui4b MinFilledSoundBuffs;
+
+LOCALPROC MySound_Start0(void)
+{
+ /* Reset variables */
+ ThePlayOffset = 0;
+ TheFillOffset = 0;
+ TheWriteOffset = 0;
+ MinFilledSoundBuffs = kSoundBuffers;
+}
+
+GLOBALOSGLUFUNC tpSoundSamp MySound_BeginWrite(ui4r n, ui4r *actL)
+{
+ ui4b ToFillLen = kAllBuffLen - (TheWriteOffset - ThePlayOffset);
+ ui4b WriteBuffContig =
+ kOneBuffLen - (TheWriteOffset & kOneBuffMask);
+
+ if (WriteBuffContig < n) {
+ n = WriteBuffContig;
+ }
+ if (ToFillLen < n) {
+ /* overwrite previous buffer */
+#if dbglog_SoundStuff
+ dbglog_writeln("sound buffer over flow");
+#endif
+ TheWriteOffset -= kOneBuffLen;
+ }
+
+ *actL = n;
+ return TheSoundBuffer + (TheWriteOffset & kAllBuffMask);
+}
+
+LOCALFUNC blnr MySound_EndWrite0(ui4r actL)
+{
+ blnr v;
+
+ TheWriteOffset += actL;
+
+ if (0 != (TheWriteOffset & kOneBuffMask)) {
+ v = falseblnr;
+ } else {
+ /* just finished a block */
+
+ TheFillOffset = TheWriteOffset;
+
+ v = trueblnr;
+ }
+
+ return v;
+}
+
+LOCALPROC MySound_SecondNotify0(void)
+{
+ if (MinFilledSoundBuffs > DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too high");
+#endif
+ IncrNextTime();
+ } else if (MinFilledSoundBuffs < DesiredMinFilledSoundBuffs) {
+#if dbglog_SoundStuff
+ dbglog_writeln("MinFilledSoundBuffs too low");
+#endif
+ ++TrueEmulatedTime;
+ }
+ MinFilledSoundBuffs = kSoundBuffers;
+}
+
+#define SOUND_SAMPLERATE 22255 /* = round(7833600 * 2 / 704) */
+
+#include "SOUNDGLU.h"
+
+#endif
+
+/* --- basic dialogs --- */
+
+LOCALPROC CheckSavedMacMsg(void)
+{
+ /* called only on quit, if error saved but not yet reported */
+
+ if (nullpr != SavedBriefMsg) {
+ char briefMsg0[ClStrMaxLength + 1];
+ char longMsg0[ClStrMaxLength + 1];
+
+ NativeStrFromCStr(briefMsg0, SavedBriefMsg);
+ NativeStrFromCStr(longMsg0, SavedLongMsg);
+
+ fprintf(stderr, "%s\n", briefMsg0);
+ fprintf(stderr, "%s\n", longMsg0);
+
+ SavedBriefMsg = nullpr;
+ }
+}
+
+/* --- clipboard --- */
+
+#if IncludeHostTextClipExchange
+LOCALVAR ui3p MyClipBuffer = NULL;
+#endif
+
+#if IncludeHostTextClipExchange
+LOCALPROC FreeMyClipBuffer(void)
+{
+ if (MyClipBuffer != NULL) {
+ free(MyClipBuffer);
+ MyClipBuffer = NULL;
+ }
+}
+#endif
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEexport(tPbuf i)
+{
+ tMacErr err = mnvm_miscErr;
+
+ FreeMyClipBuffer();
+ if (MacRomanTextToNativePtr(i, falseblnr,
+ &MyClipBuffer))
+ {
+ XSetSelectionOwner(x_display, MyXA_CLIPBOARD,
+ my_main_wind, CurrentTime);
+ err = mnvm_noErr;
+ }
+
+ PbufDispose(i);
+
+ return err;
+}
+#endif
+
+#if IncludeHostTextClipExchange
+LOCALFUNC blnr WaitForClipboardSelection(XEvent *xevent)
+{
+ struct timespec rqt;
+ struct timespec rmt;
+ int i;
+
+ for (i = 100; --i >= 0; ) {
+ while (XCheckTypedWindowEvent(x_display, my_main_wind,
+ SelectionNotify, xevent))
+ {
+ if (xevent->xselection.selection != MyXA_CLIPBOARD) {
+ /*
+ not what we were looking for. lose it.
+ (and hope it wasn't too important).
+ */
+ WriteExtraErr("Discarding unwanted SelectionNotify");
+ } else {
+ /* this is our event */
+ return trueblnr;
+ }
+ }
+
+ rqt.tv_sec = 0;
+ rqt.tv_nsec = 10000000;
+ (void) nanosleep(&rqt, &rmt);
+ }
+ return falseblnr;
+}
+#endif
+
+#if IncludeHostTextClipExchange
+LOCALPROC HTCEimport_do(void)
+{
+ Window w = XGetSelectionOwner(x_display, MyXA_CLIPBOARD);
+
+ if (w == my_main_wind) {
+ /* We own the clipboard, already have MyClipBuffer */
+ } else {
+ FreeMyClipBuffer();
+ if (w != None) {
+ XEvent xevent;
+
+ XDeleteProperty(x_display, my_main_wind,
+ MyXA_MinivMac_Clip);
+ XConvertSelection(x_display, MyXA_CLIPBOARD, XA_STRING,
+ MyXA_MinivMac_Clip, my_main_wind, CurrentTime);
+
+ if (WaitForClipboardSelection(&xevent)) {
+ if (None == xevent.xselection.property) {
+ /* oops, target not supported */
+ } else {
+ if (xevent.xselection.property
+ != MyXA_MinivMac_Clip)
+ {
+ /* not where we expected it */
+ } else {
+ Atom ret_type;
+ int ret_format;
+ unsigned long ret_item;
+ unsigned long remain_byte;
+ unsigned char *s = NULL;
+
+ if ((Success != XGetWindowProperty(
+ x_display, my_main_wind, MyXA_MinivMac_Clip,
+ 0, 65535, False, AnyPropertyType, &ret_type,
+ &ret_format, &ret_item, &remain_byte, &s))
+ || (ret_type != XA_STRING)
+ || (ret_format != 8)
+ || (NULL == s))
+ {
+ WriteExtraErr(
+ "XGetWindowProperty failed"
+ " in HTCEimport_do");
+ } else {
+ MyClipBuffer = (ui3p)malloc(ret_item + 1);
+ if (NULL == MyClipBuffer) {
+ MacMsg(kStrOutOfMemTitle,
+ kStrOutOfMemMessage, falseblnr);
+ } else {
+ MyMoveBytes((anyp)s, (anyp)MyClipBuffer,
+ ret_item);
+ MyClipBuffer[ret_item] = 0;
+ }
+ XFree(s);
+ }
+ }
+ XDeleteProperty(x_display, my_main_wind,
+ MyXA_MinivMac_Clip);
+ }
+ }
+ }
+ }
+}
+#endif
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEimport(tPbuf *r)
+{
+ HTCEimport_do();
+
+ return NativeTextToMacRomanPbuf((char *)MyClipBuffer, r);
+}
+#endif
+
+#if IncludeHostTextClipExchange
+LOCALFUNC blnr HandleSelectionRequestClipboard(XEvent *theEvent)
+{
+ blnr RequestFilled = falseblnr;
+
+#if MyDbgEvents
+ dbglog_writeln("Requested MyXA_CLIPBOARD");
+#endif
+
+ if (NULL == MyClipBuffer) {
+ /* our clipboard is empty */
+ } else if (theEvent->xselectionrequest.target == MyXA_TARGETS) {
+ Atom a[2];
+
+ a[0] = MyXA_TARGETS;
+ a[1] = XA_STRING;
+
+ XChangeProperty(x_display,
+ theEvent->xselectionrequest.requestor,
+ theEvent->xselectionrequest.property,
+ MyXA_TARGETS,
+ 32,
+ /*
+ most, but not all, other programs I've
+ look at seem to use 8 here, but that
+ can't be right. can it?
+ */
+ PropModeReplace,
+ (unsigned char *)a,
+ sizeof(a) / sizeof(Atom));
+
+ RequestFilled = trueblnr;
+ } else if (theEvent->xselectionrequest.target == XA_STRING) {
+ XChangeProperty(x_display,
+ theEvent->xselectionrequest.requestor,
+ theEvent->xselectionrequest.property,
+ XA_STRING,
+ 8,
+ PropModeReplace,
+ (unsigned char *)MyClipBuffer,
+ strlen((char *)MyClipBuffer));
+
+ RequestFilled = trueblnr;
+ }
+
+ return RequestFilled;
+}
+#endif
+
+/* --- drag and drop --- */
+
+#if EnableDragDrop
+LOCALPROC MyActivateWind(Time time)
+{
+ if (NetSupportedContains(MyXA_NetActiveWindow)) {
+ XEvent xevent;
+ Window rootwin = XRootWindow(x_display,
+ DefaultScreen(x_display));
+
+ memset(&xevent, 0, sizeof (xevent));
+
+ xevent.xany.type = ClientMessage;
+ xevent.xclient.send_event = True;
+ xevent.xclient.window = my_main_wind;
+ xevent.xclient.message_type = MyXA_NetActiveWindow;
+ xevent.xclient.format = 32;
+ xevent.xclient.data.l[0] = 1;
+ xevent.xclient.data.l[1]= time;
+
+ if (0 == XSendEvent(x_display, rootwin, 0,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xevent))
+ {
+ WriteExtraErr("XSendEvent failed in MyActivateWind");
+ }
+ }
+
+ XRaiseWindow(x_display, my_main_wind);
+ /*
+ In RedHat 7.1, _NET_ACTIVE_WINDOW supported,
+ but XSendEvent of _NET_ACTIVE_WINDOW
+ doesn't raise the window. So just always
+ call XRaiseWindow. Hopefully calling
+ XRaiseWindow won't do any harm on window
+ managers where it isn't needed.
+ (Such as in Ubuntu 5.10)
+ */
+ XSetInputFocus(x_display, my_main_wind,
+ RevertToPointerRoot, time);
+ /* And call this always too, just in case */
+}
+#endif
+
+#if EnableDragDrop
+LOCALPROC ParseOneUri(char *s)
+{
+ /* printf("ParseOneUri %s\n", s); */
+ if (('f' == s[0]) && ('i' == s[1]) && ('l' == s[2])
+ && ('e' == s[3]) && (':' == s[4]))
+ {
+ s += 5;
+ if (('/' == s[0]) && ('/' == s[1])) {
+ /* skip hostname */
+ char c;
+
+ s += 2;
+ while ((c = *s) != '/') {
+ if (0 == c) {
+ return;
+ }
+ ++s;
+ }
+ }
+ (void) Sony_Insert1a(s, falseblnr);
+ }
+}
+#endif
+
+#if EnableDragDrop
+LOCALFUNC int HexChar2Nib(char x)
+{
+ if ((x >= '0') && (x <= '9')) {
+ return x - '0';
+ } else if ((x >= 'A') && (x <= 'F')) {
+ return x - 'A' + 10;
+ } else if ((x >= 'a') && (x <= 'f')) {
+ return x - 'a' + 10;
+ } else {
+ return -1;
+ }
+}
+#endif
+
+#if EnableDragDrop
+LOCALPROC ParseUriList(char *s)
+{
+ char *p1 = s;
+ char *p0 = s;
+ char *p = s;
+ char c;
+
+ /* printf("ParseUriList %s\n", s); */
+ while ((c = *p++) != 0) {
+ if ('%' == c) {
+ int a;
+ int b;
+
+ if (((a = HexChar2Nib(p[0])) >= 0) &&
+ ((b = HexChar2Nib(p[1])) >= 0))
+ {
+ p += 2;
+ *p1++ = (a << 4) + b;
+ } else {
+ *p1++ = c;
+ }
+ } else if (('\n' == c) || ('\r' == c)) {
+ *p1++ = 0;
+ ParseOneUri(p0);
+ p0 = p1;
+ } else {
+ *p1++ = c;
+ }
+ }
+ *p1++ = 0;
+ ParseOneUri(p0);
+}
+#endif
+
+#if EnableDragDrop
+LOCALVAR Window PendingDragWindow = None;
+#endif
+
+#if EnableDragDrop
+LOCALPROC HandleSelectionNotifyDnd(XEvent *theEvent)
+{
+ blnr DropOk = falseblnr;
+
+#if MyDbgEvents
+ dbglog_writeln("Got MyXA_DndSelection");
+#endif
+
+ if ((theEvent->xselection.property == MyXA_MinivMac_DndXchng)
+ && (theEvent->xselection.target == MyXA_UriList))
+ {
+ Atom ret_type;
+ int ret_format;
+ unsigned long ret_item;
+ unsigned long remain_byte;
+ unsigned char *s = NULL;
+
+ if ((Success != XGetWindowProperty(x_display, my_main_wind,
+ MyXA_MinivMac_DndXchng,
+ 0, 65535, False, MyXA_UriList, &ret_type, &ret_format,
+ &ret_item, &remain_byte, &s))
+ || (NULL == s))
+ {
+ WriteExtraErr(
+ "XGetWindowProperty failed in SelectionNotify");
+ } else {
+ ParseUriList((char *)s);
+ DropOk = trueblnr;
+ XFree(s);
+ }
+ } else {
+ WriteExtraErr("Got Unknown SelectionNotify");
+ }
+
+ XDeleteProperty(x_display, my_main_wind,
+ MyXA_MinivMac_DndXchng);
+
+ if (PendingDragWindow != None) {
+ XEvent xevent;
+
+ memset(&xevent, 0, sizeof(xevent));
+
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = x_display;
+ xevent.xclient.window = PendingDragWindow;
+ xevent.xclient.message_type = MyXA_DndFinished;
+ xevent.xclient.format = 32;
+
+ xevent.xclient.data.l[0] = my_main_wind;
+ if (DropOk) {
+ xevent.xclient.data.l[1] = 1;
+ }
+ xevent.xclient.data.l[2] = MyXA_DndActionPrivate;
+
+ if (0 == XSendEvent(x_display,
+ PendingDragWindow, 0, 0, &xevent))
+ {
+ WriteExtraErr("XSendEvent failed in SelectionNotify");
+ }
+ }
+ if (DropOk && gTrueBackgroundFlag) {
+ MyActivateWind(theEvent->xselection.time);
+
+ WantCmdOptOnReconnect = trueblnr;
+ }
+}
+#endif
+
+#if EnableDragDrop
+LOCALPROC HandleClientMessageDndPosition(XEvent *theEvent)
+{
+ XEvent xevent;
+ int xr;
+ int yr;
+ unsigned int dr;
+ unsigned int wr;
+ unsigned int hr;
+ unsigned int bwr;
+ Window rr;
+ Window srcwin = theEvent->xclient.data.l[0];
+
+#if MyDbgEvents
+ dbglog_writeln("Got XdndPosition");
+#endif
+
+ XGetGeometry(x_display, my_main_wind,
+ &rr, &xr, &yr, &wr, &hr, &bwr, &dr);
+ memset (&xevent, 0, sizeof(xevent));
+ xevent.xany.type = ClientMessage;
+ xevent.xany.display = x_display;
+ xevent.xclient.window = srcwin;
+ xevent.xclient.message_type = MyXA_DndStatus;
+ xevent.xclient.format = 32;
+
+ xevent.xclient.data.l[0] = theEvent->xclient.window;
+ /* Target Window */
+ xevent.xclient.data.l[1] = 1; /* Accept */
+ xevent.xclient.data.l[2] = ((xr) << 16) | ((yr) & 0xFFFFUL);
+ xevent.xclient.data.l[3] = ((wr) << 16) | ((hr) & 0xFFFFUL);
+ xevent.xclient.data.l[4] = MyXA_DndActionPrivate; /* Action */
+
+ if (0 == XSendEvent(x_display, srcwin, 0, 0, &xevent)) {
+ WriteExtraErr(
+ "XSendEvent failed in HandleClientMessageDndPosition");
+ }
+}
+#endif
+
+#if EnableDragDrop
+LOCALPROC HandleClientMessageDndDrop(XEvent *theEvent)
+{
+ Time timestamp = theEvent->xclient.data.l[2];
+ PendingDragWindow = (Window) theEvent->xclient.data.l[0];
+
+#if MyDbgEvents
+ dbglog_writeln("Got XdndDrop");
+#endif
+
+ XConvertSelection(x_display, MyXA_DndSelection, MyXA_UriList,
+ MyXA_MinivMac_DndXchng, my_main_wind, timestamp);
+}
+#endif
+
+#define UseMotionEvents 1
+
+#if UseMotionEvents
+LOCALVAR blnr CaughtMouse = falseblnr;
+#endif
+
+#if MayNotFullScreen
+LOCALVAR int SavedTransH;
+LOCALVAR int SavedTransV;
+#endif
+
+/* --- event handling for main window --- */
+
+LOCALPROC HandleTheEvent(XEvent *theEvent)
+{
+ if (theEvent->xany.display != x_display) {
+ WriteExtraErr("Got event for some other display");
+ } else switch(theEvent->type) {
+ case KeyPress:
+ if (theEvent->xkey.window != my_main_wind) {
+ WriteExtraErr("Got KeyPress for some other window");
+ } else {
+#if MyDbgEvents
+ dbglog_writeln("- event - KeyPress");
+#endif
+
+ MousePositionNotify(theEvent->xkey.x, theEvent->xkey.y);
+ DoKeyCode(theEvent->xkey.keycode, trueblnr);
+ }
+ break;
+ case KeyRelease:
+ if (theEvent->xkey.window != my_main_wind) {
+ WriteExtraErr("Got KeyRelease for some other window");
+ } else {
+#if MyDbgEvents
+ dbglog_writeln("- event - KeyRelease");
+#endif
+
+ MousePositionNotify(theEvent->xkey.x, theEvent->xkey.y);
+ DoKeyCode(theEvent->xkey.keycode, falseblnr);
+ }
+ break;
+ case ButtonPress:
+ /* any mouse button, we don't care which */
+ if (theEvent->xbutton.window != my_main_wind) {
+ WriteExtraErr("Got ButtonPress for some other window");
+ } else {
+ /*
+ could check some modifiers, but don't bother for now
+ Keyboard_UpdateKeyMap2(MKC_formac_CapsLock,
+ (theEvent->xbutton.state & LockMask) != 0);
+ */
+ MousePositionNotify(
+ theEvent->xbutton.x, theEvent->xbutton.y);
+ MyMouseButtonSet(trueblnr);
+ }
+ break;
+ case ButtonRelease:
+ /* any mouse button, we don't care which */
+ if (theEvent->xbutton.window != my_main_wind) {
+ WriteExtraErr(
+ "Got ButtonRelease for some other window");
+ } else {
+ MousePositionNotify(
+ theEvent->xbutton.x, theEvent->xbutton.y);
+ MyMouseButtonSet(falseblnr);
+ }
+ break;
+#if UseMotionEvents
+ case MotionNotify:
+ if (theEvent->xmotion.window != my_main_wind) {
+ WriteExtraErr("Got MotionNotify for some other window");
+ } else {
+ MousePositionNotify(
+ theEvent->xmotion.x, theEvent->xmotion.y);
+ }
+ break;
+ case EnterNotify:
+ if (theEvent->xcrossing.window != my_main_wind) {
+ WriteExtraErr("Got EnterNotify for some other window");
+ } else {
+#if MyDbgEvents
+ dbglog_writeln("- event - EnterNotify");
+#endif
+
+ CaughtMouse = trueblnr;
+ MousePositionNotify(
+ theEvent->xcrossing.x, theEvent->xcrossing.y);
+ }
+ break;
+ case LeaveNotify:
+ if (theEvent->xcrossing.window != my_main_wind) {
+ WriteExtraErr("Got LeaveNotify for some other window");
+ } else {
+#if MyDbgEvents
+ dbglog_writeln("- event - LeaveNotify");
+#endif
+
+ MousePositionNotify(
+ theEvent->xcrossing.x, theEvent->xcrossing.y);
+ CaughtMouse = falseblnr;
+ }
+ break;
+#endif
+ case Expose:
+ if (theEvent->xexpose.window != my_main_wind) {
+ WriteExtraErr(
+ "Got SelectionRequest for some other window");
+ } else {
+ int x0 = theEvent->xexpose.x;
+ int y0 = theEvent->xexpose.y;
+ int x1 = x0 + theEvent->xexpose.width;
+ int y1 = y0 + theEvent->xexpose.height;
+
+#if 0 && MyDbgEvents
+ dbglog_writeln("- event - Expose");
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ x0 -= hOffset;
+ y0 -= vOffset;
+ x1 -= hOffset;
+ y1 -= vOffset;
+ }
+#endif
+
+#if EnableMagnify
+ if (UseMagnify) {
+ x0 /= MyWindowScale;
+ y0 /= MyWindowScale;
+ x1 = (x1 + (MyWindowScale - 1)) / MyWindowScale;
+ y1 = (y1 + (MyWindowScale - 1)) / MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ x0 += ViewHStart;
+ y0 += ViewVStart;
+ x1 += ViewHStart;
+ y1 += ViewVStart;
+ }
+#endif
+
+ if (x0 < 0) {
+ x0 = 0;
+ }
+ if (x1 > vMacScreenWidth) {
+ x1 = vMacScreenWidth;
+ }
+ if (y0 < 0) {
+ y0 = 0;
+ }
+ if (y1 > vMacScreenHeight) {
+ y1 = vMacScreenHeight;
+ }
+ if ((x0 < x1) && (y0 < y1)) {
+ HaveChangedScreenBuff(y0, x0, y1, x1);
+ }
+
+ NeedFinishOpen1 = falseblnr;
+ }
+ break;
+#if IncludeHostTextClipExchange
+ case SelectionRequest:
+ if (theEvent->xselectionrequest.owner != my_main_wind) {
+ WriteExtraErr(
+ "Got SelectionRequest for some other window");
+ } else {
+ XEvent xevent;
+ blnr RequestFilled = falseblnr;
+
+#if MyDbgEvents
+ dbglog_writeln("- event - SelectionRequest");
+ WriteDbgAtom("selection",
+ theEvent->xselectionrequest.selection);
+ WriteDbgAtom("target",
+ theEvent->xselectionrequest.target);
+ WriteDbgAtom("property",
+ theEvent->xselectionrequest.property);
+#endif
+
+ if (theEvent->xselectionrequest.selection ==
+ MyXA_CLIPBOARD)
+ {
+ RequestFilled =
+ HandleSelectionRequestClipboard(theEvent);
+ }
+
+
+ memset(&xevent, 0, sizeof(xevent));
+ xevent.xselection.type = SelectionNotify;
+ xevent.xselection.display = x_display;
+ xevent.xselection.requestor =
+ theEvent->xselectionrequest.requestor;
+ xevent.xselection.selection =
+ theEvent->xselectionrequest.selection;
+ xevent.xselection.target =
+ theEvent->xselectionrequest.target;
+ xevent.xselection.property = (! RequestFilled) ? None
+ : theEvent->xselectionrequest.property ;
+ xevent.xselection.time =
+ theEvent->xselectionrequest.time;
+
+ if (0 == XSendEvent(x_display,
+ xevent.xselection.requestor, False, 0, &xevent))
+ {
+ WriteExtraErr(
+ "XSendEvent failed in SelectionRequest");
+ }
+ }
+ break;
+ case SelectionClear:
+ if (theEvent->xselectionclear.window != my_main_wind) {
+ WriteExtraErr(
+ "Got SelectionClear for some other window");
+ } else {
+#if MyDbgEvents
+ dbglog_writeln("- event - SelectionClear");
+ WriteDbgAtom("selection",
+ theEvent->xselectionclear.selection);
+#endif
+
+ if (theEvent->xselectionclear.selection ==
+ MyXA_CLIPBOARD)
+ {
+ FreeMyClipBuffer();
+ }
+ }
+ break;
+#endif
+#if EnableDragDrop
+ case SelectionNotify:
+ if (theEvent->xselection.requestor != my_main_wind) {
+ WriteExtraErr(
+ "Got SelectionNotify for some other window");
+ } else {
+#if MyDbgEvents
+ dbglog_writeln("- event - SelectionNotify");
+ WriteDbgAtom("selection",
+ theEvent->xselection.selection);
+ WriteDbgAtom("target", theEvent->xselection.target);
+ WriteDbgAtom("property", theEvent->xselection.property);
+#endif
+
+ if (theEvent->xselection.selection == MyXA_DndSelection)
+ {
+ HandleSelectionNotifyDnd(theEvent);
+ } else {
+ WriteExtraErr(
+ "Got Unknown selection in SelectionNotify");
+ }
+ }
+ break;
+#endif
+ case ClientMessage:
+ if (theEvent->xclient.window != my_main_wind) {
+ WriteExtraErr(
+ "Got ClientMessage for some other window");
+ } else {
+#if MyDbgEvents
+ dbglog_writeln("- event - ClientMessage");
+ WriteDbgAtom("message_type",
+ theEvent->xclient.message_type);
+#endif
+
+#if EnableDragDrop
+ if (theEvent->xclient.message_type == MyXA_DndEnter) {
+ /* printf("Got XdndEnter\n"); */
+ } else if (theEvent->xclient.message_type ==
+ MyXA_DndLeave)
+ {
+ /* printf("Got XdndLeave\n"); */
+ } else if (theEvent->xclient.message_type ==
+ MyXA_DndPosition)
+ {
+ HandleClientMessageDndPosition(theEvent);
+ } else if (theEvent->xclient.message_type ==
+ MyXA_DndDrop)
+ {
+ HandleClientMessageDndDrop(theEvent);
+ } else
+#endif
+ {
+ if ((32 == theEvent->xclient.format) &&
+ (theEvent->xclient.data.l[0] == MyXA_DeleteW))
+ {
+ /*
+ I would think that should test that
+ WM_PROTOCOLS == message_type
+ but none of the other programs I looked
+ at did.
+ */
+ RequestMacOff = trueblnr;
+ }
+ }
+ }
+ break;
+ case FocusIn:
+ if (theEvent->xfocus.window != my_main_wind) {
+ WriteExtraErr("Got FocusIn for some other window");
+ } else {
+#if MyDbgEvents
+ dbglog_writeln("- event - FocusIn");
+#endif
+
+ gTrueBackgroundFlag = falseblnr;
+#if UseMotionEvents
+ CheckMouseState();
+ /*
+ Doesn't help on x11 for OS X,
+ can't get new mouse position
+ in any fashion until mouse moves.
+ */
+#endif
+ }
+ break;
+ case FocusOut:
+ if (theEvent->xfocus.window != my_main_wind) {
+ WriteExtraErr("Got FocusOut for some other window");
+ } else {
+#if MyDbgEvents
+ dbglog_writeln("- event - FocusOut");
+#endif
+
+ gTrueBackgroundFlag = trueblnr;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/* --- main window creation and disposal --- */
+
+LOCALVAR int my_argc;
+LOCALVAR char **my_argv;
+
+LOCALVAR char *display_name = NULL;
+
+LOCALFUNC blnr Screen_Init(void)
+{
+ Window rootwin;
+ int screen;
+ Colormap Xcmap;
+ Visual *Xvisual;
+
+ x_display = XOpenDisplay(display_name);
+ if (NULL == x_display) {
+ fprintf(stderr, "Cannot connect to X server.\n");
+ return falseblnr;
+ }
+
+ screen = DefaultScreen(x_display);
+
+ rootwin = XRootWindow(x_display, screen);
+
+ Xcmap = DefaultColormap(x_display, screen);
+
+ Xvisual = DefaultVisual(x_display, screen);
+
+ LoadMyXA();
+
+ XParseColor(x_display, Xcmap, "#000000", &x_black);
+ if (! XAllocColor(x_display, Xcmap, &x_black)) {
+ WriteExtraErr("XParseColor black fails");
+ }
+ XParseColor(x_display, Xcmap, "#ffffff", &x_white);
+ if (! XAllocColor(x_display, Xcmap, &x_white)) {
+ WriteExtraErr("XParseColor white fails");
+ }
+
+ if (! CreateMyBlankCursor(rootwin)) {
+ return falseblnr;
+ }
+
+#if ! UseColorImage
+ my_image = XCreateImage(x_display, Xvisual, 1, XYBitmap, 0,
+ NULL /* (char *)image_Mem1 */,
+ vMacScreenWidth, vMacScreenHeight, 32,
+ vMacScreenMonoByteWidth);
+ if (NULL == my_image) {
+ fprintf(stderr, "XCreateImage failed.\n");
+ return falseblnr;
+ }
+
+#if 0
+ fprintf(stderr, "bitmap_bit_order = %d\n",
+ (int)my_image->bitmap_bit_order);
+ fprintf(stderr, "byte_order = %d\n", (int)my_image->byte_order);
+#endif
+
+ my_image->bitmap_bit_order = MSBFirst;
+ my_image->byte_order = MSBFirst;
+#endif
+
+#if UseColorImage
+ my_image = XCreateImage(x_display, Xvisual, 24, ZPixmap, 0,
+ NULL /* (char *)image_Mem1 */,
+ vMacScreenWidth, vMacScreenHeight, 32,
+ 4 * (ui5r)vMacScreenWidth);
+ if (NULL == my_image) {
+ fprintf(stderr, "XCreateImage Color failed.\n");
+ return falseblnr;
+ }
+
+#if 0
+ fprintf(stderr, "DefaultDepth = %d\n",
+ (int)DefaultDepth(x_display, screen));
+
+ fprintf(stderr, "MSBFirst = %d\n", (int)MSBFirst);
+ fprintf(stderr, "LSBFirst = %d\n", (int)LSBFirst);
+
+ fprintf(stderr, "bitmap_bit_order = %d\n",
+ (int)my_image->bitmap_bit_order);
+ fprintf(stderr, "byte_order = %d\n",
+ (int)my_image->byte_order);
+ fprintf(stderr, "bitmap_unit = %d\n",
+ (int)my_image->bitmap_unit);
+ fprintf(stderr, "bits_per_pixel = %d\n",
+ (int)my_image->bits_per_pixel);
+ fprintf(stderr, "red_mask = %d\n",
+ (int)my_image->red_mask);
+ fprintf(stderr, "green_mask = %d\n",
+ (int)my_image->green_mask);
+ fprintf(stderr, "blue_mask = %d\n",
+ (int)my_image->blue_mask);
+#endif
+
+#endif /* UseColorImage */
+
+#if EnableMagnify && (! UseColorImage)
+ my_Scaled_image = XCreateImage(x_display, Xvisual,
+ 1, XYBitmap, 0,
+ NULL /* (char *)image_Mem1 */,
+ vMacScreenWidth * MyWindowScale,
+ vMacScreenHeight * MyWindowScale,
+ 32, vMacScreenMonoByteWidth * MyWindowScale);
+ if (NULL == my_Scaled_image) {
+ fprintf(stderr, "XCreateImage failed.\n");
+ return falseblnr;
+ }
+
+ my_Scaled_image->bitmap_bit_order = MSBFirst;
+ my_Scaled_image->byte_order = MSBFirst;
+#endif
+
+#if EnableMagnify && UseColorImage
+ my_Scaled_image = XCreateImage(x_display, Xvisual,
+ 24, ZPixmap, 0,
+ NULL /* (char *)image_Mem1 */,
+ vMacScreenWidth * MyWindowScale,
+ vMacScreenHeight * MyWindowScale,
+ 32, 4 * (ui5r)vMacScreenWidth * MyWindowScale);
+ if (NULL == my_Scaled_image) {
+ fprintf(stderr, "XCreateImage Scaled failed.\n");
+ return falseblnr;
+ }
+#endif
+
+#if 0 != vMacScreenDepth
+ ColorModeWorks = trueblnr;
+#endif
+
+ DisableKeyRepeat();
+
+ return trueblnr;
+}
+
+LOCALPROC CloseMainWindow(void)
+{
+ if (my_gc != NULL) {
+ XFreeGC(x_display, my_gc);
+ my_gc = NULL;
+ }
+ if (my_main_wind) {
+ XDestroyWindow(x_display, my_main_wind);
+ my_main_wind = 0;
+ }
+}
+
+enum {
+ kMagStateNormal,
+#if EnableMagnify
+ kMagStateMagnifgy,
+#endif
+ kNumMagStates
+};
+
+#define kMagStateAuto kNumMagStates
+
+#if MayNotFullScreen
+LOCALVAR int CurWinIndx;
+LOCALVAR blnr HavePositionWins[kNumMagStates];
+LOCALVAR int WinPositionWinsH[kNumMagStates];
+LOCALVAR int WinPositionWinsV[kNumMagStates];
+#endif
+
+#if EnableRecreateW
+LOCALPROC ZapMyWState(void)
+{
+ my_main_wind = 0;
+ my_gc = NULL;
+}
+#endif
+
+LOCALFUNC blnr CreateMainWindow(void)
+{
+ Window rootwin;
+ int screen;
+ int xr;
+ int yr;
+ unsigned int dr;
+ unsigned int wr;
+ unsigned int hr;
+ unsigned int bwr;
+ Window rr;
+ int leftPos;
+ int topPos;
+#if MayNotFullScreen
+ int WinIndx;
+#endif
+#if EnableDragDrop
+ long int xdnd_version = 5;
+#endif
+ int NewWindowHeight = vMacScreenHeight;
+ int NewWindowWidth = vMacScreenWidth;
+
+ /* Get connection to X Server */
+ screen = DefaultScreen(x_display);
+
+ rootwin = XRootWindow(x_display, screen);
+
+ XGetGeometry(x_display, rootwin,
+ &rr, &xr, &yr, &wr, &hr, &bwr, &dr);
+
+#if EnableMagnify
+ if (UseMagnify) {
+ NewWindowHeight *= MyWindowScale;
+ NewWindowWidth *= MyWindowScale;
+ }
+#endif
+
+ if (wr > NewWindowWidth) {
+ leftPos = (wr - NewWindowWidth) / 2;
+ } else {
+ leftPos = 0;
+ }
+ if (hr > NewWindowHeight) {
+ topPos = (hr - NewWindowHeight) / 2;
+ } else {
+ topPos = 0;
+ }
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ ViewHSize = wr;
+ ViewVSize = hr;
+#if EnableMagnify
+ if (UseMagnify) {
+ ViewHSize /= MyWindowScale;
+ ViewVSize /= MyWindowScale;
+ }
+#endif
+ if (ViewHSize >= vMacScreenWidth) {
+ ViewHStart = 0;
+ ViewHSize = vMacScreenWidth;
+ } else {
+ ViewHSize &= ~ 1;
+ }
+ if (ViewVSize >= vMacScreenHeight) {
+ ViewVStart = 0;
+ ViewVSize = vMacScreenHeight;
+ } else {
+ ViewVSize &= ~ 1;
+ }
+ }
+#endif
+
+#if VarFullScreen
+ if (! UseFullScreen)
+#endif
+#if MayNotFullScreen
+ {
+#if EnableMagnify
+ if (UseMagnify) {
+ WinIndx = kMagStateMagnifgy;
+ } else
+#endif
+ {
+ WinIndx = kMagStateNormal;
+ }
+
+ if (! HavePositionWins[WinIndx]) {
+ WinPositionWinsH[WinIndx] = leftPos;
+ WinPositionWinsV[WinIndx] = topPos;
+ HavePositionWins[WinIndx] = trueblnr;
+ } else {
+ leftPos = WinPositionWinsH[WinIndx];
+ topPos = WinPositionWinsV[WinIndx];
+ }
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ XSetWindowAttributes xattr;
+ xattr.override_redirect = True;
+ xattr.background_pixel = x_black.pixel;
+ xattr.border_pixel = x_white.pixel;
+
+ my_main_wind = XCreateWindow(x_display, rr,
+ 0, 0, wr, hr, 0,
+ CopyFromParent, /* depth */
+ InputOutput, /* class */
+ CopyFromParent, /* visual */
+ CWOverrideRedirect | CWBackPixel | CWBorderPixel,
+ /* valuemask */
+ &xattr /* attributes */);
+ }
+#endif
+#if VarFullScreen
+ else
+#endif
+#if MayNotFullScreen
+ {
+ my_main_wind = XCreateSimpleWindow(x_display, rootwin,
+ leftPos,
+ topPos,
+ NewWindowWidth, NewWindowHeight, 4,
+ x_white.pixel,
+ x_black.pixel);
+ }
+#endif
+
+ if (! my_main_wind) {
+ WriteExtraErr("XCreateSimpleWindow failed.");
+ return falseblnr;
+ } else {
+ char *win_name =
+ (NULL != n_arg) ? n_arg : (
+#if CanGetAppPath
+ (NULL != app_name) ? app_name :
+#endif
+ kStrAppName);
+ XSelectInput(x_display, my_main_wind,
+ ExposureMask | KeyPressMask | KeyReleaseMask
+ | ButtonPressMask | ButtonReleaseMask
+#if UseMotionEvents
+ | PointerMotionMask | EnterWindowMask | LeaveWindowMask
+#endif
+ | FocusChangeMask);
+
+ XStoreName(x_display, my_main_wind, win_name);
+ XSetIconName(x_display, my_main_wind, win_name);
+
+ {
+ XClassHint *hints = XAllocClassHint();
+ if (hints) {
+ hints->res_name = "minivmac";
+ hints->res_class = "minivmac";
+ XSetClassHint(x_display, my_main_wind, hints);
+ XFree(hints);
+ }
+ }
+
+ {
+ XWMHints *hints = XAllocWMHints();
+ if (hints) {
+ hints->input = True;
+ hints->initial_state = NormalState;
+ hints->flags = InputHint | StateHint;
+ XSetWMHints(x_display, my_main_wind, hints);
+ XFree(hints);
+ }
+
+ }
+
+ XSetCommand(x_display, my_main_wind, my_argv, my_argc);
+
+ /* let us handle a click on the close box */
+ XSetWMProtocols(x_display, my_main_wind, &MyXA_DeleteW, 1);
+
+#if EnableDragDrop
+ XChangeProperty (x_display, my_main_wind, MyXA_DndAware,
+ XA_ATOM, 32, PropModeReplace,
+ (unsigned char *) &xdnd_version, 1);
+#endif
+
+ my_gc = XCreateGC(x_display, my_main_wind, 0, NULL);
+ if (NULL == my_gc) {
+ WriteExtraErr("XCreateGC failed.");
+ return falseblnr;
+ }
+ XSetState(x_display, my_gc, x_black.pixel, x_white.pixel,
+ GXcopy, AllPlanes);
+
+#if VarFullScreen
+ if (! UseFullScreen)
+#endif
+#if MayNotFullScreen
+ {
+ XSizeHints *hints = XAllocSizeHints();
+ if (hints) {
+ hints->min_width = NewWindowWidth;
+ hints->max_width = NewWindowWidth;
+ hints->min_height = NewWindowHeight;
+ hints->max_height = NewWindowHeight;
+
+ /*
+ Try again to say where the window ought to go.
+ I've seen this described as obsolete, but it
+ seems to work on all x implementations tried
+ so far, and nothing else does.
+ */
+ hints->x = leftPos;
+ hints->y = topPos;
+ hints->width = NewWindowWidth;
+ hints->height = NewWindowHeight;
+
+ hints->flags = PMinSize | PMaxSize | PPosition | PSize;
+ XSetWMNormalHints(x_display, my_main_wind, hints);
+ XFree(hints);
+ }
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ hOffset = leftPos;
+ vOffset = topPos;
+ }
+#endif
+
+ DisconnectKeyCodes3();
+ /* since will lose keystrokes to old window */
+
+#if MayNotFullScreen
+ CurWinIndx = WinIndx;
+#endif
+
+ XMapRaised(x_display, my_main_wind);
+
+#if 0
+ XSync(x_display, 0);
+#endif
+
+#if 0
+ /*
+ This helps in Red Hat 9 to get the new window
+ activated, and I've seen other programs
+ do similar things.
+ */
+ /*
+ In current scheme, haven't closed old window
+ yet. If old window full screen, never receive
+ expose event for new one.
+ */
+ {
+ XEvent event;
+
+ do {
+ XNextEvent(x_display, &event);
+ HandleTheEvent(&event);
+ } while (! ((Expose == event.type)
+ && (event.xexpose.window == my_main_wind)));
+ }
+#endif
+
+ NeedFinishOpen1 = trueblnr;
+ NeedFinishOpen2 = trueblnr;
+
+ return trueblnr;
+ }
+}
+
+#if MayFullScreen
+LOCALVAR blnr GrabMachine = falseblnr;
+#endif
+
+#if MayFullScreen
+LOCALPROC GrabTheMachine(void)
+{
+#if EnableFSMouseMotion
+ StartSaveMouseMotion();
+#endif
+#if GrabKeysFullScreen
+ MyGrabKeyboard();
+#endif
+}
+#endif
+
+#if MayFullScreen
+LOCALPROC UngrabMachine(void)
+{
+#if EnableFSMouseMotion
+ StopSaveMouseMotion();
+#endif
+#if GrabKeysFullScreen
+ MyUnGrabKeyboard();
+#endif
+}
+#endif
+
+#if EnableRecreateW
+struct MyWState {
+ Window f_my_main_wind;
+ GC f_my_gc;
+#if MayFullScreen
+ short f_hOffset;
+ short f_vOffset;
+ ui4r f_ViewHSize;
+ ui4r f_ViewVSize;
+ ui4r f_ViewHStart;
+ ui4r f_ViewVStart;
+#endif
+#if VarFullScreen
+ blnr f_UseFullScreen;
+#endif
+#if EnableMagnify
+ blnr f_UseMagnify;
+#endif
+};
+typedef struct MyWState MyWState;
+#endif
+
+#if EnableRecreateW
+LOCALPROC GetMyWState(MyWState *r)
+{
+ r->f_my_main_wind = my_main_wind;
+ r->f_my_gc = my_gc;
+#if MayFullScreen
+ r->f_hOffset = hOffset;
+ r->f_vOffset = vOffset;
+ r->f_ViewHSize = ViewHSize;
+ r->f_ViewVSize = ViewVSize;
+ r->f_ViewHStart = ViewHStart;
+ r->f_ViewVStart = ViewVStart;
+#endif
+#if VarFullScreen
+ r->f_UseFullScreen = UseFullScreen;
+#endif
+#if EnableMagnify
+ r->f_UseMagnify = UseMagnify;
+#endif
+}
+#endif
+
+#if EnableRecreateW
+LOCALPROC SetMyWState(MyWState *r)
+{
+ my_main_wind = r->f_my_main_wind;
+ my_gc = r->f_my_gc;
+#if MayFullScreen
+ hOffset = r->f_hOffset;
+ vOffset = r->f_vOffset;
+ ViewHSize = r->f_ViewHSize;
+ ViewVSize = r->f_ViewVSize;
+ ViewHStart = r->f_ViewHStart;
+ ViewVStart = r->f_ViewVStart;
+#endif
+#if VarFullScreen
+ UseFullScreen = r->f_UseFullScreen;
+#endif
+#if EnableMagnify
+ UseMagnify = r->f_UseMagnify;
+#endif
+}
+#endif
+
+#if EnableRecreateW
+LOCALVAR blnr WantRestoreCursPos = falseblnr;
+LOCALVAR ui4b RestoreMouseH;
+LOCALVAR ui4b RestoreMouseV;
+#endif
+
+#if EnableRecreateW
+LOCALFUNC blnr ReCreateMainWindow(void)
+{
+ MyWState old_state;
+ MyWState new_state;
+#if IncludeHostTextClipExchange
+ blnr OwnClipboard = falseblnr;
+#endif
+
+ if (HaveCursorHidden) {
+ WantRestoreCursPos = trueblnr;
+ RestoreMouseH = CurMouseH;
+ RestoreMouseV = CurMouseV;
+ }
+
+ ForceShowCursor(); /* hide/show cursor api is per window */
+
+#if MayNotFullScreen
+#if VarFullScreen
+ if (! UseFullScreen)
+#endif
+ if (my_main_wind)
+ if (! NeedFinishOpen2)
+ {
+ /* save old position */
+ int xr;
+ int yr;
+ unsigned int dr;
+ unsigned int wr;
+ unsigned int hr;
+ unsigned int bwr;
+ Window rr;
+ Window rr2;
+
+ /* Get connection to X Server */
+ int screen = DefaultScreen(x_display);
+
+ Window rootwin = XRootWindow(x_display, screen);
+
+ XGetGeometry(x_display, rootwin,
+ &rr, &xr, &yr, &wr, &hr, &bwr, &dr);
+
+ /*
+ Couldn't reliably find out where window
+ is now, due to what seem to be some
+ broken X implementations, and so instead
+ track how far window has moved.
+ */
+ XSync(x_display, 0);
+ if (XTranslateCoordinates(x_display, my_main_wind, rootwin,
+ 0, 0, &xr, &yr, &rr2))
+ {
+ int newposh =
+ WinPositionWinsH[CurWinIndx] + (xr - SavedTransH);
+ int newposv =
+ WinPositionWinsV[CurWinIndx] + (yr - SavedTransV);
+ if ((newposv > 0) && (newposv < hr) && (newposh < wr)) {
+ WinPositionWinsH[CurWinIndx] = newposh;
+ WinPositionWinsV[CurWinIndx] = newposv;
+ SavedTransH = xr;
+ SavedTransV = yr;
+ }
+ }
+ }
+#endif
+
+#if MayFullScreen
+ if (GrabMachine) {
+ GrabMachine = falseblnr;
+ UngrabMachine();
+ }
+#endif
+
+ GetMyWState(&old_state);
+ ZapMyWState();
+
+#if EnableMagnify
+ UseMagnify = WantMagnify;
+#endif
+#if VarFullScreen
+ UseFullScreen = WantFullScreen;
+#endif
+
+ ColorTransValid = falseblnr;
+
+ if (! CreateMainWindow()) {
+ CloseMainWindow();
+ SetMyWState(&old_state);
+
+ /* avoid retry */
+#if VarFullScreen
+ WantFullScreen = UseFullScreen;
+#endif
+#if EnableMagnify
+ WantMagnify = UseMagnify;
+#endif
+
+ return falseblnr;
+ } else {
+ GetMyWState(&new_state);
+ SetMyWState(&old_state);
+
+#if IncludeHostTextClipExchange
+ if (my_main_wind) {
+ if (XGetSelectionOwner(x_display, MyXA_CLIPBOARD) ==
+ my_main_wind)
+ {
+ OwnClipboard = trueblnr;
+ }
+ }
+#endif
+
+ CloseMainWindow();
+
+ SetMyWState(&new_state);
+
+#if IncludeHostTextClipExchange
+ if (OwnClipboard) {
+ XSetSelectionOwner(x_display, MyXA_CLIPBOARD,
+ my_main_wind, CurrentTime);
+ }
+#endif
+ }
+
+ return trueblnr;
+}
+#endif
+
+#if VarFullScreen && EnableMagnify
+enum {
+ kWinStateWindowed,
+#if EnableMagnify
+ kWinStateFullScreen,
+#endif
+ kNumWinStates
+};
+#endif
+
+#if VarFullScreen && EnableMagnify
+LOCALVAR int WinMagStates[kNumWinStates];
+#endif
+
+LOCALPROC ZapWinStateVars(void)
+{
+#if MayNotFullScreen
+ {
+ int i;
+
+ for (i = 0; i < kNumMagStates; ++i) {
+ HavePositionWins[i] = falseblnr;
+ }
+ }
+#endif
+#if VarFullScreen && EnableMagnify
+ {
+ int i;
+
+ for (i = 0; i < kNumWinStates; ++i) {
+ WinMagStates[i] = kMagStateAuto;
+ }
+ }
+#endif
+}
+
+#if VarFullScreen
+LOCALPROC ToggleWantFullScreen(void)
+{
+ WantFullScreen = ! WantFullScreen;
+
+#if EnableMagnify
+ {
+ int OldWinState =
+ UseFullScreen ? kWinStateFullScreen : kWinStateWindowed;
+ int OldMagState =
+ UseMagnify ? kMagStateMagnifgy : kMagStateNormal;
+ int NewWinState =
+ WantFullScreen ? kWinStateFullScreen : kWinStateWindowed;
+ int NewMagState = WinMagStates[NewWinState];
+
+ WinMagStates[OldWinState] = OldMagState;
+ if (kMagStateAuto != NewMagState) {
+ WantMagnify = (kMagStateMagnifgy == NewMagState);
+ } else {
+ WantMagnify = falseblnr;
+ if (WantFullScreen) {
+ Window rootwin;
+ int xr;
+ int yr;
+ unsigned int dr;
+ unsigned int wr;
+ unsigned int hr;
+ unsigned int bwr;
+ Window rr;
+
+ rootwin =
+ XRootWindow(x_display, DefaultScreen(x_display));
+ XGetGeometry(x_display, rootwin,
+ &rr, &xr, &yr, &wr, &hr, &bwr, &dr);
+ if ((wr >= vMacScreenWidth * MyWindowScale)
+ && (hr >= vMacScreenHeight * MyWindowScale)
+ )
+ {
+ WantMagnify = trueblnr;
+ }
+ }
+ }
+ }
+#endif
+}
+#endif
+
+/* --- SavedTasks --- */
+
+LOCALPROC LeaveBackground(void)
+{
+ ReconnectKeyCodes3();
+ DisableKeyRepeat();
+}
+
+LOCALPROC EnterBackground(void)
+{
+ RestoreKeyRepeat();
+ DisconnectKeyCodes3();
+
+ ForceShowCursor();
+}
+
+LOCALPROC LeaveSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Start();
+#endif
+
+ StartUpTimeAdjust();
+}
+
+LOCALPROC EnterSpeedStopped(void)
+{
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+}
+
+LOCALPROC CheckForSavedTasks(void)
+{
+ if (MyEvtQNeedRecover) {
+ MyEvtQNeedRecover = falseblnr;
+
+ /* attempt cleanup, MyEvtQNeedRecover may get set again */
+ MyEvtQTryRecoverFromFull();
+ }
+
+ if (NeedFinishOpen2 && ! NeedFinishOpen1) {
+ NeedFinishOpen2 = falseblnr;
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ XSetInputFocus(x_display, my_main_wind,
+ RevertToPointerRoot, CurrentTime);
+ }
+#endif
+#if VarFullScreen
+ else
+#endif
+#if MayNotFullScreen
+ {
+ Window rr;
+ int screen = DefaultScreen(x_display);
+ Window rootwin = XRootWindow(x_display, screen);
+#if 0
+ /*
+ This doesn't work right in Red Hat 6, and may not
+ be needed anymore, now that using PPosition hint.
+ */
+ XMoveWindow(x_display, my_main_wind,
+ leftPos, topPos);
+ /*
+ Needed after XMapRaised, because some window
+ managers will apparently ignore where the
+ window was asked to be put.
+ */
+#endif
+
+ XSync(x_display, 0);
+ /*
+ apparently, XTranslateCoordinates can be inaccurate
+ without this
+ */
+ XTranslateCoordinates(x_display, my_main_wind, rootwin,
+ 0, 0, &SavedTransH, &SavedTransV, &rr);
+ }
+#endif
+
+#if EnableRecreateW
+ if (WantRestoreCursPos) {
+#if EnableFSMouseMotion
+ if (! HaveMouseMotion)
+#endif
+ {
+ (void) MyMoveMouse(RestoreMouseH, RestoreMouseV);
+ WantCursorHidden = trueblnr;
+ }
+ WantRestoreCursPos = falseblnr;
+ }
+#endif
+ }
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMouseConstrain();
+ }
+#endif
+
+ if (RequestMacOff) {
+ RequestMacOff = falseblnr;
+ if (AnyDiskInserted()) {
+ MacMsgOverride(kStrQuitWarningTitle,
+ kStrQuitWarningMessage);
+ } else {
+ ForceMacOff = trueblnr;
+ }
+ }
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (gTrueBackgroundFlag != gBackgroundFlag) {
+ gBackgroundFlag = gTrueBackgroundFlag;
+ if (gTrueBackgroundFlag) {
+ EnterBackground();
+ } else {
+ LeaveBackground();
+ }
+ }
+
+ if (CurSpeedStopped != (SpeedStopped ||
+ (gBackgroundFlag && ! RunInBackground
+#if EnableAutoSlow && 0
+ && (QuietSubTicks >= 4092)
+#endif
+ )))
+ {
+ CurSpeedStopped = ! CurSpeedStopped;
+ if (CurSpeedStopped) {
+ EnterSpeedStopped();
+ } else {
+ LeaveSpeedStopped();
+ }
+ }
+
+#if MayFullScreen
+ if (gTrueBackgroundFlag
+#if VarFullScreen
+ && WantFullScreen
+#endif
+ )
+ {
+ /*
+ Since often get here on Ubuntu Linux 5.10
+ running on a slow machine (emulated) when
+ attempt to enter full screen, don't abort
+ full screen, but try to fix it.
+ */
+#if 0
+ ToggleWantFullScreen();
+#else
+ XRaiseWindow(x_display, my_main_wind);
+ XSetInputFocus(x_display, my_main_wind,
+ RevertToPointerRoot, CurrentTime);
+#endif
+ }
+#endif
+
+#if EnableRecreateW
+ if (0
+#if EnableMagnify
+ || (UseMagnify != WantMagnify)
+#endif
+#if VarFullScreen
+ || (UseFullScreen != WantFullScreen)
+#endif
+ )
+ {
+ (void) ReCreateMainWindow();
+ }
+#endif
+
+
+#if MayFullScreen
+ if (GrabMachine != (
+#if VarFullScreen
+ UseFullScreen &&
+#endif
+ ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ GrabMachine = ! GrabMachine;
+ if (GrabMachine) {
+ GrabTheMachine();
+ } else {
+ UngrabMachine();
+ }
+ }
+#endif
+
+#if IncludeSonyNew
+ if (vSonyNewDiskWanted) {
+#if IncludeSonyNameNew
+ if (vSonyNewDiskName != NotAPbuf) {
+ ui3p NewDiskNameDat;
+ if (MacRomanTextToNativePtr(vSonyNewDiskName, trueblnr,
+ &NewDiskNameDat))
+ {
+ MakeNewDisk(vSonyNewDiskSize, (char *)NewDiskNameDat);
+ free(NewDiskNameDat);
+ }
+ PbufDispose(vSonyNewDiskName);
+ vSonyNewDiskName = NotAPbuf;
+ } else
+#endif
+ {
+ MakeNewDiskAtDefault(vSonyNewDiskSize);
+ }
+ vSonyNewDiskWanted = falseblnr;
+ /* must be done after may have gotten disk */
+ }
+#endif
+
+ if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) {
+ MacMsgDisplayOn();
+ }
+
+ if (NeedWholeScreenDraw) {
+ NeedWholeScreenDraw = falseblnr;
+ ScreenChangedAll();
+ }
+
+#if NeedRequestIthDisk
+ if (0 != RequestIthDisk) {
+ Sony_InsertIth(RequestIthDisk);
+ RequestIthDisk = 0;
+ }
+#endif
+
+ if (HaveCursorHidden != (WantCursorHidden
+ && ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ HaveCursorHidden = ! HaveCursorHidden;
+ if (HaveCursorHidden) {
+ XDefineCursor(x_display, my_main_wind, blankCursor);
+ } else {
+ XUndefineCursor(x_display, my_main_wind);
+ }
+ }
+}
+
+/* --- command line parsing --- */
+
+LOCALFUNC blnr ScanCommandLine(void)
+{
+ char *pa;
+ int i = 1;
+
+label_retry:
+ if (i < my_argc) {
+ pa = my_argv[i++];
+ if ('-' == pa[0]) {
+ if ((0 == strcmp(pa, "--display"))
+ || (0 == strcmp(pa, "-display")))
+ {
+ if (i < my_argc) {
+ display_name = my_argv[i++];
+ goto label_retry;
+ }
+ } else
+ if ((0 == strcmp(pa, "--rom"))
+ || (0 == strcmp(pa, "-r")))
+ {
+ if (i < my_argc) {
+ rom_path = my_argv[i++];
+ goto label_retry;
+ }
+ } else
+ if (0 == strcmp(pa, "-n"))
+ {
+ if (i < my_argc) {
+ n_arg = my_argv[i++];
+ goto label_retry;
+ }
+ } else
+ if (0 == strcmp(pa, "-d"))
+ {
+ if (i < my_argc) {
+ d_arg = my_argv[i++];
+ goto label_retry;
+ }
+ } else
+#ifndef UsingAlsa
+#define UsingAlsa 0
+#endif
+
+#if UsingAlsa
+ if ((0 == strcmp(pa, "--alsadev"))
+ || (0 == strcmp(pa, "-alsadev")))
+ {
+ if (i < my_argc) {
+ alsadev_name = my_argv[i++];
+ goto label_retry;
+ }
+ } else
+#endif
+#if 0
+ if (0 == strcmp(pa, "-l")) {
+ SpeedValue = 0;
+ goto label_retry;
+ } else
+#endif
+ {
+ MacMsg(kStrBadArgTitle, kStrBadArgMessage, falseblnr);
+ }
+ } else {
+ (void) Sony_Insert1(pa, falseblnr);
+ goto label_retry;
+ }
+ }
+
+ return trueblnr;
+}
+
+/* --- main program flow --- */
+
+GLOBALOSGLUPROC DoneWithDrawingForTick(void)
+{
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ AutoScrollScreen();
+ }
+#endif
+ MyDrawChangesAndClear();
+ XFlush(x_display);
+}
+
+GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void)
+{
+ UpdateTrueEmulatedTime();
+ return TrueEmulatedTime == OnTrueTime;
+}
+
+LOCALPROC WaitForTheNextEvent(void)
+{
+ XEvent event;
+
+ XNextEvent(x_display, &event);
+ HandleTheEvent(&event);
+}
+
+LOCALPROC CheckForSystemEvents(void)
+{
+ int i = 10;
+
+ while ((XEventsQueued(x_display, QueuedAfterReading) > 0)
+ && (--i >= 0))
+ {
+ WaitForTheNextEvent();
+ }
+}
+
+GLOBALOSGLUPROC WaitForNextTick(void)
+{
+label_retry:
+ CheckForSystemEvents();
+ CheckForSavedTasks();
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (CurSpeedStopped) {
+ DoneWithDrawingForTick();
+ WaitForTheNextEvent();
+ goto label_retry;
+ }
+
+ if (ExtraTimeNotOver()) {
+ struct timespec rqt;
+ struct timespec rmt;
+
+ si5b TimeDiff = GetTimeDiff();
+ if (TimeDiff < 0) {
+ rqt.tv_sec = 0;
+ rqt.tv_nsec = (- TimeDiff) * 1000;
+ (void) nanosleep(&rqt, &rmt);
+ }
+ goto label_retry;
+ }
+
+ if (CheckDateTime()) {
+#if MySoundEnabled
+ MySound_SecondNotify();
+#endif
+#if EnableDemoMsg
+ DemoModeSecondNotify();
+#endif
+ }
+
+ if ((! gBackgroundFlag)
+#if UseMotionEvents
+ && (! CaughtMouse)
+#endif
+ )
+ {
+ CheckMouseState();
+ }
+
+ OnTrueTime = TrueEmulatedTime;
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("WaitForNextTick, OnTrueTime", OnTrueTime);
+#endif
+}
+
+/* --- platform independent code can be thought of as going here --- */
+
+#include "PROGMAIN.h"
+
+LOCALPROC ZapOSGLUVars(void)
+{
+ InitDrives();
+ ZapWinStateVars();
+}
+
+LOCALPROC ReserveAllocAll(void)
+{
+#if dbglog_HAVE
+ dbglog_ReserveAlloc();
+#endif
+ ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr);
+
+ ReserveAllocOneBlock(&screencomparebuff,
+ vMacScreenNumBytes, 5, trueblnr);
+#if UseControlKeys
+ ReserveAllocOneBlock(&CntrlDisplayBuff,
+ vMacScreenNumBytes, 5, falseblnr);
+#endif
+#if WantScalingBuff
+ ReserveAllocOneBlock(&ScalingBuff,
+ ScalingBuffsz, 5, falseblnr);
+#endif
+#if WantScalingTabl
+ ReserveAllocOneBlock(&ScalingTabl,
+ ScalingTablsz, 5, falseblnr);
+#endif
+
+#if MySoundEnabled
+ ReserveAllocOneBlock((ui3p *)&TheSoundBuffer,
+ dbhBufferSize, 5, falseblnr);
+#endif
+
+ EmulationReserveAlloc();
+}
+
+LOCALFUNC blnr AllocMyMemory(void)
+{
+ uimr n;
+ blnr IsOk = falseblnr;
+
+ ReserveAllocOffset = 0;
+ ReserveAllocBigBlock = nullpr;
+ ReserveAllocAll();
+ n = ReserveAllocOffset;
+ ReserveAllocBigBlock = (ui3p)calloc(1, n);
+ if (NULL == ReserveAllocBigBlock) {
+ MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr);
+ } else {
+ ReserveAllocOffset = 0;
+ ReserveAllocAll();
+ if (n != ReserveAllocOffset) {
+ /* oops, program error */
+ } else {
+ IsOk = trueblnr;
+ }
+ }
+
+ return IsOk;
+}
+
+LOCALPROC UnallocMyMemory(void)
+{
+ if (nullpr != ReserveAllocBigBlock) {
+ free((char *)ReserveAllocBigBlock);
+ }
+}
+
+#if HaveAppPathLink
+LOCALFUNC blnr ReadLink_Alloc(char *path, char **r)
+{
+ /*
+ This should work to find size:
+
+ struct stat r;
+
+ if (lstat(path, &r) != -1) {
+ r = r.st_size;
+ IsOk = trueblnr;
+ }
+
+ But observed to return 0 in Ubuntu 10.04 x86-64
+ */
+
+ char *s;
+ int sz;
+ char *p;
+ blnr IsOk = falseblnr;
+ size_t s_alloc = 256;
+
+label_retry:
+ s = (char *)malloc(s_alloc);
+ if (NULL == s) {
+ fprintf(stderr, "malloc failed.\n");
+ } else {
+ sz = readlink(path, s, s_alloc);
+ if ((sz < 0) || (sz >= s_alloc)) {
+ free(s);
+ if (sz == s_alloc) {
+ s_alloc <<= 1;
+ goto label_retry;
+ } else {
+ fprintf(stderr, "readlink failed.\n");
+ }
+ } else {
+ /* ok */
+ p = (char *)malloc(sz + 1);
+ if (NULL == p) {
+ fprintf(stderr, "malloc failed.\n");
+ } else {
+ (void) memcpy(p, s, sz);
+ p[sz] = 0;
+ *r = p;
+ IsOk = trueblnr;
+ }
+ free(s);
+ }
+ }
+
+ return IsOk;
+}
+#endif
+
+#if HaveSysctlPath
+LOCALFUNC blnr ReadKernProcPathname(char **r)
+{
+ size_t s_alloc;
+ char *s;
+ int mib[] = {
+ CTL_KERN,
+ KERN_PROC,
+ KERN_PROC_PATHNAME,
+ -1
+ };
+ blnr IsOk = falseblnr;
+
+ if (0 != sysctl(mib, sizeof(mib) / sizeof(int),
+ NULL, &s_alloc, NULL, 0))
+ {
+ fprintf(stderr, "sysctl failed.\n");
+ } else {
+ s = (char *)malloc(s_alloc);
+ if (NULL == s) {
+ fprintf(stderr, "malloc failed.\n");
+ } else {
+ if (0 != sysctl(mib, sizeof(mib) / sizeof(int),
+ s, &s_alloc, NULL, 0))
+ {
+ fprintf(stderr, "sysctl 2 failed.\n");
+ } else {
+ *r = s;
+ IsOk = trueblnr;
+ }
+ if (! IsOk) {
+ free(s);
+ }
+ }
+ }
+
+ return IsOk;
+}
+#endif
+
+#if CanGetAppPath
+LOCALFUNC blnr Path2ParentAndName(char *path,
+ char **parent, char **name)
+{
+ blnr IsOk = falseblnr;
+
+ char *t = strrchr(path, '/');
+ if (NULL == t) {
+ fprintf(stderr, "no directory.\n");
+ } else {
+ int par_sz = t - path;
+ char *par = (char *)malloc(par_sz + 1);
+ if (NULL == par) {
+ fprintf(stderr, "malloc failed.\n");
+ } else {
+ (void) memcpy(par, path, par_sz);
+ par[par_sz] = 0;
+ {
+ int s_sz = strlen(path);
+ int child_sz = s_sz - par_sz - 1;
+ char *child = (char *)malloc(child_sz + 1);
+ if (NULL == child) {
+ fprintf(stderr, "malloc failed.\n");
+ } else {
+ (void) memcpy(child, t + 1, child_sz);
+ child[child_sz] = 0;
+
+ *name = child;
+ IsOk = trueblnr;
+ /* free(child); */
+ }
+ }
+ if (! IsOk) {
+ free(par);
+ } else {
+ *parent = par;
+ }
+ }
+ }
+
+ return IsOk;
+}
+#endif
+
+#if CanGetAppPath
+LOCALFUNC blnr InitWhereAmI(void)
+{
+ char *s;
+
+ if (!
+#if HaveAppPathLink
+ ReadLink_Alloc(TheAppPathLink, &s)
+#endif
+#if HaveSysctlPath
+ ReadKernProcPathname(&s)
+#endif
+ )
+ {
+ fprintf(stderr, "InitWhereAmI fails.\n");
+ } else {
+ if (! Path2ParentAndName(s, &app_parent, &app_name)) {
+ fprintf(stderr, "Path2ParentAndName fails.\n");
+ } else {
+ /* ok */
+ /*
+ fprintf(stderr, "parent = %s.\n", app_parent);
+ fprintf(stderr, "name = %s.\n", app_name);
+ */
+ }
+
+ free(s);
+ }
+
+ return trueblnr; /* keep going regardless */
+}
+#endif
+
+#if CanGetAppPath
+LOCALPROC UninitWhereAmI(void)
+{
+ MyMayFree(app_parent);
+ MyMayFree(app_name);
+}
+#endif
+
+LOCALFUNC blnr InitOSGLU(void)
+{
+ if (AllocMyMemory())
+#if CanGetAppPath
+ if (InitWhereAmI())
+#endif
+#if dbglog_HAVE
+ if (dbglog_open())
+#endif
+ if (ScanCommandLine())
+ if (LoadMacRom())
+ if (LoadInitialImages())
+#if UseActvCode
+ if (ActvCodeInit())
+#endif
+ if (InitLocationDat())
+#if MySoundEnabled
+ if (MySound_Init())
+#endif
+ if (Screen_Init())
+ if (CreateMainWindow())
+ if (KC2MKCInit())
+ if (WaitForRom())
+ {
+ return trueblnr;
+ }
+ return falseblnr;
+}
+
+LOCALPROC UnInitOSGLU(void)
+{
+ if (MacMsgDisplayed) {
+ MacMsgDisplayOff();
+ }
+
+ RestoreKeyRepeat();
+#if MayFullScreen
+ UngrabMachine();
+#endif
+#if MySoundEnabled
+ MySound_Stop();
+#endif
+#if MySoundEnabled
+ MySound_UnInit();
+#endif
+#if IncludeHostTextClipExchange
+ FreeMyClipBuffer();
+#endif
+#if IncludePbufs
+ UnInitPbufs();
+#endif
+ UnInitDrives();
+
+ ForceShowCursor();
+ if (blankCursor != None) {
+ XFreeCursor(x_display, blankCursor);
+ }
+
+ if (my_image != NULL) {
+ XDestroyImage(my_image);
+ }
+#if EnableMagnify
+ if (my_Scaled_image != NULL) {
+ XDestroyImage(my_Scaled_image);
+ }
+#endif
+
+ CloseMainWindow();
+ if (x_display != NULL) {
+ XCloseDisplay(x_display);
+ }
+
+#if dbglog_HAVE
+ dbglog_close();
+#endif
+
+#if CanGetAppPath
+ UninitWhereAmI();
+#endif
+ UnallocMyMemory();
+
+ CheckSavedMacMsg();
+}
+
+int main(int argc, char **argv)
+{
+ my_argc = argc;
+ my_argv = argv;
+
+ ZapOSGLUVars();
+ if (InitOSGLU()) {
+ ProgramMain();
+ }
+ UnInitOSGLU();
+
+ return 0;
+}
--- /dev/null
+++ b/src/OSPLAN9.c
@@ -1,0 +1,1886 @@
+#include <u.h>
+#include <libc.h>
+#include <stdio.h>
+#include <draw.h>
+#include <mouse.h>
+#include <cursor.h>
+#include <keyboard.h>
+#include <thread.h>
+#include <plumb.h>
+#define Uint8 u8int
+#define Uint16 u16int
+#define Uint32 u32int
+#include "CNFGRAPI.h"
+#include "SYSDEPNS.h"
+#include "ENDIANAC.h"
+#include "MYOSGLUE.h"
+#include "STRCONST.h"
+
+GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount)
+{
+ memmove(destPtr, srcPtr, byteCount);
+}
+
+#define NeedCell2PlainAsciiMap 1
+#include "INTLCHAR.h"
+
+#if dbglog_HAVE
+
+#define dbglog_ToStdErr 0
+
+#if ! dbglog_ToStdErr
+LOCALVAR FILE *dbglog_File = NULL;
+#endif
+
+LOCALFUNC blnr dbglog_open0(void)
+{
+#if dbglog_ToStdErr
+ return trueblnr;
+#else
+ dbglog_File = fopen("dbglog.txt", "w");
+ return (NULL != dbglog_File);
+#endif
+}
+
+LOCALPROC dbglog_write0(char *s, uimr L)
+{
+#if dbglog_ToStdErr
+ (void) fwrite(s, 1, L, stderr);
+#else
+ if (dbglog_File != NULL) {
+ (void) fwrite(s, 1, L, dbglog_File);
+ }
+#endif
+}
+
+LOCALPROC dbglog_close0(void)
+{
+#if ! dbglog_ToStdErr
+ if (dbglog_File != NULL) {
+ fclose(dbglog_File);
+ dbglog_File = NULL;
+ }
+#endif
+}
+
+#endif
+
+/* --- information about the environment --- */
+
+#define WantColorTransValid 0
+
+#include "COMOSGLU.h"
+
+#include "PBUFSTDC.h"
+
+#include "CONTROLM.h"
+
+/* --- text translation --- */
+
+LOCALPROC NativeStrFromCStr(char *r, char *s)
+{
+ ui3b ps[ClStrMaxLength];
+ int i;
+ int L;
+
+ ClStrFromSubstCStr(&L, ps, s);
+
+ for (i = 0; i < L; ++i) {
+ r[i] = Cell2PlainAsciiMap[ps[i]];
+ }
+
+ r[L] = 0;
+}
+
+/* --- drives --- */
+
+#define NotAfileRef NULL
+
+LOCALVAR FILE *Drives[NumDrives]; /* open disk image files */
+
+LOCALPROC InitDrives(void)
+{
+ /*
+ This isn't really needed, Drives[i] and DriveNames[i]
+ need not have valid values when not vSonyIsInserted[i].
+ */
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ Drives[i] = NotAfileRef;
+ }
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer,
+ tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
+ ui5r *Sony_ActCount)
+{
+ tMacErr err = mnvm_miscErr;
+ FILE *refnum = Drives[Drive_No];
+ ui5r NewSony_Count = 0;
+
+ if (0 == fseek(refnum, Sony_Start, SEEK_SET)) {
+ if (IsWrite) {
+ NewSony_Count = fwrite(Buffer, 1, Sony_Count, refnum);
+ } else {
+ NewSony_Count = fread(Buffer, 1, Sony_Count, refnum);
+ }
+
+ if (NewSony_Count == Sony_Count) {
+ err = mnvm_noErr;
+ }
+ }
+
+ if (nullpr != Sony_ActCount) {
+ *Sony_ActCount = NewSony_Count;
+ }
+
+ return err; /*& figure out what really to return &*/
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count)
+{
+ tMacErr err = mnvm_miscErr;
+ FILE *refnum = Drives[Drive_No];
+ long v;
+
+ if (0 == fseek(refnum, 0, SEEK_END)) {
+ v = ftell(refnum);
+ if (v >= 0) {
+ *Sony_Count = v;
+ err = mnvm_noErr;
+ }
+ }
+
+ return err; /*& figure out what really to return &*/
+}
+
+LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit)
+{
+ FILE *refnum = Drives[Drive_No];
+
+ DiskEjectedNotify(Drive_No);
+
+ fclose(refnum);
+ Drives[Drive_No] = NotAfileRef; /* not really needed */
+
+ return mnvm_noErr;
+}
+
+GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No)
+{
+ return vSonyEject0(Drive_No, falseblnr);
+}
+
+#if IncludeSonyNew
+GLOBALOSGLUFUNC tMacErr vSonyEjectDelete(tDrive Drive_No)
+{
+ return vSonyEject0(Drive_No, trueblnr);
+}
+#endif
+
+#if IncludeSonyGetName
+GLOBALOSGLUFUNC tMacErr vSonyGetName(tDrive Drive_No, tPbuf *r)
+{
+ r[0] = 0;
+ return mnvm_noErr;
+}
+#endif
+
+LOCALPROC UnInitDrives(void)
+{
+ tDrive i;
+
+ for (i = 0; i < NumDrives; ++i) {
+ if (vSonyIsInserted(i)) {
+ (void) vSonyEject(i);
+ }
+ }
+}
+
+LOCALFUNC blnr Sony_Insert0(FILE *refnum, blnr locked,
+ char *drivepath)
+{
+ tDrive Drive_No;
+ blnr IsOk = falseblnr;
+
+ if (! FirstFreeDisk(&Drive_No)) {
+ MacMsg(kStrTooManyImagesTitle, kStrTooManyImagesMessage,
+ falseblnr);
+ } else {
+ /* printf("Sony_Insert0 %d\n", (int)Drive_No); */
+
+ {
+ Drives[Drive_No] = refnum;
+ DiskInsertNotify(Drive_No, locked);
+
+ IsOk = trueblnr;
+ }
+ }
+
+ if (! IsOk) {
+ fclose(refnum);
+ }
+
+ return IsOk;
+}
+
+LOCALFUNC blnr Sony_Insert1(char *drivepath, blnr silentfail)
+{
+ blnr locked = falseblnr;
+ /* printf("Sony_Insert1 %s\n", drivepath); */
+ FILE *refnum = fopen(drivepath, "rb+");
+ if (NULL == refnum) {
+ locked = trueblnr;
+ refnum = fopen(drivepath, "rb");
+ }
+ if (NULL == refnum) {
+ if (! silentfail) {
+ MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
+ }
+ } else {
+ return Sony_Insert0(refnum, locked, drivepath);
+ }
+ return falseblnr;
+}
+
+LOCALFUNC tMacErr LoadMacRomFrom(char *path)
+{
+ tMacErr err;
+ FILE *ROM_File;
+ int File_Size;
+
+ ROM_File = fopen(path, "rb");
+ if (NULL == ROM_File) {
+ err = mnvm_fnfErr;
+ } else {
+ File_Size = fread(ROM, 1, kROM_Size, ROM_File);
+ if (File_Size != kROM_Size) {
+ if (feof(ROM_File)) {
+ MacMsgOverride(kStrShortROMTitle,
+ kStrShortROMMessage);
+ err = mnvm_eofErr;
+ } else {
+ MacMsgOverride(kStrNoReadROMTitle,
+ kStrNoReadROMMessage);
+ err = mnvm_miscErr;
+ }
+ } else {
+ err = ROM_IsValid();
+ }
+ fclose(ROM_File);
+ }
+
+ return err;
+}
+
+LOCALFUNC blnr Sony_Insert1a(char *drivepath, blnr silentfail)
+{
+ blnr v;
+
+ if (! ROM_loaded) {
+ v = (mnvm_noErr == LoadMacRomFrom(drivepath));
+ } else {
+ v = Sony_Insert1(drivepath, silentfail);
+ }
+
+ return v;
+}
+
+static void
+plumbproc(void *)
+{
+ int f;
+ Plumbmsg *m;
+ char tmp[1024];
+
+ threadsetname("plumb");
+ if ((f = plumbopen("minivmac", OREAD)) >= 0) {
+ while ((m = plumbrecv(f)) != nil) {
+ snprint(tmp, sizeof(tmp), "%s/%s", m->wdir, m->data);
+ Sony_Insert1a(tmp, 0);
+ plumbfree(m);
+ }
+ }
+
+ threadexits(nil);
+}
+
+LOCALFUNC blnr Sony_Insert2(char *s)
+{
+ return Sony_Insert1(s, trueblnr);
+}
+
+LOCALFUNC blnr Sony_InsertIth(int i)
+{
+ blnr v;
+
+ if ((i > 9) || ! FirstFreeDisk(nullpr)) {
+ v = falseblnr;
+ } else {
+ char s[] = "disk?.dsk";
+
+ s[4] = '0' + i;
+
+ v = Sony_Insert2(s);
+ }
+
+ return v;
+}
+
+LOCALFUNC blnr LoadInitialImages(void)
+{
+ if (! AnyDiskInserted()) {
+ int i;
+
+ for (i = 1; Sony_InsertIth(i); ++i) {
+ /* stop on first error (including file not found) */
+ }
+ }
+
+ proccreate(plumbproc, nil, mainstacksize);
+
+ return trueblnr;
+}
+
+/* --- ROM --- */
+
+LOCALVAR char *rom_path = NULL;
+
+LOCALFUNC blnr LoadMacRom(void)
+{
+ tMacErr err;
+
+ if ((NULL == rom_path)
+ || (mnvm_fnfErr == (err = LoadMacRomFrom(rom_path))))
+ if (mnvm_fnfErr == (err = LoadMacRomFrom(RomFileName)))
+ {
+ }
+
+ return trueblnr; /* keep launching Mini vMac, regardless */
+}
+
+/* --- video out --- */
+
+#if VarFullScreen
+LOCALVAR blnr UseFullScreen = (WantInitFullScreen != 0);
+#endif
+
+#if EnableMagnify
+LOCALVAR blnr UseMagnify = (WantInitMagnify != 0);
+#endif
+
+LOCALVAR blnr gBackgroundFlag = falseblnr;
+LOCALVAR blnr gTrueBackgroundFlag = falseblnr;
+LOCALVAR blnr CurSpeedStopped = falseblnr;
+
+#if EnableMagnify
+#define MaxScale MyWindowScale
+#else
+#define MaxScale 1
+#endif
+
+
+LOCALVAR Image *my_surface = nullpr;
+LOCALVAR u8int *pixels;
+
+LOCALVAR ui3p ScalingBuff = nullpr;
+
+LOCALVAR ui3p CLUT_final;
+
+#define CLUT_finalsz (256 * 8 * 4 * MaxScale)
+ /*
+ 256 possible values of one byte
+ 8 pixels per byte maximum (when black and white)
+ 4 bytes per destination pixel maximum
+ multiplied by MyWindowScale if EnableMagnify
+ */
+
+#define ScrnMapr_DoMap UpdateBWDepth3Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth4Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 4
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth5Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth3ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth4ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 4
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateBWDepth5ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth 0
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+
+#define ScrnMapr_DoMap UpdateColorDepth3Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth4Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 4
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth5Copy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth3ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 3
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth4ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 4
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#define ScrnMapr_DoMap UpdateColorDepth5ScaledCopy
+#define ScrnMapr_Src GetCurDrawBuff()
+#define ScrnMapr_Dst ScalingBuff
+#define ScrnMapr_SrcDepth vMacScreenDepth
+#define ScrnMapr_DstDepth 5
+#define ScrnMapr_Map CLUT_final
+#define ScrnMapr_Scale MyWindowScale
+
+#include "SCRNMAPR.h"
+
+#endif
+
+
+LOCALPROC HaveChangedScreenBuff(ui4r top, ui4r left,
+ ui4r bottom, ui4r right)
+{
+ int i;
+ int j;
+ ui3b *p;
+ Uint32 pixel;
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ Uint32 CLUT_pixel[CLUT_size];
+#endif
+ Uint32 BWLUT_pixel[2];
+ ui5r top2 = top;
+ ui5r left2 = left;
+ ui5r bottom2 = bottom;
+ ui5r right2 = right;
+
+#if EnableMagnify
+ if (UseMagnify) {
+ top2 *= MyWindowScale;
+ left2 *= MyWindowScale;
+ bottom2 *= MyWindowScale;
+ right2 *= MyWindowScale;
+ }
+#endif
+
+ /* FIXME image locking here? */
+
+ {
+
+ int bpp = 4; /* FIXME RGB32 for now, make it dynamic though */
+ ui5r ExpectedPitch = vMacScreenWidth * bpp;
+
+#if EnableMagnify
+ if (UseMagnify) {
+ ExpectedPitch *= MyWindowScale;
+ }
+#endif
+
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+#if vMacScreenDepth < 4
+ for (i = 0; i < CLUT_size; ++i) {
+ CLUT_pixel[i] = (CLUT_blues[i]>>8)<<24 | (CLUT_greens[i]>>8)<<16 | (CLUT_reds[i]>>8)<<8 | 0xff;
+ }
+#endif
+ } else
+#endif
+ {
+ BWLUT_pixel[1] = 0x000000ff;
+ /* black */
+ BWLUT_pixel[0] = 0xffffffff;
+ /* white */
+ }
+
+ if ((0 == ((bpp - 1) & bpp)) /* a power of 2 */
+#if (vMacScreenDepth > 3)
+ && ! UseColorMode
+#endif
+ )
+ {
+ int k;
+ Uint32 v;
+#if EnableMagnify
+ int a;
+#endif
+ int PixPerByte =
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ UseColorMode ? (1 << (3 - vMacScreenDepth)) :
+#endif
+ 8;
+ Uint8 *p4 = (Uint8 *)CLUT_final;
+
+ for (i = 0; i < 256; ++i) {
+ for (k = PixPerByte; --k >= 0; ) {
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ if (UseColorMode) {
+ v = CLUT_pixel[
+#if 3 == vMacScreenDepth
+ i
+#else
+ (i >> (k << vMacScreenDepth))
+ & (CLUT_size - 1)
+#endif
+ ];
+ } else
+#endif
+ {
+ v = BWLUT_pixel[(i >> k) & 1];
+ }
+
+#if EnableMagnify
+ for (a = UseMagnify ? MyWindowScale : 1; --a >= 0; )
+#endif
+ {
+ switch (bpp) {
+ case 1: /* Assuming 8-bpp */
+ *p4++ = v;
+ break;
+ case 2: /* Probably 15-bpp or 16-bpp */
+ *(Uint16 *)p4 = v;
+ p4 += 2;
+ break;
+ case 4: /* Probably 32-bpp */
+ *(Uint32 *)p4 = v;
+ p4 += 4;
+ break;
+ }
+ }
+ }
+ }
+
+ ScalingBuff = (ui3p)pixels;
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ if (UseColorMode) {
+#if EnableMagnify
+ if (UseMagnify) {
+ switch (bpp) {
+ case 1:
+ UpdateColorDepth3ScaledCopy(
+ top, left, bottom, right);
+ break;
+ case 2:
+ UpdateColorDepth4ScaledCopy(
+ top, left, bottom, right);
+ break;
+ case 4:
+ UpdateColorDepth5ScaledCopy(
+ top, left, bottom, right);
+ break;
+ }
+ } else
+#endif
+ {
+ switch (bpp) {
+ case 1:
+ UpdateColorDepth3Copy(top, left, bottom, right);
+ break;
+ case 2:
+ UpdateColorDepth4Copy(top, left, bottom, right);
+ break;
+ case 4:
+ UpdateColorDepth5Copy(top, left, bottom, right);
+ break;
+ }
+ }
+ } else
+#endif
+ {
+#if EnableMagnify
+ if (UseMagnify) {
+ switch (bpp) {
+ case 1:
+ UpdateBWDepth3ScaledCopy(
+ top, left, bottom, right);
+ break;
+ case 2:
+ UpdateBWDepth4ScaledCopy(
+ top, left, bottom, right);
+ break;
+ case 4:
+ UpdateBWDepth5ScaledCopy(
+ top, left, bottom, right);
+ break;
+ }
+ } else
+#endif
+ {
+ switch (bpp) {
+ case 1:
+ UpdateBWDepth3Copy(top, left, bottom, right);
+ break;
+ case 2:
+ UpdateBWDepth4Copy(top, left, bottom, right);
+ break;
+ case 4:
+ UpdateBWDepth5Copy(top, left, bottom, right);
+ break;
+ }
+ }
+ }
+
+ } else {
+ ui3b *the_data = (ui3b *)GetCurDrawBuff();
+
+ /* adapted from putpixel in SDL documentation */
+
+ for (i = top2; i < bottom2; ++i) {
+ for (j = left2; j < right2; ++j) {
+ int i0 = i;
+ int j0 = j;
+ Uint8 *bufp = (Uint8 *)pixels
+ + i * Dx(my_surface->r)*bpp + j * bpp;
+
+#if EnableMagnify
+ if (UseMagnify) {
+ i0 /= MyWindowScale;
+ j0 /= MyWindowScale;
+ }
+#endif
+
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+#if vMacScreenDepth < 4
+ p = the_data + ((i0 * vMacScreenWidth + j0)
+ >> (3 - vMacScreenDepth));
+ {
+ ui3r k = (*p >> (((~ j0)
+ & ((1 << (3 - vMacScreenDepth)) - 1))
+ << vMacScreenDepth))
+ & (CLUT_size - 1);
+ pixel = CLUT_pixel[k];
+ }
+#elif 4 == vMacScreenDepth
+ p = the_data + ((i0 * vMacScreenWidth + j0) << 1);
+ {
+ ui4r t0 = do_get_mem_word(p);
+ pixel =
+ (((t0 & 0x7C00) >> 7)
+ | ((t0 & 0x7000) >> 12))<<24 |
+ (((t0 & 0x03E0) >> 2)
+ | ((t0 & 0x0380) >> 7))<<16 |
+ (((t0 & 0x001F) << 3)
+ | ((t0 & 0x001C) >> 2))<<8 |
+ 0xff;
+ }
+#elif 5 == vMacScreenDepth
+ p = the_data + ((i0 * vMacScreenWidth + j0) << 2);
+ pixel = p[1]<<24 | p[2]<<16 | p[3]<<8 | 0xff;
+#endif
+ } else
+#endif
+ {
+ p = the_data + ((i0 * vMacScreenWidth + j0) / 8);
+ pixel = BWLUT_pixel[(*p >> ((~ j0) & 0x7)) & 1];
+ }
+
+ switch (bpp) {
+ case 1: /* Assuming 8-bpp */
+ *bufp = pixel;
+ break;
+ case 2: /* Probably 15-bpp or 16-bpp */
+ *(Uint16 *)bufp = pixel;
+ break;
+ case 3:
+ bufp[0] = (pixel >> 16) & 0xff;
+ bufp[1] = (pixel >> 8) & 0xff;
+ bufp[2] = pixel & 0xff;
+ break;
+ case 4: /* Probably 32-bpp */
+ *(Uint32 *)bufp = pixel;
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ /* FIXME image unlocking? */
+ lockdisplay(display);
+ if(loadimage(my_surface, my_surface->r, pixels, 4*Dx(my_surface->r)*Dy(my_surface->r)) < 0)
+ sysfatal("%r");
+ Rectangle r = screen->r;
+ r.min.x += (Dx(r) - Dx(my_surface->r))/2;
+ r.min.y += (Dy(r) - Dy(my_surface->r))/2;
+ draw(screen, r, my_surface, nil, ZP);
+ flushimage(display, 1);
+ unlockdisplay(display);
+}
+
+LOCALPROC MyDrawChangesAndClear(void)
+{
+ if (ScreenChangedBottom > ScreenChangedTop) {
+ HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft,
+ ScreenChangedBottom, ScreenChangedRight);
+ ScreenClearChanges();
+ }
+}
+
+GLOBALOSGLUPROC DoneWithDrawingForTick(void)
+{
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ AutoScrollScreen();
+ }
+#endif
+ MyDrawChangesAndClear();
+}
+
+/* --- mouse --- */
+
+/* cursor hiding */
+
+LOCALVAR blnr HaveCursorHidden = falseblnr;
+LOCALVAR blnr WantCursorHidden = falseblnr;
+
+LOCALPROC ForceShowCursor(void)
+{
+ if (HaveCursorHidden) {
+ HaveCursorHidden = falseblnr;
+ // FIXME pointer toggle
+ //(void) SDL_ShowCursor(SDL_ENABLE);
+ }
+}
+
+/* cursor moving */
+
+LOCALFUNC blnr MyMoveMouse(si4b h, si4b v)
+{
+#if EnableMagnify
+ if (UseMagnify) {
+ h *= MyWindowScale;
+ v *= MyWindowScale;
+ }
+#endif
+
+ // FIXME pointer warp
+ //SDL_WarpMouse(h, v);
+
+ return trueblnr;
+}
+
+/* cursor state */
+
+LOCALPROC MousePositionNotify(int NewMousePosh, int NewMousePosv)
+{
+ blnr ShouldHaveCursorHidden = trueblnr;
+
+#if EnableMagnify
+ if (UseMagnify) {
+ NewMousePosh /= MyWindowScale;
+ NewMousePosv /= MyWindowScale;
+ }
+#endif
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMousePositionSetDelta(NewMousePosh - SavedMouseH,
+ NewMousePosv - SavedMouseV);
+ SavedMouseH = NewMousePosh;
+ SavedMouseV = NewMousePosv;
+ } else
+#endif
+ {
+ if (NewMousePosh < 0) {
+ NewMousePosh = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosh >= vMacScreenWidth) {
+ NewMousePosh = vMacScreenWidth - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+ if (NewMousePosv < 0) {
+ NewMousePosv = 0;
+ ShouldHaveCursorHidden = falseblnr;
+ } else if (NewMousePosv >= vMacScreenHeight) {
+ NewMousePosv = vMacScreenHeight - 1;
+ ShouldHaveCursorHidden = falseblnr;
+ }
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ ShouldHaveCursorHidden = trueblnr;
+ }
+#endif
+
+ /* if (ShouldHaveCursorHidden || CurMouseButton) */
+ /*
+ for a game like arkanoid, would like mouse to still
+ move even when outside window in one direction
+ */
+ MyMousePositionSet(NewMousePosh, NewMousePosv);
+ }
+
+ WantCursorHidden = ShouldHaveCursorHidden;
+}
+
+/* --- keyboard input --- */
+
+LOCALFUNC ui3r Rune2MacKeyCode(Rune i)
+{
+ ui3r v = MKC_None;
+
+ switch (i) {
+ case Kbs: v = MKC_BackSpace; break;
+ case '\t': v = MKC_Tab; break;
+ //FIXME case clear: v = MKC_Clear; break;
+ case '\n': v = MKC_Return; break;
+ //FIXME case pause: v = MKC_Pause; break;
+ case Kesc: v = MKC_formac_Escape; break;
+ case ' ': v = MKC_Space; break;
+ case '\'': v = MKC_SingleQuote; break;
+ case ',': v = MKC_Comma; break;
+ case '-': v = MKC_Minus; break;
+ case '.': v = MKC_Period; break;
+ case '/': v = MKC_formac_Slash; break;
+ case '0': v = MKC_0; break;
+ case '1': v = MKC_1; break;
+ case '2': v = MKC_2; break;
+ case '3': v = MKC_3; break;
+ case '4': v = MKC_4; break;
+ case '5': v = MKC_5; break;
+ case '6': v = MKC_6; break;
+ case '7': v = MKC_7; break;
+ case '8': v = MKC_8; break;
+ case '9': v = MKC_9; break;
+ case ';': v = MKC_SemiColon; break;
+ case '=': v = MKC_Equal; break;
+
+ case '[': v = MKC_LeftBracket; break;
+ case '\\': v = MKC_formac_BackSlash; break;
+ case ']': v = MKC_RightBracket; break;
+ case '`': v = MKC_formac_Grave; break;
+
+ case 'a': v = MKC_A; break;
+ case 'b': v = MKC_B; break;
+ case 'c': v = MKC_C; break;
+ case 'd': v = MKC_D; break;
+ case 'e': v = MKC_E; break;
+ case 'f': v = MKC_F; break;
+ case 'g': v = MKC_G; break;
+ case 'h': v = MKC_H; break;
+ case 'i': v = MKC_I; break;
+ case 'j': v = MKC_J; break;
+ case 'k': v = MKC_K; break;
+ case 'l': v = MKC_L; break;
+ case 'm': v = MKC_M; break;
+ case 'n': v = MKC_N; break;
+ case 'o': v = MKC_O; break;
+ case 'p': v = MKC_P; break;
+ case 'q': v = MKC_Q; break;
+ case 'r': v = MKC_R; break;
+ case 's': v = MKC_S; break;
+ case 't': v = MKC_T; break;
+ case 'u': v = MKC_U; break;
+ case 'v': v = MKC_V; break;
+ case 'w': v = MKC_W; break;
+ case 'x': v = MKC_X; break;
+ case 'y': v = MKC_Y; break;
+ case 'z': v = MKC_Z; break;
+
+ case Kup: v = MKC_Up; break;
+ case Kdown: v = MKC_Down; break;
+ case Kright: v = MKC_Right; break;
+ case Kleft: v = MKC_Left; break;
+ case Kins: v = MKC_formac_Help; break;
+ case Khome: v = MKC_formac_Home; break;
+ case Kend: v = MKC_formac_End; break;
+ case Kpgup: v = MKC_formac_PageUp; break;
+ case Kpgdown: v = MKC_formac_PageDown; break;
+
+ //case KF|1: v = MKC_formac_F1; break;
+ //case KF|2: v = MKC_formac_F2; break;
+ //case KF|3: v = MKC_formac_F3; break;
+ case KF|4: v = MKC_formac_F4; break;
+ case KF|5: v = MKC_formac_F5; break;
+ case KF|6: v = MKC_F6; break;
+ case KF|7: v = MKC_F7; break;
+ case KF|8: v = MKC_F8; break;
+ case KF|9: v = MKC_F9; break;
+ case KF|10: v = MKC_F10; break;
+ case KF|11: v = MKC_F11; break;
+ case KF|12: v = MKC_F12; break;
+
+ case Kshift: v = MKC_formac_Shift; break;
+ case Kctl: v = MKC_formac_Control; break;
+ case Kalt: case KF|1: v = MKC_formac_Command; break;
+ case KF|2: v = MKC_formac_Command; break;
+ case KF|3: v = MKC_formac_Option; break;
+
+ //FIXME case SDLK_HELP: v = MKC_formac_Help; break;
+ //FIXME case SDLK_PRINT: v = MKC_Print; break;
+
+ default:
+ break;
+ }
+
+ return v;
+}
+
+LOCALPROC DoKeyCode(Rune r, blnr down)
+{
+ ui3r v = Rune2MacKeyCode(r);
+ if (MKC_None != v) {
+ Keyboard_UpdateKeyMap2(v, down);
+ }
+}
+
+LOCALPROC DisableKeyRepeat(void)
+{
+}
+
+LOCALPROC RestoreKeyRepeat(void)
+{
+}
+
+LOCALPROC ReconnectKeyCodes3(void)
+{
+}
+
+LOCALPROC DisconnectKeyCodes3(void)
+{
+ DisconnectKeyCodes2();
+ MyMouseButtonSet(falseblnr);
+}
+
+/* --- time, date, location --- */
+
+#define dbglog_TimeStuff (0 && dbglog_HAVE)
+
+LOCALVAR ui5b TrueEmulatedTime = 0;
+
+#define MyInvTimeDivPow 16
+#define MyInvTimeDiv (1 << MyInvTimeDivPow)
+#define MyInvTimeDivMask (MyInvTimeDiv - 1)
+#define MyInvTimeStep 1089590 /* 1000 / 60.14742 * MyInvTimeDiv */
+
+LOCALVAR Uint32 LastTime;
+
+LOCALVAR Uint32 NextIntTime;
+LOCALVAR ui5b NextFracTime;
+
+LOCALPROC IncrNextTime(void)
+{
+ NextFracTime += MyInvTimeStep;
+ NextIntTime += (NextFracTime >> MyInvTimeDivPow);
+ NextFracTime &= MyInvTimeDivMask;
+}
+
+LOCALPROC InitNextTime(void)
+{
+ NextIntTime = LastTime;
+ NextFracTime = 0;
+ IncrNextTime();
+}
+
+LOCALVAR ui5b NewMacDateInSeconds;
+
+static int usensec = 0;
+
+/*
+ * nsec() is wallclock and can be adjusted by timesync
+ * so need to use cycles() instead, but fall back to
+ * nsec() in case we can't
+ *
+ * "fasthz" is how many ticks there are in a second
+ * can be read from /dev/time
+ *
+ * perhaps using RDTSCP is even better
+ */
+static uvlong
+nanosec(void)
+{
+ static uvlong fasthz, xstart;
+ uvlong x, div;
+ int f, n, i;
+ char tmp[128], *e;
+
+ if (fasthz == ~0ULL)
+ return nsec() - xstart;
+
+ if (fasthz == 0) {
+ fasthz = ~0ULL;
+ xstart = nsec();
+ if (usensec)
+ return 0;
+ if ((f = open("/dev/time", OREAD)) >= 0 && (n = read(f, tmp, sizeof(tmp)-1)) > 2) {
+ tmp[n] = 0;
+ e = tmp;
+ for (i = 0; i < 3; i++)
+ strtoll(e, &e, 10);
+ if ((fasthz = strtoll(e, nil, 10)) < 1)
+ fasthz = ~0ULL;
+ else
+ cycles(&xstart);
+ }
+ close(f);
+ if (fasthz == ~0ULL) {
+ fprint(2, "couldn't get fasthz, falling back to nsec()\n");
+ fprint(2, "you might want to disable aux/timesync\n");
+ return 0;
+ }
+ }
+ cycles(&x);
+ x -= xstart;
+
+ for (div = 1000000000ULL; x < 0x1999999999999999ULL && div > 1 ; div /= 10ULL, x *= 10ULL);
+
+ return x / (fasthz / div);
+}
+
+LOCALFUNC blnr UpdateTrueEmulatedTime(void)
+{
+ Uint32 LatestTime;
+ si5b TimeDiff;
+
+ LatestTime = nanosec() / 1000000ULL;
+ if (LatestTime != LastTime) {
+
+ NewMacDateInSeconds = LatestTime / 1000;
+ /* no date and time api in SDL */
+
+ LastTime = LatestTime;
+ TimeDiff = (LatestTime - NextIntTime);
+ /* this should work even when time wraps */
+ if (TimeDiff >= 0) {
+ if (TimeDiff > 256) {
+ /* emulation interrupted, forget it */
+ ++TrueEmulatedTime;
+ InitNextTime();
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("emulation interrupted",
+ TrueEmulatedTime);
+#endif
+ } else {
+ do {
+ ++TrueEmulatedTime;
+ IncrNextTime();
+ TimeDiff = (LatestTime - NextIntTime);
+ } while (TimeDiff >= 0);
+ }
+ return trueblnr;
+ } else {
+ if (TimeDiff < -256) {
+#if dbglog_TimeStuff
+ dbglog_writeln("clock set back");
+#endif
+ /* clock goofed if ever get here, reset */
+ InitNextTime();
+ }
+ }
+ }
+ return falseblnr;
+}
+
+
+LOCALFUNC blnr CheckDateTime(void)
+{
+ if (CurMacDateInSeconds != NewMacDateInSeconds) {
+ CurMacDateInSeconds = NewMacDateInSeconds;
+ return trueblnr;
+ } else {
+ return falseblnr;
+ }
+}
+
+LOCALPROC StartUpTimeAdjust(void)
+{
+ LastTime = nanosec() / 1000000ULL;
+ InitNextTime();
+}
+
+LOCALFUNC blnr InitLocationDat(void)
+{
+ LastTime = nanosec() / 1000000ULL;
+ InitNextTime();
+ NewMacDateInSeconds = LastTime / 1000;
+ CurMacDateInSeconds = NewMacDateInSeconds;
+
+ return trueblnr;
+}
+
+/* --- sound --- */
+
+static int audiofd;
+static u8int *audiobuf;
+static int audiooff;
+
+GLOBALOSGLUFUNC tpSoundSamp MySound_BeginWrite(ui4r n, ui4r *actL)
+{
+ *actL = n;
+ audiooff += n;
+ return audiobuf + audiooff - n;
+}
+
+LOCALVAR blnr HaveSoundOut = falseblnr;
+
+static char audiofmt[32];
+
+static void
+runpcmconv(void *x)
+{
+ int *p;
+
+ p = x;
+ dup(p[0], 0); close(p[0]); close(p[1]);
+ dup(open("/dev/audio", OWRITE), 1);
+ procexecl(nil, "/bin/audio/pcmconv", "pcmconv", "-i", audiofmt, nil);
+ threadexits("exec: %r");
+}
+
+#define SOUND_SAMPLERATE 22255
+
+LOCALFUNC blnr MySound_Init(void)
+{
+ int p[2];
+
+ sprint(
+ audiofmt, "%c%dc1r%d",
+ 3 == kLn2SoundSampSz ? 'u' : 's',
+ 3 == kLn2SoundSampSz ? 8 : 16,
+ SOUND_SAMPLERATE
+ );
+
+ pipe(p);
+ procrfork(runpcmconv, p, 4096, RFFDG);
+ close(p[0]);
+ audiofd = p[1];
+ HaveSoundOut = trueblnr;
+ audiobuf = malloc(65536);
+
+ return trueblnr;
+}
+
+GLOBALOSGLUPROC MySound_EndWrite(ui4r actL)
+{
+ write(audiofd, audiobuf, audiooff);
+ audiooff = 0;
+}
+
+/* --- basic dialogs --- */
+
+LOCALPROC CheckSavedMacMsg(void)
+{
+ /* called only on quit, if error saved but not yet reported */
+
+ if (nullpr != SavedBriefMsg) {
+ char briefMsg0[ClStrMaxLength + 1];
+ char longMsg0[ClStrMaxLength + 1];
+
+ NativeStrFromCStr(briefMsg0, SavedBriefMsg);
+ NativeStrFromCStr(longMsg0, SavedLongMsg);
+
+ fprint(2, "%s\n", briefMsg0);
+ fprint(2, "%s\n", longMsg0);
+
+ SavedBriefMsg = nullpr;
+ }
+}
+
+/* --- main window creation and disposal --- */
+
+LOCALVAR int my_argc;
+LOCALVAR char **my_argv;
+
+enum {
+ Cmouse,
+ Cresize,
+ Numchan,
+};
+
+static Mousectl *mctl;
+static Keyboardctl kctl;
+static Rune rune;
+static Mouse mouse;
+static int altdown, ctldown, shiftdown;
+static Alt a[Numchan+1] = {
+ [Cmouse] = { nil, &mouse, CHANRCV },
+ [Cresize] = { nil, nil, CHANRCV },
+ { nil, nil, CHANNOBLK },
+};
+
+static void
+kbdproc(void *)
+{
+ char buf[128], buf2[128], *s;
+ int kfd, n, kbin;
+ Rune r;
+
+ threadsetname("kbdproc");
+ if ((kfd = open("/dev/kbd", OREAD)) < 0)
+ sysfatal("/dev/kbd: %r");
+ kbin = open("/dev/kbin", OWRITE);
+
+ buf2[0] = 0;
+ buf2[1] = 0;
+ buf[0] = 0;
+ for (;;) {
+ if (buf[0] != 0) {
+ n = strlen(buf)+1;
+ memmove(buf, buf+n, sizeof(buf)-n);
+ }
+ if (buf[0] == 0) {
+ n = read(kfd, buf, sizeof(buf)-1);
+ if (n <= 0)
+ break;
+ buf[n-1] = 0;
+ buf[n] = 0;
+ }
+
+ switch (buf[0]) {
+ default:
+ continue;
+
+ case 'k':
+ s = buf+1;
+ while (*s) {
+ s += chartorune(&r, s);
+ if (utfrune(buf2+1, r) == nil) {
+ DoKeyCode(r, 1);
+ if (r == Kalt) {
+ /* magic trick: write Alt scancode to disable the "compose" mode */
+ if (kbin >= 0)
+ write(kbin, "\x46", 1);
+ }
+ }
+ }
+ break;
+
+ case 'K':
+ s = buf2+1;
+ while (*s) {
+ s += chartorune(&r, s);
+ if (utfrune(buf+1, r) == nil)
+ DoKeyCode(r, 0);
+ }
+ break;
+ }
+ strcpy(buf2, buf);
+ }
+
+ threadexits(nil);
+}
+
+static Cursor emptycursor = { {0, 0}, { 0 }, { 0 } };
+
+LOCALFUNC blnr Screen_Init(void)
+{
+ InitKeyCodes();
+
+ threadsetname(kStrAppName);
+
+ if(initdraw(nil, nil, kStrAppName) < 0)
+ sysfatal("initdraw: %r");
+ if ((mctl = initmouse(nil, screen)) == nil)
+ sysfatal("initmouse: %r");
+ setcursor(mctl, &emptycursor);
+ display->locking = 1;
+ unlockdisplay(display);
+
+ a[Cmouse].c = mctl->c;
+ a[Cresize].c = mctl->resizec;
+
+ proccreate(kbdproc, nil, mainstacksize);
+
+ return trueblnr;
+}
+
+#if MayFullScreen
+LOCALVAR blnr GrabMachine = falseblnr;
+#endif
+
+#if MayFullScreen
+LOCALPROC GrabTheMachine(void)
+{
+#if GrabKeysFullScreen
+#endif
+
+#if EnableFSMouseMotion
+ /*
+ if magnification changes, need to reset,
+ even if HaveMouseMotion already true
+ */
+ if (MyMoveMouse(ViewHStart + (ViewHSize / 2),
+ ViewVStart + (ViewVSize / 2)))
+ {
+ SavedMouseH = ViewHStart + (ViewHSize / 2);
+ SavedMouseV = ViewVStart + (ViewVSize / 2);
+ HaveMouseMotion = trueblnr;
+ }
+#endif
+}
+#endif
+
+#if MayFullScreen
+LOCALPROC UngrabMachine(void)
+{
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ HaveMouseMotion = falseblnr;
+ }
+#endif
+
+#if GrabKeysFullScreen
+#endif
+}
+#endif
+
+#if EnableFSMouseMotion
+LOCALPROC MyMouseConstrain(void)
+{
+ si4b shiftdh;
+ si4b shiftdv;
+
+ if (SavedMouseH < ViewHStart + (ViewHSize / 4)) {
+ shiftdh = ViewHSize / 2;
+ } else if (SavedMouseH > ViewHStart + ViewHSize - (ViewHSize / 4)) {
+ shiftdh = - ViewHSize / 2;
+ } else {
+ shiftdh = 0;
+ }
+ if (SavedMouseV < ViewVStart + (ViewVSize / 4)) {
+ shiftdv = ViewVSize / 2;
+ } else if (SavedMouseV > ViewVStart + ViewVSize - (ViewVSize / 4)) {
+ shiftdv = - ViewVSize / 2;
+ } else {
+ shiftdv = 0;
+ }
+ if ((shiftdh != 0) || (shiftdv != 0)) {
+ SavedMouseH += shiftdh;
+ SavedMouseV += shiftdv;
+ if (! MyMoveMouse(SavedMouseH, SavedMouseV)) {
+ HaveMouseMotion = falseblnr;
+ }
+ }
+}
+#endif
+
+LOCALFUNC blnr CreateMainWindow(void)
+{
+ int NewWindowHeight = vMacScreenHeight;
+ int NewWindowWidth = vMacScreenWidth;
+ blnr v = falseblnr;
+
+#if EnableMagnify && 1
+ if (UseMagnify) {
+ NewWindowHeight *= MyWindowScale;
+ NewWindowWidth *= MyWindowScale;
+ }
+#endif
+
+#if VarFullScreen
+ if (UseFullScreen)
+#endif
+#if MayFullScreen
+ {
+ }
+#endif
+
+ ViewHStart = 0;
+ ViewVStart = 0;
+ ViewHSize = vMacScreenWidth;
+ ViewVSize = vMacScreenHeight;
+
+ freeimage(my_surface);
+ my_surface = allocimage(
+ display,
+ Rect(0, 0, NewWindowWidth, NewWindowHeight),
+ CHAN4(CBlue, 8, CGreen, 8, CRed, 8, CIgnore, 8),
+ 0,
+ DWhite);
+ if (NULL == my_surface) {
+ fprint(2, "allocimage: %r\n");
+ } else {
+#if 0 != vMacScreenDepth
+ ColorModeWorks = trueblnr;
+#endif
+ v = trueblnr;
+ pixels = realloc(pixels, 4*NewWindowWidth*NewWindowHeight);
+ }
+
+ return v;
+}
+
+#if EnableRecreateW
+LOCALFUNC blnr ReCreateMainWindow(void)
+{
+ ForceShowCursor(); /* hide/show cursor api is per window */
+
+#if MayFullScreen
+ if (GrabMachine) {
+ GrabMachine = falseblnr;
+ UngrabMachine();
+ }
+#endif
+
+#if EnableMagnify
+ UseMagnify = WantMagnify;
+#endif
+#if VarFullScreen
+ UseFullScreen = WantFullScreen;
+#endif
+
+ (void) CreateMainWindow();
+
+ if (HaveCursorHidden) {
+ (void) MyMoveMouse(CurMouseH, CurMouseV);
+ }
+
+ return trueblnr;
+}
+#endif
+
+LOCALPROC ZapWinStateVars(void)
+{
+}
+
+#if VarFullScreen
+LOCALPROC ToggleWantFullScreen(void)
+{
+ WantFullScreen = ! WantFullScreen;
+}
+#endif
+
+/* --- SavedTasks --- */
+
+LOCALPROC LeaveBackground(void)
+{
+ ReconnectKeyCodes3();
+ DisableKeyRepeat();
+}
+
+LOCALPROC EnterBackground(void)
+{
+ RestoreKeyRepeat();
+ DisconnectKeyCodes3();
+
+ ForceShowCursor();
+}
+
+LOCALPROC LeaveSpeedStopped(void)
+{
+ StartUpTimeAdjust();
+}
+
+LOCALPROC EnterSpeedStopped(void)
+{
+}
+
+LOCALPROC CheckForSavedTasks(void)
+{
+ if (MyEvtQNeedRecover) {
+ MyEvtQNeedRecover = falseblnr;
+
+ /* attempt cleanup, MyEvtQNeedRecover may get set again */
+ MyEvtQTryRecoverFromFull();
+ }
+
+#if EnableFSMouseMotion
+ if (HaveMouseMotion) {
+ MyMouseConstrain();
+ }
+#endif
+
+ if (RequestMacOff) {
+ RequestMacOff = falseblnr;
+ if (AnyDiskInserted()) {
+ MacMsgOverride(kStrQuitWarningTitle,
+ kStrQuitWarningMessage);
+ } else {
+ ForceMacOff = trueblnr;
+ }
+ }
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (gTrueBackgroundFlag != gBackgroundFlag) {
+ gBackgroundFlag = gTrueBackgroundFlag;
+ if (gTrueBackgroundFlag) {
+ EnterBackground();
+ } else {
+ LeaveBackground();
+ }
+ }
+
+ if (CurSpeedStopped != (SpeedStopped ||
+ (gBackgroundFlag && ! RunInBackground
+#if EnableAutoSlow && 0
+ && (QuietSubTicks >= 4092)
+#endif
+ )))
+ {
+ CurSpeedStopped = ! CurSpeedStopped;
+ if (CurSpeedStopped) {
+ EnterSpeedStopped();
+ } else {
+ LeaveSpeedStopped();
+ }
+ }
+
+ if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) {
+ MacMsgDisplayOn();
+ }
+
+#if EnableRecreateW
+ if (0
+#if EnableMagnify
+ || (UseMagnify != WantMagnify)
+#endif
+#if VarFullScreen
+ || (UseFullScreen != WantFullScreen)
+#endif
+ )
+ {
+ (void) ReCreateMainWindow();
+ }
+#endif
+
+#if MayFullScreen
+ if (GrabMachine != (
+#if VarFullScreen
+ UseFullScreen &&
+#endif
+ ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ GrabMachine = ! GrabMachine;
+ if (GrabMachine) {
+ GrabTheMachine();
+ } else {
+ UngrabMachine();
+ }
+ }
+#endif
+
+ if (NeedWholeScreenDraw) {
+ NeedWholeScreenDraw = falseblnr;
+ ScreenChangedAll();
+ }
+
+#if NeedRequestIthDisk
+ if (0 != RequestIthDisk) {
+ Sony_InsertIth(RequestIthDisk);
+ RequestIthDisk = 0;
+ }
+#endif
+
+ if (HaveCursorHidden != (WantCursorHidden
+ && ! (gTrueBackgroundFlag || CurSpeedStopped)))
+ {
+ HaveCursorHidden = ! HaveCursorHidden;
+ //FIXME setcursor(mctl, HaveCursorHidden ? &emptycursor : nil);
+ }
+}
+
+/* --- command line parsing --- */
+
+LOCALFUNC blnr ScanCommandLine(void)
+{
+ char *pa;
+ int i = 1;
+
+label_retry:
+ if (i < my_argc) {
+ pa = my_argv[i++];
+ if ('-' == pa[0]) {
+ if ((0 == strcmp(pa, "--rom"))
+ || (0 == strcmp(pa, "-r")))
+ {
+ if (i < my_argc) {
+ rom_path = my_argv[i++];
+ goto label_retry;
+ }
+ } else
+ {
+ MacMsg(kStrBadArgTitle, kStrBadArgMessage, falseblnr);
+ }
+ } else {
+ (void) Sony_Insert1(pa, falseblnr);
+ goto label_retry;
+ }
+ }
+
+ return trueblnr;
+}
+
+/* --- main program flow --- */
+
+GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void)
+{
+ UpdateTrueEmulatedTime();
+ return TrueEmulatedTime == OnTrueTime;
+}
+
+LOCALPROC WaitForTheNextEvent(void)
+{
+ switch (alt(a)) {
+ case -1:
+ //threadexitsall(nil);
+
+ case Cmouse:
+ MousePositionNotify(mouse.xy.x-screen->r.min.x-(Dx(screen->r)-Dx(my_surface->r))/2, mouse.xy.y-screen->r.min.y-(Dx(screen->r)-Dx(my_surface->r))/2);
+ MyMouseButtonSet(mouse.buttons & 1);
+ break;
+
+ case Cresize:
+ if(getwindow(display, Refnone) < 0)
+ sysfatal("getwindow: %r");
+ break;
+ }
+}
+
+GLOBALOSGLUPROC WaitForNextTick(void)
+{
+label_retry:
+ CheckForSavedTasks();
+
+ if (ForceMacOff) {
+ return;
+ }
+
+ if (1) {//CurSpeedStopped) {
+ DoneWithDrawingForTick();
+ WaitForTheNextEvent();
+ if (CurSpeedStopped)
+ goto label_retry;
+ }
+
+ if (ExtraTimeNotOver()) {
+ sleep(NextIntTime - LastTime); /* FIXME do a better job like in orca */
+ goto label_retry;
+ }
+
+ if (CheckDateTime()) {
+#if EnableDemoMsg
+ DemoModeSecondNotify();
+#endif
+ }
+
+ OnTrueTime = TrueEmulatedTime;
+
+#if dbglog_TimeStuff
+ dbglog_writelnNum("WaitForNextTick, OnTrueTime", OnTrueTime);
+#endif
+}
+
+/* --- platform independent code can be thought of as going here --- */
+
+#include "PROGMAIN.h"
+
+LOCALPROC ZapOSGLUVars(void)
+{
+ InitDrives();
+ ZapWinStateVars();
+}
+
+LOCALPROC ReserveAllocAll(void)
+{
+#if dbglog_HAVE
+ dbglog_ReserveAlloc();
+#endif
+ ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr);
+
+ ReserveAllocOneBlock(&screencomparebuff,
+ vMacScreenNumBytes, 5, trueblnr);
+#if UseControlKeys
+ ReserveAllocOneBlock(&CntrlDisplayBuff,
+ vMacScreenNumBytes, 5, falseblnr);
+#endif
+
+ ReserveAllocOneBlock(&CLUT_final, CLUT_finalsz, 5, falseblnr);
+
+ EmulationReserveAlloc();
+}
+
+LOCALFUNC blnr AllocMyMemory(void)
+{
+ uimr n;
+ blnr IsOk = falseblnr;
+
+ ReserveAllocOffset = 0;
+ ReserveAllocBigBlock = nullpr;
+ ReserveAllocAll();
+ n = ReserveAllocOffset;
+ ReserveAllocBigBlock = (ui3p)calloc(1, n);
+ if (NULL == ReserveAllocBigBlock) {
+ MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr);
+ } else {
+ ReserveAllocOffset = 0;
+ ReserveAllocAll();
+ if (n != ReserveAllocOffset) {
+ /* oops, program error */
+ } else {
+ IsOk = trueblnr;
+ }
+ }
+
+ return IsOk;
+}
+
+LOCALPROC UnallocMyMemory(void)
+{
+ if (nullpr != ReserveAllocBigBlock) {
+ free((char *)ReserveAllocBigBlock);
+ }
+}
+
+LOCALFUNC blnr InitOSGLU(void)
+{
+ if (AllocMyMemory())
+#if dbglog_HAVE
+ if (dbglog_open())
+#endif
+ if (ScanCommandLine())
+ if (LoadMacRom())
+ if (LoadInitialImages())
+ if (InitLocationDat())
+ if (MySound_Init())
+ if (Screen_Init())
+ if (CreateMainWindow())
+ if (WaitForRom())
+ {
+ return trueblnr;
+ }
+ return falseblnr;
+}
+
+LOCALPROC UnInitOSGLU(void)
+{
+ if (MacMsgDisplayed) {
+ MacMsgDisplayOff();
+ }
+
+ RestoreKeyRepeat();
+#if MayFullScreen
+ UngrabMachine();
+#endif
+#if IncludePbufs
+ UnInitPbufs();
+#endif
+ UnInitDrives();
+
+ ForceShowCursor();
+
+#if dbglog_HAVE
+ dbglog_close();
+#endif
+
+ UnallocMyMemory();
+
+ CheckSavedMacMsg();
+}
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEexport(tPbuf i)
+{
+ return mnvm_miscErr;
+}
+#endif
+
+#if IncludeHostTextClipExchange
+GLOBALOSGLUFUNC tMacErr HTCEimport(tPbuf *r)
+{
+ return mnvm_miscErr;
+}
+#endif
+
+void
+threadmain(int argc, char **argv)
+{
+ my_argc = argc;
+ my_argv = argv;
+
+ ZapOSGLUVars();
+ if (InitOSGLU()) {
+ ProgramMain();
+ }
+ UnInitOSGLU();
+
+ threadexitsall(nil);
+}
--- /dev/null
+++ b/src/PBUFSTDC.h
@@ -1,0 +1,121 @@
+/*
+ PBUFSTDC.h
+
+ Copyright (C) 2018 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Parameter BUFfers implemented with STanDard C library
+*/
+
+
+#if IncludePbufs
+LOCALVAR void *PbufDat[NumPbufs];
+#endif
+
+#if IncludePbufs
+LOCALFUNC tMacErr PbufNewFromPtr(void *p, ui5b count, tPbuf *r)
+{
+ tPbuf i;
+ tMacErr err;
+
+ if (! FirstFreePbuf(&i)) {
+ free(p);
+ err = mnvm_miscErr;
+ } else {
+ *r = i;
+ PbufDat[i] = p;
+ PbufNewNotify(i, count);
+ err = mnvm_noErr;
+ }
+
+ return err;
+}
+#endif
+
+#if IncludePbufs
+LOCALPROC PbufKillToPtr(void **p, ui5r *count, tPbuf r)
+{
+ *p = PbufDat[r];
+ *count = PbufSize[r];
+
+ PbufDisposeNotify(r);
+}
+#endif
+
+#if IncludePbufs
+GLOBALOSGLUFUNC tMacErr PbufNew(ui5b count, tPbuf *r)
+{
+ tMacErr err = mnvm_miscErr;
+
+ void *p = calloc(1, count);
+ if (NULL != p) {
+ err = PbufNewFromPtr(p, count, r);
+ }
+
+ return err;
+}
+#endif
+
+#if IncludePbufs
+GLOBALOSGLUPROC PbufDispose(tPbuf i)
+{
+ void *p;
+ ui5r count;
+
+ PbufKillToPtr(&p, &count, i);
+
+ free(p);
+}
+#endif
+
+#if IncludePbufs
+LOCALPROC UnInitPbufs(void)
+{
+ tPbuf i;
+
+ for (i = 0; i < NumPbufs; ++i) {
+ if (PbufIsAllocated(i)) {
+ PbufDispose(i);
+ }
+ }
+}
+#endif
+
+#if IncludePbufs
+#define PbufHaveLock 1
+#endif
+
+#if IncludePbufs
+LOCALFUNC ui3p PbufLock(tPbuf i)
+{
+ return (ui3p)PbufDat[i];
+}
+#endif
+
+#if IncludePbufs
+#define PbufUnlock(i)
+#endif
+
+#if IncludePbufs
+GLOBALOSGLUPROC PbufTransfer(ui3p Buffer,
+ tPbuf i, ui5r offset, ui5r count, blnr IsWrite)
+{
+ void *p = ((ui3p)PbufDat[i]) + offset;
+ if (IsWrite) {
+ (void) memcpy(p, Buffer, count);
+ } else {
+ (void) memcpy(Buffer, p, count);
+ }
+}
+#endif
--- /dev/null
+++ b/src/PMUEMDEV.c
@@ -1,0 +1,442 @@
+/*
+ PMUEMDEV.c
+
+ Copyright (C) 2008 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Power Management Unit EMulated DEVice
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+#include "MYOSGLUE.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#include "VIAEMDEV.h"
+#endif
+
+#include "PMUEMDEV.h"
+
+/*
+ ReportAbnormalID unused 0x0E0E - 0x0EFF
+*/
+
+enum {
+ kPMUStateReadyForCommand,
+ kPMUStateRecievingLength,
+ kPMUStateRecievingBuffer,
+ kPMUStateRecievedCommand,
+ kPMUStateSendLength,
+ kPMUStateSendBuffer,
+
+ kPMUStates
+};
+
+#define PMU_BuffSz 8
+LOCALVAR ui3b PMU_BuffA[PMU_BuffSz];
+LOCALVAR ui3p PMU_p;
+LOCALVAR ui3r PMU_rem;
+LOCALVAR ui3r PMU_i;
+
+LOCALVAR int PMUState = kPMUStateReadyForCommand;
+
+LOCALVAR ui3r PMU_CurCommand;
+LOCALVAR ui3r PMU_SendNext;
+LOCALVAR ui3r PMU_BuffL;
+
+LOCALPROC PmuStartSendResult(ui3r ResultCode, ui3r L)
+{
+ PMU_SendNext = ResultCode;
+ PMU_BuffL = L;
+ PMUState = kPMUStateSendLength;
+}
+
+LOCALVAR ui3b PARAMRAM[128];
+
+LOCALPROC PmuCheckCommandOp(void)
+{
+ switch (PMU_CurCommand) {
+ case 0x10: /* kPMUpowerCntl - power plane/clock control */
+ break;
+ case 0x32: /* kPMUxPramWrite - write extended PRAM byte(s) */
+ if (kPMUStateRecievingBuffer == PMUState) {
+ if (0 == PMU_i) {
+ if (PMU_BuffL >= 2) {
+ PMU_p = PMU_BuffA;
+ PMU_rem = 2;
+ } else {
+ ReportAbnormalID(0x0E01,
+ "PMU_BuffL too small for kPMUxPramWrite");
+ }
+ } else if (2 == PMU_i) {
+ if ((PMU_BuffA[1] + 2 == PMU_BuffL)
+ && (PMU_BuffA[0] + PMU_BuffA[1] <= 0x80))
+ {
+ PMU_p = &PARAMRAM[PMU_BuffA[0]];
+ PMU_rem = PMU_BuffA[1];
+ } else {
+ ReportAbnormalID(0x0E02,
+ "bad range for kPMUxPramWrite");
+ }
+ } else {
+ ReportAbnormalID(0x0E03,
+ "Wrong PMU_i for kPMUpramWrite");
+ }
+ } else if (kPMUStateRecievedCommand == PMUState) {
+ /* already done */
+ }
+ break;
+#if 0
+ case 0xE2: /* kPMUdownloadStatus - PRAM status */
+ break;
+#endif
+ case 0xE0: /* kPMUwritePmgrRAM - write to internal PMGR RAM */
+ break;
+ case 0x21: /* kPMUpMgrADBoff - turn ADB auto-poll off */
+ if (kPMUStateRecievedCommand == PMUState) {
+ if (0 != PMU_BuffL) {
+ ReportAbnormalID(0x0E04,
+ "kPMUpMgrADBoff nonzero length");
+ }
+ }
+ break;
+ case 0xEC: /* kPMUPmgrSelfTest - run the PMGR selftest */
+ if (kPMUStateRecievedCommand == PMUState) {
+ PmuStartSendResult(0, 0);
+ }
+ break;
+ case 0x78:
+ /* kPMUreadINT - get PMGR interrupt data */
+ case 0x68:
+ /*
+ kPMUbatteryRead - read battery/charger level and status
+ */
+ case 0x7F:
+ /*
+ kPMUsleepReq - put the system to sleep (sleepSig='MATT')
+ */
+ if (kPMUStateRecievedCommand == PMUState) {
+ PMU_BuffA[0] = 0;
+ PmuStartSendResult(0, 1);
+ }
+ break;
+ case 0xE8: /* kPMUreadPmgrRAM - read from internal PMGR RAM */
+ if (kPMUStateRecievedCommand == PMUState) {
+ if ((3 == PMU_BuffL)
+ && (0 == PMU_BuffA[0])
+ && (0xEE == PMU_BuffA[1])
+ && (1 == PMU_BuffA[2]))
+ {
+ PMU_BuffA[0] = 1 << 5;
+ PmuStartSendResult(0, 1);
+ } else {
+ PMU_BuffA[0] = 0;
+ PmuStartSendResult(0, 1);
+ /* ReportAbnormal("Unknown kPMUreadPmgrRAM op"); */
+ }
+ }
+ break;
+ case 0x3A: /* kPMUxPramRead - read extended PRAM byte(s) */
+ if (kPMUStateRecievedCommand == PMUState) {
+ if ((2 == PMU_BuffL)
+ && (PMU_BuffA[0] + PMU_BuffA[1] <= 0x80))
+ {
+ PMU_p = &PARAMRAM[PMU_BuffA[0]];
+ PMU_rem = PMU_BuffA[1];
+ PmuStartSendResult(0, PMU_rem);
+ } else {
+ ReportAbnormalID(0x0E05,
+ "Unknown kPMUxPramRead op");
+ }
+ }
+ break;
+ case 0x38:
+ /* kPMUtimeRead - read the time from the clock chip */
+ if (kPMUStateRecievedCommand == PMUState) {
+ if (0 == PMU_BuffL) {
+ PMU_BuffA[0] = 0;
+ PMU_BuffA[1] = 0;
+ PMU_BuffA[2] = 0;
+ PMU_BuffA[3] = 0;
+ PmuStartSendResult(0, 4);
+ } else {
+ ReportAbnormalID(0x0E06, "Unknown kPMUtimeRead op");
+ }
+ }
+ break;
+ case 0x31:
+ /*
+ kPMUpramWrite - write the original 20 bytes of PRAM
+ (Portable only)
+ */
+ if (kPMUStateRecievedCommand == PMUState) {
+ if (20 == PMU_BuffL) {
+ /* done */
+ } else {
+ ReportAbnormalID(0x0E07,
+ "Unknown kPMUpramWrite op");
+ }
+ } else if (kPMUStateRecievingBuffer == PMUState) {
+ if (20 == PMU_BuffL) {
+ if (0 == PMU_i) {
+ PMU_p = &PARAMRAM[16];
+ PMU_rem = 16;
+ } else if (16 == PMU_i) {
+ PMU_p = &PARAMRAM[8];
+ PMU_rem = 4;
+ } else {
+ ReportAbnormalID(0x0E08,
+ "Wrong PMU_i for kPMUpramWrite");
+ }
+ }
+ }
+ break;
+ case 0x39:
+ /*
+ kPMUpramRead - read the original 20 bytes of PRAM
+ (Portable only)
+ */
+ if (kPMUStateRecievedCommand == PMUState) {
+ if (0 == PMU_BuffL) {
+ PmuStartSendResult(0, 20);
+ } else {
+ ReportAbnormalID(0x0E09, "Unknown kPMUpramRead op");
+ }
+ } else if (kPMUStateSendBuffer == PMUState) {
+#if 0
+ {
+ int i;
+
+ for (i = 0; i < PMU_BuffSz; ++i) {
+ PMU_BuffA[i] = 0;
+ }
+ }
+#endif
+ if (0 == PMU_i) {
+ PMU_p = &PARAMRAM[16];
+ PMU_rem = 16;
+ } else if (16 == PMU_i) {
+ PMU_p = &PARAMRAM[8];
+ PMU_rem = 4;
+ } else {
+ ReportAbnormalID(0x0E0A,
+ "Wrong PMU_i for kPMUpramRead");
+ }
+ }
+ break;
+ default:
+ if (kPMUStateRecievedCommand == PMUState) {
+ ReportAbnormalID(0x0E0B, "Unknown PMU op");
+#if dbglog_HAVE
+ dbglog_writeCStr("Unknown PMU op ");
+ dbglog_writeHex(PMU_CurCommand);
+ dbglog_writeReturn();
+ dbglog_writeCStr("PMU_BuffL = ");
+ dbglog_writeHex(PMU_BuffL);
+ dbglog_writeReturn();
+ if (PMU_BuffL <= PMU_BuffSz) {
+ int i;
+
+ for (i = 0; i < PMU_BuffL; ++i) {
+ dbglog_writeCStr("PMU_BuffA[");
+ dbglog_writeNum(i);
+ dbglog_writeCStr("] = ");
+ dbglog_writeHex(PMU_BuffA[i]);
+ dbglog_writeReturn();
+ }
+ }
+#endif
+ }
+ break;
+ }
+}
+
+LOCALPROC LocBuffSetUpNextChunk(void)
+{
+ PMU_p = PMU_BuffA;
+ PMU_rem = PMU_BuffL - PMU_i;
+ if (PMU_rem >= PMU_BuffSz) {
+ PMU_rem = PMU_BuffSz;
+ }
+}
+
+LOCALFUNC ui3r GetPMUbus(void)
+{
+ ui3r v;
+
+ v = VIA1_iA7;
+ v <<= 1;
+ v |= VIA1_iA6;
+ v <<= 1;
+ v |= VIA1_iA5;
+ v <<= 1;
+ v |= VIA1_iA4;
+ v <<= 1;
+ v |= VIA1_iA3;
+ v <<= 1;
+ v |= VIA1_iA2;
+ v <<= 1;
+ v |= VIA1_iA1;
+ v <<= 1;
+ v |= VIA1_iA0;
+
+ return v;
+}
+
+LOCALPROC SetPMUbus(ui3r v)
+{
+ VIA1_iA0 = v & 0x01;
+ v >>= 1;
+ VIA1_iA1 = v & 0x01;
+ v >>= 1;
+ VIA1_iA2 = v & 0x01;
+ v >>= 1;
+ VIA1_iA3 = v & 0x01;
+ v >>= 1;
+ VIA1_iA4 = v & 0x01;
+ v >>= 1;
+ VIA1_iA5 = v & 0x01;
+ v >>= 1;
+ VIA1_iA6 = v & 0x01;
+ v >>= 1;
+ VIA1_iA7 = v & 0x01;
+}
+
+LOCALVAR blnr PMU_Sending = falseblnr;
+
+LOCALPROC PmuCheckCommandCompletion(void)
+{
+ if (PMU_i == PMU_BuffL) {
+ PMUState = kPMUStateRecievedCommand;
+ PmuCheckCommandOp();
+ if ((PMU_CurCommand & 0x08) == 0) {
+ PMUState = kPMUStateReadyForCommand;
+ SetPMUbus(0xFF);
+ } else {
+ if (PMUState != kPMUStateSendLength) {
+ PmuStartSendResult(0xFF, 0);
+ PMUState = kPMUStateSendLength;
+ }
+ PMU_i = 0;
+ PMU_Sending = trueblnr;
+ ICT_add(kICT_PMU_Task,
+ 20400UL * kCycleScale / 64 * kMyClockMult);
+ }
+ }
+}
+
+GLOBALPROC PmuToReady_ChangeNtfy(void)
+{
+ if (PMU_Sending) {
+ PMU_Sending = falseblnr;
+ ReportAbnormalID(0x0E0C,
+ "PmuToReady_ChangeNtfy while PMU_Sending");
+ PmuFromReady = 0;
+ }
+ switch (PMUState) {
+ case kPMUStateReadyForCommand:
+ if (! PmuToReady) {
+ PmuFromReady = 0;
+ } else {
+ PMU_CurCommand = GetPMUbus();
+ PMUState = kPMUStateRecievingLength;
+ PmuFromReady = 1;
+ }
+ break;
+ case kPMUStateRecievingLength:
+ if (! PmuToReady) {
+ PmuFromReady = 0;
+ } else {
+ PMU_BuffL = GetPMUbus();
+ PMU_i = 0;
+ PMU_rem = 0;
+ PMUState = kPMUStateRecievingBuffer;
+ PmuCheckCommandCompletion();
+ PmuFromReady = 1;
+ }
+ break;
+ case kPMUStateRecievingBuffer:
+ if (! PmuToReady) {
+ PmuFromReady = 0;
+ } else {
+ ui3r v = GetPMUbus();
+ if (0 == PMU_rem) {
+ PMU_p = nullpr;
+ PmuCheckCommandOp();
+ if (nullpr == PMU_p) {
+ /* default handler */
+ LocBuffSetUpNextChunk();
+ }
+ }
+ if (nullpr == PMU_p) {
+ /* mini vmac bug if ever happens */
+ ReportAbnormalID(0x0E0D,
+ "PMU_p null while kPMUStateRecievingBuffer");
+ }
+ *PMU_p++ = v;
+ --PMU_rem;
+ ++PMU_i;
+ PmuCheckCommandCompletion();
+ PmuFromReady = 1;
+ }
+ break;
+ case kPMUStateSendLength:
+ if (! PmuToReady) {
+ /* receiving */
+ PmuFromReady = 1;
+ } else {
+ PMU_SendNext = PMU_BuffL;
+ PMUState = kPMUStateSendBuffer;
+ PMU_Sending = trueblnr;
+ ICT_add(kICT_PMU_Task,
+ 20400UL * kCycleScale / 64 * kMyClockMult);
+ }
+ break;
+ case kPMUStateSendBuffer:
+ if (! PmuToReady) {
+ /* receiving */
+ PmuFromReady = 1;
+ } else {
+ if (PMU_i == PMU_BuffL) {
+ PMUState = kPMUStateReadyForCommand;
+ SetPMUbus(0xFF);
+ } else {
+ if (0 == PMU_rem) {
+ PMU_p = nullpr;
+ PmuCheckCommandOp();
+ if (nullpr == PMU_p) {
+ /* default handler */
+ LocBuffSetUpNextChunk();
+ }
+ }
+ PMU_SendNext = *PMU_p++;
+ --PMU_rem;
+ ++PMU_i;
+ PMU_Sending = trueblnr;
+ ICT_add(kICT_PMU_Task,
+ 20400UL * kCycleScale / 64 * kMyClockMult);
+ }
+ }
+ break;
+ }
+}
+
+GLOBALPROC PMU_DoTask(void)
+{
+ if (PMU_Sending) {
+ PMU_Sending = falseblnr;
+ SetPMUbus(PMU_SendNext);
+ PmuFromReady = 0;
+ }
+}
--- /dev/null
+++ b/src/PMUEMDEV.h
@@ -1,0 +1,24 @@
+/*
+ PMUEMDEV.h
+
+ Copyright (C) 2008 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef PMUEMDEV_H
+#error "header already included"
+#else
+#define PMUEMDEV_H
+#endif
+
+EXPORTPROC PmuToReady_ChangeNtfy(void);
+EXPORTPROC PMU_DoTask(void);
--- /dev/null
+++ b/src/PROGMAIN.c
@@ -1,0 +1,562 @@
+/*
+ PROGMAIN.c
+
+ Copyright (C) 2009 Bernd Schmidt, Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ PROGram MAIN.
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+
+#include "MYOSGLUE.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#include "M68KITAB.h"
+#include "MINEM68K.h"
+#include "VIAEMDEV.h"
+#if EmVIA2
+#include "VIA2EMDV.h"
+#endif
+#include "IWMEMDEV.h"
+#include "SCCEMDEV.h"
+#if EmRTC
+#include "RTCEMDEV.h"
+#endif
+#include "ROMEMDEV.h"
+#include "SCSIEMDV.h"
+#include "SONYEMDV.h"
+#include "SCRNEMDV.h"
+#if EmVidCard
+#include "VIDEMDEV.h"
+#endif
+#if EmClassicKbrd
+#include "KBRDEMDV.h"
+#elif EmPMU
+#include "PMUEMDEV.h"
+#else
+#include "ADBEMDEV.h"
+#endif
+#if EmASC
+#include "ASCEMDEV.h"
+#else
+#if MySoundEnabled && (CurEmMd != kEmMd_PB100)
+#include "SNDEMDEV.h"
+#endif
+#endif
+#include "MOUSEMDV.h"
+#endif
+
+
+#include "PROGMAIN.h"
+
+/*
+ ReportAbnormalID unused 0x1002 - 0x10FF
+*/
+
+LOCALPROC EmulatedHardwareZap(void)
+{
+ Memory_Reset();
+ ICT_Zap();
+ IWM_Reset();
+ SCC_Reset();
+ SCSI_Reset();
+ VIA1_Zap();
+#if EmVIA2
+ VIA2_Zap();
+#endif
+ Sony_Reset();
+ Extn_Reset();
+ m68k_reset();
+}
+
+LOCALPROC DoMacReset(void)
+{
+ Sony_EjectAllDisks();
+ EmulatedHardwareZap();
+}
+
+LOCALPROC InterruptReset_Update(void)
+{
+ SetInterruptButton(falseblnr);
+ /*
+ in case has been set. so only stays set
+ for 60th of a second.
+ */
+
+ if (WantMacInterrupt) {
+ SetInterruptButton(trueblnr);
+ WantMacInterrupt = falseblnr;
+ }
+ if (WantMacReset) {
+ DoMacReset();
+ WantMacReset = falseblnr;
+ }
+}
+
+LOCALPROC SubTickNotify(int SubTick)
+{
+#if 0
+ dbglog_writeCStr("ending sub tick ");
+ dbglog_writeNum(SubTick);
+ dbglog_writeReturn();
+#endif
+#if EmASC
+ ASC_SubTick(SubTick);
+#else
+#if MySoundEnabled && (CurEmMd != kEmMd_PB100)
+ MacSound_SubTick(SubTick);
+#else
+ UnusedParam(SubTick);
+#endif
+#endif
+}
+
+#define CyclesScaledPerTick (130240UL * kMyClockMult * kCycleScale)
+#define CyclesScaledPerSubTick (CyclesScaledPerTick / kNumSubTicks)
+
+LOCALVAR ui4r SubTickCounter;
+
+LOCALPROC SubTickTaskDo(void)
+{
+ SubTickNotify(SubTickCounter);
+ ++SubTickCounter;
+ if (SubTickCounter < (kNumSubTicks - 1)) {
+ /*
+ final SubTick handled by SubTickTaskEnd,
+ since CyclesScaledPerSubTick * kNumSubTicks
+ might not equal CyclesScaledPerTick.
+ */
+
+ ICT_add(kICT_SubTick, CyclesScaledPerSubTick);
+ }
+}
+
+LOCALPROC SubTickTaskStart(void)
+{
+ SubTickCounter = 0;
+ ICT_add(kICT_SubTick, CyclesScaledPerSubTick);
+}
+
+LOCALPROC SubTickTaskEnd(void)
+{
+ SubTickNotify(kNumSubTicks - 1);
+}
+
+LOCALPROC SixtiethSecondNotify(void)
+{
+#if dbglog_HAVE && 0
+ dbglog_WriteNote("begin new Sixtieth");
+#endif
+ Mouse_Update();
+ InterruptReset_Update();
+#if EmClassicKbrd
+ KeyBoard_Update();
+#endif
+#if EmADB
+ ADB_Update();
+#endif
+
+ Sixtieth_PulseNtfy(); /* Vertical Blanking Interrupt */
+ Sony_Update();
+
+#if EmLocalTalk
+ LocalTalkTick();
+#endif
+#if EmRTC
+ RTC_Interrupt();
+#endif
+#if EmVidCard
+ Vid_Update();
+#endif
+
+ SubTickTaskStart();
+}
+
+LOCALPROC SixtiethEndNotify(void)
+{
+ SubTickTaskEnd();
+ Mouse_EndTickNotify();
+ Screen_EndTickNotify();
+#if dbglog_HAVE && 0
+ dbglog_WriteNote("end Sixtieth");
+#endif
+}
+
+LOCALPROC ExtraTimeBeginNotify(void)
+{
+#if 0
+ dbglog_writeCStr("begin extra time");
+ dbglog_writeReturn();
+#endif
+ VIA1_ExtraTimeBegin();
+#if EmVIA2
+ VIA2_ExtraTimeBegin();
+#endif
+}
+
+LOCALPROC ExtraTimeEndNotify(void)
+{
+ VIA1_ExtraTimeEnd();
+#if EmVIA2
+ VIA2_ExtraTimeEnd();
+#endif
+#if 0
+ dbglog_writeCStr("end extra time");
+ dbglog_writeReturn();
+#endif
+}
+
+GLOBALPROC EmulationReserveAlloc(void)
+{
+ ReserveAllocOneBlock(&RAM,
+ kRAM_Size + RAMSafetyMarginFudge, 5, falseblnr);
+#if EmVidCard
+ ReserveAllocOneBlock(&VidROM, kVidROM_Size, 5, falseblnr);
+#endif
+#if IncludeVidMem
+ ReserveAllocOneBlock(&VidMem,
+ kVidMemRAM_Size + RAMSafetyMarginFudge, 5, trueblnr);
+#endif
+#if SmallGlobals
+ MINEM68K_ReserveAlloc();
+#endif
+}
+
+LOCALFUNC blnr InitEmulation(void)
+{
+#if EmRTC
+ if (RTC_Init())
+#endif
+ if (ROM_Init())
+#if EmVidCard
+ if (Vid_Init())
+#endif
+ if (AddrSpac_Init())
+ {
+ EmulatedHardwareZap();
+ return trueblnr;
+ }
+ return falseblnr;
+}
+
+LOCALPROC ICT_DoTask(int taskid)
+{
+ switch (taskid) {
+ case kICT_SubTick:
+ SubTickTaskDo();
+ break;
+#if EmClassicKbrd
+ case kICT_Kybd_ReceiveEndCommand:
+ DoKybd_ReceiveEndCommand();
+ break;
+ case kICT_Kybd_ReceiveCommand:
+ DoKybd_ReceiveCommand();
+ break;
+#endif
+#if EmADB
+ case kICT_ADB_NewState:
+ ADB_DoNewState();
+ break;
+#endif
+#if EmPMU
+ case kICT_PMU_Task:
+ PMU_DoTask();
+ break;
+#endif
+ case kICT_VIA1_Timer1Check:
+ VIA1_DoTimer1Check();
+ break;
+ case kICT_VIA1_Timer2Check:
+ VIA1_DoTimer2Check();
+ break;
+#if EmVIA2
+ case kICT_VIA2_Timer1Check:
+ VIA2_DoTimer1Check();
+ break;
+ case kICT_VIA2_Timer2Check:
+ VIA2_DoTimer2Check();
+ break;
+#endif
+ default:
+ ReportAbnormalID(0x1001, "unknown taskid in ICT_DoTask");
+ break;
+ }
+}
+
+LOCALPROC ICT_DoCurrentTasks(void)
+{
+ int i = 0;
+ uimr m = ICTactive;
+
+ while (0 != m) {
+ if (0 != (m & 1)) {
+ if (i >= kNumICTs) {
+ /* shouldn't happen */
+ ICTactive &= ((1 << kNumICTs) - 1);
+ m = 0;
+ } else if (ICTwhen[i] == NextiCount) {
+ ICTactive &= ~ (1 << i);
+#ifdef _VIA_Debug
+ fprintf(stderr, "doing task %d, %d\n", NextiCount, i);
+#endif
+ ICT_DoTask(i);
+
+ /*
+ A Task may set the time of
+ any task, including itself.
+ But it cannot set any task
+ to execute immediately, so
+ one pass is sufficient.
+ */
+ }
+ }
+ ++i;
+ m >>= 1;
+ }
+}
+
+LOCALFUNC ui5b ICT_DoGetNext(ui5b maxn)
+{
+ int i = 0;
+ uimr m = ICTactive;
+ ui5b v = maxn;
+
+ while (0 != m) {
+ if (0 != (m & 1)) {
+ if (i >= kNumICTs) {
+ /* shouldn't happen */
+ m = 0;
+ } else {
+ ui5b d = ICTwhen[i] - NextiCount;
+ /* at this point d must be > 0 */
+ if (d < v) {
+#ifdef _VIA_Debug
+ fprintf(stderr, "coming task %d, %d, %d\n",
+ NextiCount, i, d);
+#endif
+ v = d;
+ }
+ }
+ }
+ ++i;
+ m >>= 1;
+ }
+
+ return v;
+}
+
+LOCALPROC m68k_go_nCycles_1(ui5b n)
+{
+ ui5b n2;
+ ui5b StopiCount = NextiCount + n;
+ do {
+ ICT_DoCurrentTasks();
+ n2 = ICT_DoGetNext(n);
+#if dbglog_HAVE && 0
+ dbglog_StartLine();
+ dbglog_writeCStr("before m68k_go_nCycles, NextiCount:");
+ dbglog_writeHex(NextiCount);
+ dbglog_writeCStr(", n2:");
+ dbglog_writeHex(n2);
+ dbglog_writeCStr(", n:");
+ dbglog_writeHex(n);
+ dbglog_writeReturn();
+#endif
+ NextiCount += n2;
+ m68k_go_nCycles(n2);
+ n = StopiCount - NextiCount;
+ } while (n != 0);
+}
+
+LOCALVAR ui5b ExtraSubTicksToDo = 0;
+
+LOCALPROC DoEmulateOneTick(void)
+{
+#if EnableAutoSlow
+ {
+ ui5r NewQuietTime = QuietTime + 1;
+
+ if (NewQuietTime > QuietTime) {
+ /* if not overflow */
+ QuietTime = NewQuietTime;
+ }
+ }
+#endif
+#if EnableAutoSlow
+ {
+ ui5r NewQuietSubTicks = QuietSubTicks + kNumSubTicks;
+
+ if (NewQuietSubTicks > QuietSubTicks) {
+ /* if not overflow */
+ QuietSubTicks = NewQuietSubTicks;
+ }
+ }
+#endif
+
+ SixtiethSecondNotify();
+
+ m68k_go_nCycles_1(CyclesScaledPerTick);
+
+ SixtiethEndNotify();
+
+ if ((ui3b) -1 == SpeedValue) {
+ ExtraSubTicksToDo = (ui5b) -1;
+ } else {
+ ui5b ExtraAdd = (kNumSubTicks << SpeedValue) - kNumSubTicks;
+ ui5b ExtraLimit = ExtraAdd << 3;
+
+ ExtraSubTicksToDo += ExtraAdd;
+ if (ExtraSubTicksToDo > ExtraLimit) {
+ ExtraSubTicksToDo = ExtraLimit;
+ }
+ }
+}
+
+LOCALFUNC blnr MoreSubTicksToDo(void)
+{
+ blnr v = falseblnr;
+
+ if (ExtraTimeNotOver() && (ExtraSubTicksToDo > 0)) {
+#if EnableAutoSlow
+ if ((QuietSubTicks >= 16384)
+ && (QuietTime >= 34)
+ && ! WantNotAutoSlow)
+ {
+ ExtraSubTicksToDo = 0;
+ } else
+#endif
+ {
+ v = trueblnr;
+ }
+ }
+
+ return v;
+}
+
+LOCALPROC DoEmulateExtraTime(void)
+{
+ /*
+ DoEmulateExtraTime is used for
+ anything over emulation speed
+ of 1x. It periodically calls
+ ExtraTimeNotOver and stops
+ when this returns false (or it
+ is finished with emulating the
+ extra time).
+ */
+
+ if (MoreSubTicksToDo()) {
+ ExtraTimeBeginNotify();
+ do {
+#if EnableAutoSlow
+ {
+ ui5r NewQuietSubTicks = QuietSubTicks + 1;
+
+ if (NewQuietSubTicks > QuietSubTicks) {
+ /* if not overflow */
+ QuietSubTicks = NewQuietSubTicks;
+ }
+ }
+#endif
+ m68k_go_nCycles_1(CyclesScaledPerSubTick);
+ --ExtraSubTicksToDo;
+ } while (MoreSubTicksToDo());
+ ExtraTimeEndNotify();
+ }
+}
+
+LOCALVAR ui5b CurEmulatedTime = 0;
+ /*
+ The number of ticks that have been
+ emulated so far.
+
+ That is, the number of times
+ "DoEmulateOneTick" has been called.
+ */
+
+LOCALPROC RunEmulatedTicksToTrueTime(void)
+{
+ /*
+ The general idea is to call DoEmulateOneTick
+ once per tick.
+
+ But if emulation is lagging, we'll try to
+ catch up by calling DoEmulateOneTick multiple
+ times, unless we're too far behind, in
+ which case we forget it.
+
+ If emulating one tick takes longer than
+ a tick we don't want to sit here
+ forever. So the maximum number of calls
+ to DoEmulateOneTick is determined at
+ the beginning, rather than just
+ calling DoEmulateOneTick until
+ CurEmulatedTime >= TrueEmulatedTime.
+ */
+
+ si3b n = OnTrueTime - CurEmulatedTime;
+
+ if (n > 0) {
+ DoEmulateOneTick();
+ ++CurEmulatedTime;
+
+ DoneWithDrawingForTick();
+
+ if (n > 8) {
+ /* emulation not fast enough */
+ n = 8;
+ CurEmulatedTime = OnTrueTime - n;
+ }
+
+ if (ExtraTimeNotOver() && (--n > 0)) {
+ /* lagging, catch up */
+
+ EmVideoDisable = trueblnr;
+
+ do {
+ DoEmulateOneTick();
+ ++CurEmulatedTime;
+ } while (ExtraTimeNotOver()
+ && (--n > 0));
+
+ EmVideoDisable = falseblnr;
+ }
+
+ EmLagTime = n;
+ }
+}
+
+LOCALPROC MainEventLoop(void)
+{
+ for (; ; ) {
+ WaitForNextTick();
+ if (ForceMacOff) {
+ return;
+ }
+
+ RunEmulatedTicksToTrueTime();
+
+ DoEmulateExtraTime();
+ }
+}
+
+GLOBALPROC ProgramMain(void)
+{
+ if (InitEmulation())
+ {
+ MainEventLoop();
+ }
+}
--- /dev/null
+++ b/src/PROGMAIN.h
@@ -1,0 +1,25 @@
+/*
+ PROGMAIN.h
+
+ Copyright (C) 2009 Philip Cummins, Richard F. Bannister,
+ Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef PROGMAIN_H
+#error "header already included"
+#else
+#define PROGMAIN_H
+#endif
+
+EXPORTPROC EmulationReserveAlloc(void);
+EXPORTPROC ProgramMain(void);
--- /dev/null
+++ b/src/ROMEMDEV.c
@@ -1,0 +1,332 @@
+/*
+ ROMEMDEV.c
+
+ Copyright (C) 2007 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Read Only Memory EMulated DEVice
+
+ Checks the header of the loaded ROM image, and then patches
+ the ROM image.
+
+ This code descended from "ROM.c" in vMac by Philip Cummins.
+
+ Support for "Twiggy" Mac by Mathew Hybler.
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+#include "MYOSGLUE.h"
+#include "ENDIANAC.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#endif
+
+#include "ROMEMDEV.h"
+
+#define UseSonyPatch \
+ ((CurEmMd <= kEmMd_Classic) || (CurEmMd == kEmMd_II) \
+ || (CurEmMd == kEmMd_IIx))
+
+#ifndef UseLargeScreenHack
+#define UseLargeScreenHack 0
+#endif
+
+#if UseSonyPatch
+LOCALVAR const ui3b sony_driver[] = {
+/*
+ Replacement for .Sony driver
+ 68k machine code, compiled from mydriver.a
+*/
+0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xEE, 0x00, 0x18, 0x00, 0x24, 0x00, 0x4A,
+0x00, 0x8A, 0x05, 0x2E, 0x53, 0x6F, 0x6E, 0x79,
+0x48, 0xE7, 0x00, 0xC0, 0x55, 0x4F, 0x3F, 0x3C,
+0x00, 0x01, 0x60, 0x30, 0x48, 0xE7, 0x00, 0xC0,
+0x55, 0x4F, 0x3F, 0x3C, 0x00, 0x02, 0x41, 0xFA,
+0x01, 0x84, 0x2F, 0x18, 0x20, 0x50, 0x20, 0x8F,
+0x5C, 0x4F, 0x30, 0x1F, 0x4C, 0xDF, 0x03, 0x00,
+0x0C, 0x68, 0x00, 0x01, 0x00, 0x1A, 0x66, 0x1E,
+0x4E, 0x75, 0x48, 0xE7, 0x00, 0xC0, 0x55, 0x4F,
+0x3F, 0x3C, 0x00, 0x03, 0x41, 0xFA, 0x01, 0x5E,
+0x2F, 0x18, 0x20, 0x50, 0x20, 0x8F, 0x5C, 0x4F,
+0x30, 0x1F, 0x4C, 0xDF, 0x03, 0x00, 0x32, 0x28,
+0x00, 0x06, 0x08, 0x01, 0x00, 0x09, 0x67, 0x0C,
+0x4A, 0x40, 0x6F, 0x02, 0x42, 0x40, 0x31, 0x40,
+0x00, 0x10, 0x4E, 0x75, 0x4A, 0x40, 0x6F, 0x04,
+0x42, 0x40, 0x4E, 0x75, 0x2F, 0x38, 0x08, 0xFC,
+0x4E, 0x75, 0x48, 0xE7, 0x00, 0xC0, 0x55, 0x4F,
+0x3F, 0x3C, 0x00, 0x04, 0x41, 0xFA, 0x01, 0x1E,
+0x2F, 0x18, 0x20, 0x50, 0x20, 0x8F, 0x5C, 0x4F,
+0x30, 0x1F, 0x4C, 0xDF, 0x03, 0x00, 0x4E, 0x75,
+0x48, 0xE7, 0xE0, 0xC0, 0x20, 0x2F, 0x00, 0x14,
+0x59, 0x4F, 0x2F, 0x00, 0x55, 0x4F, 0x3F, 0x3C,
+0x00, 0x08, 0x41, 0xFA, 0x00, 0xF8, 0x2F, 0x18,
+0x20, 0x50, 0x20, 0x8F, 0x5C, 0x4F, 0x32, 0x1F,
+0x58, 0x4F, 0x20, 0x1F, 0x4A, 0x41, 0x66, 0x06,
+0x30, 0x7C, 0x00, 0x07, 0xA0, 0x2F, 0x4C, 0xDF,
+0x03, 0x07, 0x58, 0x4F, 0x4E, 0x73, 0x21, 0x40,
+0x00, 0x06, 0x43, 0xF8, 0x03, 0x08, 0x4E, 0xF9,
+0x00, 0x40, 0x0B, 0x20, 0x4E, 0x75, 0x48, 0xE7,
+0x1F, 0x10, 0x48, 0xE7, 0x00, 0xC0, 0x5D, 0x4F,
+0x3F, 0x3C, 0x00, 0x05, 0x41, 0xFA, 0x00, 0xB6,
+0x2F, 0x18, 0x20, 0x50, 0x20, 0x8F, 0x5C, 0x4F,
+0x30, 0x1F, 0x2E, 0x1F, 0x0C, 0x40, 0xFF, 0xCF,
+0x66, 0x06, 0x42, 0x40, 0x60, 0x00, 0x00, 0x8E,
+0x4A, 0x40, 0x66, 0x00, 0x00, 0x88, 0x20, 0x07,
+0xA7, 0x1E, 0x26, 0x48, 0x20, 0x0B, 0x67, 0x00,
+0x00, 0x86, 0x9E, 0xFC, 0x00, 0x10, 0x2F, 0x0B,
+0x2F, 0x07, 0x55, 0x4F, 0x3F, 0x3C, 0x00, 0x06,
+0x41, 0xFA, 0x00, 0x7A, 0x2F, 0x18, 0x20, 0x50,
+0x20, 0x8F, 0x5C, 0x4F, 0x30, 0x1F, 0x50, 0x4F,
+0x2E, 0x1F, 0x76, 0x00, 0x36, 0x1F, 0x38, 0x1F,
+0x3C, 0x1F, 0x3A, 0x1F, 0x26, 0x5F, 0x4A, 0x40,
+0x66, 0x4A, 0x20, 0x0B, 0x67, 0x0E, 0x41, 0xFA,
+0xFF, 0x8C, 0x27, 0x48, 0x00, 0x06, 0x20, 0x4B,
+0xA0, 0x58, 0x60, 0x1A, 0x41, 0xFA, 0xFF, 0x70,
+0x30, 0x3C, 0xA0, 0x4E, 0xA0, 0x47, 0x60, 0x0E,
+0x20, 0x47, 0x30, 0x06, 0x48, 0x40, 0x30, 0x05,
+0xA0, 0x4E, 0xDE, 0x83, 0x52, 0x46, 0x51, 0xCC,
+0xFF, 0xF0, 0x48, 0x7A, 0xFF, 0x1C, 0x55, 0x4F,
+0x3F, 0x3C, 0x00, 0x07, 0x41, 0xFA, 0x00, 0x1E,
+0x2F, 0x18, 0x20, 0x50, 0x20, 0x8F, 0x5C, 0x4F,
+0x30, 0x1F, 0x58, 0x4F, 0x4C, 0xDF, 0x03, 0x00,
+0x4C, 0xDF, 0x08, 0xF8, 0x4E, 0x75, 0x30, 0x3C,
+0xFF, 0xFF, 0x60, 0xF0
+};
+#endif
+
+#if UseSonyPatch
+LOCALVAR const ui3b my_disk_icon[] = {
+ 0x7F, 0xFF, 0xFF, 0xF0,
+ 0x81, 0x00, 0x01, 0x08,
+ 0x81, 0x00, 0x71, 0x04,
+ 0x81, 0x00, 0x89, 0x02,
+ 0x81, 0x00, 0x89, 0x01,
+ 0x81, 0x00, 0x89, 0x01,
+ 0x81, 0x00, 0x89, 0x01,
+ 0x81, 0x00, 0x89, 0x01,
+ 0x81, 0x00, 0x89, 0x01,
+ 0x81, 0x00, 0x71, 0x01,
+ 0x81, 0x00, 0x01, 0x01,
+ 0x80, 0xFF, 0xFE, 0x01,
+ 0x80, 0x00, 0x00, 0x01,
+ 0x80, 0x00, 0x00, 0x01,
+ 0x80, 0x00, 0x00, 0x01,
+ 0x80, 0x00, 0x00, 0x01,
+ 0x83, 0xFF, 0xFF, 0xC1,
+ 0x84, 0x00, 0x00, 0x21,
+ 0x84, 0x00, 0x00, 0x21,
+ 0x84, 0x00, 0x00, 0x21,
+ 0x84, 0x00, 0x00, 0x21,
+ 0x84, 0x00, 0x00, 0x21,
+ 0x84, 0x06, 0x30, 0x21,
+ 0x84, 0x06, 0x60, 0x21,
+ 0x84, 0x06, 0xC0, 0x21,
+ 0x84, 0x07, 0x80, 0x21,
+ 0x84, 0x07, 0x00, 0x21,
+ 0x84, 0x06, 0x00, 0x21,
+ 0x84, 0x00, 0x00, 0x21,
+ 0x84, 0x00, 0x00, 0x21,
+ 0x84, 0x00, 0x00, 0x21,
+ 0x7F, 0xFF, 0xFF, 0xFE,
+
+ /* mask */
+
+ 0x3F, 0xFF, 0xFF, 0xF0,
+ 0x7F, 0xFF, 0xFF, 0xF0,
+ 0xFF, 0xFF, 0xFF, 0xFC,
+ 0xFF, 0xFF, 0xFF, 0xFC,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF, 0xFC,
+ 0x3F, 0xFF, 0xFF, 0xFC,
+
+ /* empty pascal string */
+ 0x00, 0x00,
+};
+#endif
+
+#if CurEmMd <= kEmMd_Twig43
+#define Sony_DriverBase 0x1836
+#elif CurEmMd <= kEmMd_Twiggy
+#define Sony_DriverBase 0x16E4
+#elif CurEmMd <= kEmMd_128K
+#define Sony_DriverBase 0x1690
+#elif CurEmMd <= kEmMd_Plus
+#define Sony_DriverBase 0x17D30
+#elif CurEmMd <= kEmMd_Classic
+#define Sony_DriverBase 0x34680
+#elif (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+#define Sony_DriverBase 0x2D72C
+#endif
+
+#define kVidMem_Base 0x00540000
+
+#if UseSonyPatch
+LOCALPROC Sony_Install(void)
+{
+ ui3p pto = Sony_DriverBase + ROM;
+
+ MyMoveBytes((anyp)sony_driver, (anyp)pto, sizeof(sony_driver));
+#if CurEmMd <= kEmMd_Twiggy
+ do_put_mem_long(pto + 0x14, 0x4469736B);
+ /* 'Disk' instead of 'Sony' */
+#if CurEmMd <= kEmMd_Twig43
+ do_put_mem_word(pto + 0xEA, 0x0C8A);
+#else
+ do_put_mem_word(pto + 0xEA, 0x0B74);
+#endif
+#endif
+
+ pto += sizeof(sony_driver);
+
+ do_put_mem_word(pto, kcom_callcheck);
+ pto += 2;
+ do_put_mem_word(pto, kExtnSony);
+ pto += 2;
+ do_put_mem_long(pto, kExtn_Block_Base); /* pokeaddr */
+ pto += 4;
+
+ my_disk_icon_addr = (pto - ROM) + kROM_Base;
+ MyMoveBytes((anyp)my_disk_icon, (anyp)pto, sizeof(my_disk_icon));
+ pto += sizeof(my_disk_icon);
+
+#if UseLargeScreenHack
+ {
+ ui3p patchp = pto;
+
+#include "SCRNHACK.h"
+ }
+#endif
+
+ (void) pto; /* avoid warning about unused */
+}
+#endif
+
+#ifndef DisableRomCheck
+#define DisableRomCheck 1
+#endif
+
+#ifndef DisableRamTest
+#define DisableRamTest 1
+#endif
+
+#ifdef CurAltHappyMac
+#include "HPMCHACK.h"
+#endif
+
+#ifdef ln2mtb
+LOCALPROC ROMscrambleForMTB(void)
+{
+ si5r j;
+ ui3p p = ROM;
+ ui3p p2 = ROM + (1 << ln2mtb);
+
+ for (j = kROM_Size / (1 << ln2mtb) / 2; --j >= 0; ) {
+ si5r i;
+
+ for (i = (1 << ln2mtb); --i >= 0; ) {
+ ui3b t0 = *p;
+ ui3b t1 = *p2;
+ *p++ = t1;
+ *p2++ = t0;
+ }
+
+ p += (1 << ln2mtb);
+ p2 += (1 << ln2mtb);
+ }
+}
+#endif
+
+GLOBALFUNC blnr ROM_Init(void)
+{
+#if DisableRomCheck
+
+/* skip the rom checksum */
+#if CurEmMd <= kEmMd_Twig43
+ /* no checksum code */
+#elif CurEmMd <= kEmMd_Twiggy
+ do_put_mem_word(0x136 + ROM, 0x6004);
+#elif CurEmMd <= kEmMd_128K
+ do_put_mem_word(0xE2 + ROM, 0x6004);
+#elif CurEmMd <= kEmMd_Plus
+ do_put_mem_word(0xD7A + ROM, 0x6022);
+#elif CurEmMd <= kEmMd_Classic
+ do_put_mem_word(0x1C68 + ROM, 0x6008);
+#elif (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ do_put_mem_word(0x2AB0 + ROM, 0x6008);
+#endif
+
+#endif /* DisableRomCheck */
+
+
+#if DisableRamTest
+
+#if CurEmMd <= kEmMd_128K
+#elif CurEmMd <= kEmMd_Plus
+ do_put_mem_word(3752 + ROM, 0x4E71);
+ /* shorten the ram check read */
+ do_put_mem_word(3728 + ROM, 0x4E71);
+ /* shorten the ram check write */
+#elif CurEmMd <= kEmMd_Classic
+ do_put_mem_word(134 + ROM, 0x6002);
+ do_put_mem_word(286 + ROM, 0x6002);
+#elif (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ do_put_mem_word(0xEE + ROM, 0x6002);
+ do_put_mem_word(0x1AA + ROM, 0x6002);
+#endif
+
+#endif /* DisableRamTest */
+
+#ifdef CurAltHappyMac
+ PatchHappyMac();
+#endif
+
+ /* do_put_mem_word(862 + ROM, 0x4E71); */ /* shorten set memory */
+
+#if UseSonyPatch
+ Sony_Install();
+#endif
+
+#ifdef ln2mtb
+ ROMscrambleForMTB();
+#endif
+
+ return trueblnr;
+}
--- /dev/null
+++ b/src/ROMEMDEV.h
@@ -1,0 +1,23 @@
+/*
+ ROMEMDEV.h
+
+ Copyright (C) 2003 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef ROMEMDEV_H
+#error "header already included"
+#else
+#define ROMEMDEV_H
+#endif
+
+EXPORTFUNC blnr ROM_Init(void);
--- /dev/null
+++ b/src/RTCEMDEV.c
@@ -1,0 +1,509 @@
+/*
+ RTCEMDEV.c
+
+ Copyright (C) 2003 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Real Time Clock EMulated DEVice
+
+ Emulates the RTC found in the Mac Plus.
+
+ This code adapted from "RTC.c" in vMac by Philip Cummins.
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+#include "MYOSGLUE.h"
+#include "ENDIANAC.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#endif
+
+/* define _RTC_Debug */
+#ifdef _RTC_Debug
+#include <stdio.h>
+#endif
+
+#include "RTCEMDEV.h"
+
+#define HaveXPRAM (CurEmMd >= kEmMd_Plus)
+
+/*
+ ReportAbnormalID unused 0x0805 - 0x08FF
+*/
+
+#if HaveXPRAM
+#define PARAMRAMSize 256
+#else
+#define PARAMRAMSize 20
+#endif
+
+#if HaveXPRAM
+#define Group1Base 0x10
+#define Group2Base 0x08
+#else
+#define Group1Base 0x00
+#define Group2Base 0x10
+#endif
+
+typedef struct
+{
+ /* RTC VIA Flags */
+ ui3b WrProtect;
+ ui3b DataOut;
+ ui3b DataNextOut;
+
+ /* RTC Data */
+ ui3b ShiftData;
+ ui3b Counter;
+ ui3b Mode;
+ ui3b SavedCmd;
+#if HaveXPRAM
+ ui3b Sector;
+#endif
+
+ /* RTC Registers */
+ ui3b Seconds_1[4];
+ ui3b PARAMRAM[PARAMRAMSize];
+} RTC_Ty;
+
+LOCALVAR RTC_Ty RTC;
+
+/* RTC Functions */
+
+LOCALVAR ui5b LastRealDate;
+
+#ifndef RTCinitPRAM
+#define RTCinitPRAM 1
+#endif
+
+#ifndef TrackSpeed /* in 0..4 */
+#define TrackSpeed 0
+#endif
+
+#ifndef AlarmOn /* in 0..1 */
+#define AlarmOn 0
+#endif
+
+#ifndef DiskCacheSz /* in 1,2,3,4,6,8,12 */
+/* actual cache size is DiskCacheSz * 32k */
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+#define DiskCacheSz 1
+#else
+#define DiskCacheSz 4
+#endif
+#endif
+
+#ifndef StartUpDisk /* in 0..1 */
+#define StartUpDisk 0
+#endif
+
+#ifndef DiskCacheOn /* in 0..1 */
+#define DiskCacheOn 0
+#endif
+
+#ifndef MouseScalingOn /* in 0..1 */
+#define MouseScalingOn 0
+#endif
+
+#define prb_fontHi 0
+#define prb_fontLo 2
+#define prb_kbdPrintHi (AutoKeyRate + (AutoKeyThresh << 4))
+#define prb_kbdPrintLo 0
+#define prb_volClickHi (SpeakerVol + (TrackSpeed << 3) + (AlarmOn << 7))
+#define prb_volClickLo (CaretBlinkTime + (DoubleClickTime << 4))
+#define prb_miscHi DiskCacheSz
+#define prb_miscLo \
+ ((MenuBlink << 2) + (StartUpDisk << 4) \
+ + (DiskCacheOn << 5) + (MouseScalingOn << 6))
+
+#if dbglog_HAVE && 0
+EXPORTPROC DumpRTC(void);
+
+GLOBALPROC DumpRTC(void)
+{
+ int Counter;
+
+ dbglog_writeln("RTC Parameter RAM");
+ for (Counter = 0; Counter < PARAMRAMSize; Counter++) {
+ dbglog_writeNum(Counter);
+ dbglog_writeCStr(", ");
+ dbglog_writeHex(RTC.PARAMRAM[Counter]);
+ dbglog_writeReturn();
+ }
+}
+#endif
+
+GLOBALFUNC blnr RTC_Init(void)
+{
+ int Counter;
+ ui5b secs;
+
+ RTC.Mode = RTC.ShiftData = RTC.Counter = 0;
+ RTC.DataOut = RTC.DataNextOut = 0;
+ RTC.WrProtect = falseblnr;
+
+ secs = CurMacDateInSeconds;
+ LastRealDate = secs;
+
+ RTC.Seconds_1[0] = secs & 0xFF;
+ RTC.Seconds_1[1] = (secs & 0xFF00) >> 8;
+ RTC.Seconds_1[2] = (secs & 0xFF0000) >> 16;
+ RTC.Seconds_1[3] = (secs & 0xFF000000) >> 24;
+
+ for (Counter = 0; Counter < PARAMRAMSize; Counter++) {
+ RTC.PARAMRAM[Counter] = 0;
+ }
+
+#if RTCinitPRAM
+ RTC.PARAMRAM[0 + Group1Base] = 168; /* valid */
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ RTC.PARAMRAM[2 + Group1Base] = 1;
+ /* node id hint for printer port (AppleTalk) */
+#endif
+ RTC.PARAMRAM[3 + Group1Base] = 34;
+ /*
+ serial ports config bits: 4-7 A, 0-3 B
+ useFree 0 Use undefined
+ useATalk 1 AppleTalk
+ useAsync 2 Async
+ useExtClk 3 externally clocked
+ */
+
+ RTC.PARAMRAM[4 + Group1Base] = 204; /* portA, high */
+ RTC.PARAMRAM[5 + Group1Base] = 10; /* portA, low */
+ RTC.PARAMRAM[6 + Group1Base] = 204; /* portB, high */
+ RTC.PARAMRAM[7 + Group1Base] = 10; /* portB, low */
+ RTC.PARAMRAM[13 + Group1Base] = prb_fontLo;
+ RTC.PARAMRAM[14 + Group1Base] = prb_kbdPrintHi;
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ RTC.PARAMRAM[15 + Group1Base] = 1;
+ /*
+ printer, if any, connected to modem port
+ because printer port used for appletalk.
+ */
+#endif
+
+#if prb_volClickHi != 0
+ RTC.PARAMRAM[0 + Group2Base] = prb_volClickHi;
+#endif
+ RTC.PARAMRAM[1 + Group2Base] = prb_volClickLo;
+ RTC.PARAMRAM[2 + Group2Base] = prb_miscHi;
+ RTC.PARAMRAM[3 + Group2Base] = prb_miscLo
+#if 0 != vMacScreenDepth
+ | 0x80
+#endif
+ ;
+
+#if HaveXPRAM /* extended parameter ram initialized */
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ RTC.PARAMRAM[12] = 0x4e;
+ RTC.PARAMRAM[13] = 0x75;
+ RTC.PARAMRAM[14] = 0x4d;
+ RTC.PARAMRAM[15] = 0x63;
+#else
+ RTC.PARAMRAM[12] = 0x42;
+ RTC.PARAMRAM[13] = 0x75;
+ RTC.PARAMRAM[14] = 0x67;
+ RTC.PARAMRAM[15] = 0x73;
+#endif
+#endif
+
+#if ((CurEmMd >= kEmMd_SE) && (CurEmMd <= kEmMd_Classic)) \
+ || (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+
+ RTC.PARAMRAM[0x01] = 0x80;
+ RTC.PARAMRAM[0x02] = 0x4F;
+#endif
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ RTC.PARAMRAM[0x03] = 0x48;
+
+ /* video board id */
+ RTC.PARAMRAM[0x46] = /* 0x42 */ 0x76; /* 'v' */
+ RTC.PARAMRAM[0x47] = /* 0x32 */ 0x4D; /* 'M' */
+ /* mode */
+#if (0 == vMacScreenDepth) || (vMacScreenDepth >= 4)
+ RTC.PARAMRAM[0x48] = 0x80;
+#else
+ RTC.PARAMRAM[0x48] = 0x81;
+ /* 0x81 doesn't quite work right at boot */
+ /* no, it seems to work now (?) */
+ /* but only if depth <= 3 */
+#endif
+#endif
+
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ RTC.PARAMRAM[0x77] = 0x01;
+#endif
+
+#if ((CurEmMd >= kEmMd_SE) && (CurEmMd <= kEmMd_Classic)) \
+ || (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+
+ /* start up disk (encoded how?) */
+ RTC.PARAMRAM[0x78] = 0x00;
+ RTC.PARAMRAM[0x79] = 0x01;
+ RTC.PARAMRAM[0x7A] = 0xFF;
+ RTC.PARAMRAM[0x7B] = 0xFE;
+#endif
+
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ RTC.PARAMRAM[0x80] = 0x09;
+ RTC.PARAMRAM[0x81] = 0x80;
+#endif
+
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+
+#define pr_HilColRedHi (pr_HilColRed >> 8)
+#if 0 != pr_HilColRedHi
+ RTC.PARAMRAM[0x82] = pr_HilColRedHi;
+#endif
+#define pr_HilColRedLo (pr_HilColRed & 0xFF)
+#if 0 != pr_HilColRedLo
+ RTC.PARAMRAM[0x83] = pr_HilColRedLo;
+#endif
+
+#define pr_HilColGreenHi (pr_HilColGreen >> 8)
+#if 0 != pr_HilColGreenHi
+ RTC.PARAMRAM[0x84] = pr_HilColGreenHi;
+#endif
+#define pr_HilColGreenLo (pr_HilColGreen & 0xFF)
+#if 0 != pr_HilColGreenLo
+ RTC.PARAMRAM[0x85] = pr_HilColGreenLo;
+#endif
+
+#define pr_HilColBlueHi (pr_HilColBlue >> 8)
+#if 0 != pr_HilColBlueHi
+ RTC.PARAMRAM[0x86] = pr_HilColBlueHi;
+#endif
+#define pr_HilColBlueLo (pr_HilColBlue & 0xFF)
+#if 0 != pr_HilColBlueLo
+ RTC.PARAMRAM[0x87] = pr_HilColBlueLo;
+#endif
+
+#endif /* (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx) */
+
+#if HaveXPRAM /* extended parameter ram initialized */
+ do_put_mem_long(&RTC.PARAMRAM[0xE4], CurMacLatitude);
+ do_put_mem_long(&RTC.PARAMRAM[0xE8], CurMacLongitude);
+ do_put_mem_long(&RTC.PARAMRAM[0xEC], CurMacDelta);
+#endif
+
+#endif /* RTCinitPRAM */
+
+ return trueblnr;
+}
+
+#ifdef RTC_OneSecond_PulseNtfy
+IMPORTPROC RTC_OneSecond_PulseNtfy(void);
+#endif
+
+GLOBALPROC RTC_Interrupt(void)
+{
+ ui5b Seconds = 0;
+ ui5b NewRealDate = CurMacDateInSeconds;
+ ui5b DateDelta = NewRealDate - LastRealDate;
+
+ if (DateDelta != 0) {
+ Seconds = (RTC.Seconds_1[3] << 24) + (RTC.Seconds_1[2] << 16)
+ + (RTC.Seconds_1[1] << 8) + RTC.Seconds_1[0];
+ Seconds += DateDelta;
+ RTC.Seconds_1[0] = Seconds & 0xFF;
+ RTC.Seconds_1[1] = (Seconds & 0xFF00) >> 8;
+ RTC.Seconds_1[2] = (Seconds & 0xFF0000) >> 16;
+ RTC.Seconds_1[3] = (Seconds & 0xFF000000) >> 24;
+
+ LastRealDate = NewRealDate;
+
+#ifdef RTC_OneSecond_PulseNtfy
+ RTC_OneSecond_PulseNtfy();
+#endif
+ }
+}
+
+LOCALFUNC ui3b RTC_Access_PRAM_Reg(ui3b Data, blnr WriteReg, ui3b t)
+{
+ if (WriteReg) {
+ if (! RTC.WrProtect) {
+ RTC.PARAMRAM[t] = Data;
+#ifdef _RTC_Debug
+ printf("Writing Address %2x, Data %2x\n", t, Data);
+#endif
+ }
+ } else {
+ Data = RTC.PARAMRAM[t];
+ }
+ return Data;
+}
+
+LOCALFUNC ui3b RTC_Access_Reg(ui3b Data, blnr WriteReg, ui3b TheCmd)
+{
+ ui3b t = (TheCmd & 0x7C) >> 2;
+ if (t < 8) {
+ if (WriteReg) {
+ if (! RTC.WrProtect) {
+ RTC.Seconds_1[t & 0x03] = Data;
+ }
+ } else {
+ Data = RTC.Seconds_1[t & 0x03];
+ }
+ } else if (t < 12) {
+ Data = RTC_Access_PRAM_Reg(Data, WriteReg,
+ (t & 0x03) + Group2Base);
+ } else if (t < 16) {
+ if (WriteReg) {
+ switch (t) {
+ case 12 :
+ break; /* Test Write, do nothing */
+ case 13 :
+ RTC.WrProtect = (Data & 0x80) != 0;
+ break; /* Write_Protect Register */
+ default :
+ ReportAbnormalID(0x0801, "Write RTC Reg unknown");
+ break;
+ }
+ } else {
+ ReportAbnormalID(0x0802, "Read RTC Reg unknown");
+ }
+ } else {
+ Data = RTC_Access_PRAM_Reg(Data, WriteReg,
+ (t & 0x0F) + Group1Base);
+ }
+ return Data;
+}
+
+LOCALPROC RTC_DoCmd(void)
+{
+ switch (RTC.Mode) {
+ case 0: /* This Byte is a RTC Command */
+#if HaveXPRAM
+ if ((RTC.ShiftData & 0x78) == 0x38) { /* Extended Command */
+ RTC.SavedCmd = RTC.ShiftData;
+ RTC.Mode = 2;
+#ifdef _RTC_Debug
+ printf("Extended command %2x\n", RTC.ShiftData);
+#endif
+ } else
+#endif
+ {
+ if ((RTC.ShiftData & 0x80) != 0x00) { /* Read Command */
+ RTC.ShiftData =
+ RTC_Access_Reg(0, falseblnr, RTC.ShiftData);
+ RTC.DataNextOut = 1;
+ } else { /* Write Command */
+ RTC.SavedCmd = RTC.ShiftData;
+ RTC.Mode = 1;
+ }
+ }
+ break;
+ case 1: /* This Byte is data for RTC Write */
+ (void) RTC_Access_Reg(RTC.ShiftData,
+ trueblnr, RTC.SavedCmd);
+ RTC.Mode = 0;
+ break;
+#if HaveXPRAM
+ case 2: /* This Byte is rest of Extended RTC command address */
+#ifdef _RTC_Debug
+ printf("Mode 2 %2x\n", RTC.ShiftData);
+#endif
+ RTC.Sector = ((RTC.SavedCmd & 0x07) << 5)
+ | ((RTC.ShiftData & 0x7C) >> 2);
+ if ((RTC.SavedCmd & 0x80) != 0x00) { /* Read Command */
+ RTC.ShiftData = RTC.PARAMRAM[RTC.Sector];
+ RTC.DataNextOut = 1;
+ RTC.Mode = 0;
+#ifdef _RTC_Debug
+ printf("Reading X Address %2x, Data %2x\n",
+ RTC.Sector, RTC.ShiftData);
+#endif
+ } else {
+ RTC.Mode = 3;
+#ifdef _RTC_Debug
+ printf("Writing X Address %2x\n", RTC.Sector);
+#endif
+ }
+ break;
+ case 3: /* This Byte is data for an Extended RTC Write */
+ (void) RTC_Access_PRAM_Reg(RTC.ShiftData,
+ trueblnr, RTC.Sector);
+ RTC.Mode = 0;
+ break;
+#endif
+ }
+}
+
+GLOBALPROC RTCunEnabled_ChangeNtfy(void)
+{
+ if (RTCunEnabled) {
+ /* abort anything going on */
+ if (RTC.Counter != 0) {
+#ifdef _RTC_Debug
+ printf("aborting, %2x\n", RTC.Counter);
+#endif
+ ReportAbnormalID(0x0803, "RTC aborting");
+ }
+ RTC.Mode = 0;
+ RTC.DataOut = 0;
+ RTC.DataNextOut = 0;
+ RTC.ShiftData = 0;
+ RTC.Counter = 0;
+ }
+}
+
+GLOBALPROC RTCclock_ChangeNtfy(void)
+{
+ if (! RTCunEnabled) {
+ if (RTCclock) {
+ RTC.DataOut = RTC.DataNextOut;
+ RTC.Counter = (RTC.Counter - 1) & 0x07;
+ if (RTC.DataOut) {
+ RTCdataLine = ((RTC.ShiftData >> RTC.Counter) & 0x01);
+ /*
+ should notify VIA if changed, so can check
+ data direction
+ */
+ if (RTC.Counter == 0) {
+ RTC.DataNextOut = 0;
+ }
+ } else {
+ RTC.ShiftData = (RTC.ShiftData << 1) | RTCdataLine;
+ if (RTC.Counter == 0) {
+ RTC_DoCmd();
+ }
+ }
+ }
+ }
+}
+
+GLOBALPROC RTCdataLine_ChangeNtfy(void)
+{
+#if dbglog_HAVE
+ if (RTC.DataOut) {
+ if (! RTC.DataNextOut) {
+ /*
+ ignore. The ROM doesn't read from the RTC the
+ way described in the Hardware Reference.
+ It reads the data after setting the clock to
+ one instead of before, and then immediately
+ changes the VIA direction. So the RTC
+ has no way of knowing to stop driving the
+ data line, which certainly can't really be
+ correct.
+ */
+ } else {
+ ReportAbnormalID(0x0804,
+ "write RTC Data unexpected direction");
+ }
+ }
+#endif
+}
--- /dev/null
+++ b/src/RTCEMDEV.h
@@ -1,0 +1,28 @@
+/*
+ RTCEMDEV.h
+
+ Copyright (C) 2003 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef RTCEMDEV_H
+#error "header already included"
+#else
+#define RTCEMDEV_H
+#endif
+
+EXPORTFUNC blnr RTC_Init(void);
+EXPORTPROC RTC_Interrupt(void);
+
+EXPORTPROC RTCunEnabled_ChangeNtfy(void);
+EXPORTPROC RTCclock_ChangeNtfy(void);
+EXPORTPROC RTCdataLine_ChangeNtfy(void);
--- /dev/null
+++ b/src/SCCEMDEV.c
@@ -1,0 +1,2801 @@
+/*
+ SCCEMDEV.c
+
+ Copyright (C) 2012 Philip Cummins, Weston Pawlowski,
+ Michael Fort, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Serial Communications Controller EMulated DEVice
+
+ additions for LocalTalk networking support
+ Copyright 2011-2012, Michael Fort
+ enabled with "EmLocalTalk"
+
+ -- original description: --
+
+ Emulates the Z8530 SCC found in the Mac Plus.
+ But only the minimum amount needed to emulate
+ normal operation in a Mac Plus with nothing
+ connected to the serial ports.
+ (and not even that much is complete yet)
+
+ This code adapted from "SCC.c" in vMac by Philip Cummins.
+ With additional code by Weston Pawlowski from the Windows
+ port of vMac.
+
+ Further information was found in the
+ "Zilog SCC/ESCC User's Manual".
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+
+#include "MYOSGLUE.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#endif
+
+#include "SCCEMDEV.h"
+
+/*
+ ReportAbnormalID unused 0x0721, 0x0722, 0x074D - 0x07FF
+*/
+
+#define SCC_dolog (dbglog_HAVE && 0)
+#define SCC_TrackMore 0
+
+/* Just to make things a little easier */
+#define Bit0 1
+#define Bit1 2
+#define Bit2 4
+#define Bit3 8
+#define Bit4 16
+#define Bit5 32
+#define Bit6 64
+#define Bit7 128
+
+/* SCC Interrupts */
+#define SCC_A_Rx 8 /* Rx Char Available */
+#define SCC_A_Rx_Spec 7 /* Rx Special Condition */
+#define SCC_A_Tx_Empty 6 /* Tx Buffer Empty */
+#define SCC_A_Ext 5 /* External/Status Change */
+#define SCC_B_Rx 4 /* Rx Char Available */
+#define SCC_B_Rx_Spec 3 /* Rx Special Condition */
+#define SCC_B_Tx_Empty 2 /* Tx Buffer Empty */
+#define SCC_B_Ext 1 /* External/Status Change */
+
+typedef struct {
+ blnr TxEnable;
+ blnr RxEnable;
+ blnr TxIE; /* Transmit Interrupt Enable */
+ blnr TxUnderrun;
+ blnr SyncHunt;
+ blnr TxIP; /* Transmit Interrupt Pending */
+#if EmLocalTalk
+ ui3r RxBuff;
+#endif
+#if EmLocalTalk
+ /* otherwise TxBufferEmpty always true */
+ /*
+ though should behave as went false
+ for an instant when write to transmit buffer
+ */
+ blnr TxBufferEmpty;
+#endif
+#if EmLocalTalk || SCC_TrackMore
+ blnr ExtIE;
+#endif
+#if SCC_TrackMore
+ blnr WaitRqstEnbl;
+#endif
+#if SCC_TrackMore
+ blnr WaitRqstSlct;
+#endif
+#if SCC_TrackMore
+ blnr WaitRqstRT;
+#endif
+#if SCC_TrackMore
+ blnr PrtySpclCond;
+#endif
+#if SCC_TrackMore
+ blnr PrtyEnable;
+#endif
+#if SCC_TrackMore
+ blnr PrtyEven;
+#endif
+#if SCC_TrackMore
+ blnr RxCRCEnbl;
+#endif
+#if SCC_TrackMore
+ blnr TxCRCEnbl;
+#endif
+#if SCC_TrackMore
+ blnr RTSctrl;
+#endif
+#if SCC_TrackMore
+ blnr SndBrkCtrl;
+#endif
+#if SCC_TrackMore
+ blnr DTRctrl;
+#endif
+#if EmLocalTalk || SCC_TrackMore
+ blnr AddrSrchMd;
+#endif
+#if SCC_TrackMore
+ blnr SyncChrLdInhb;
+#endif
+#if SCC_TrackMore
+ ui3r ClockRate;
+#endif
+#if SCC_TrackMore
+ ui3r DataEncoding;
+#endif
+#if SCC_TrackMore
+ ui3r TRxCsrc;
+#endif
+#if SCC_TrackMore
+ ui3r TClkSlct;
+#endif
+#if SCC_TrackMore
+ ui3r RClkSlct;
+#endif
+#if SCC_TrackMore
+ ui3r RBitsPerChar;
+#endif
+#if SCC_TrackMore
+ ui3r TBitsPerChar;
+#endif
+#if EmLocalTalk || SCC_TrackMore
+ ui3r RxIntMode;
+#endif
+#if EmLocalTalk || SCC_TrackMore
+ blnr FirstChar;
+#endif
+#if EmLocalTalk || SCC_TrackMore
+ ui3r SyncMode;
+#endif
+#if SCC_TrackMore
+ ui3r StopBits;
+#endif
+#if 0 /* AllSent always true */
+ blnr AllSent;
+#endif
+#if 0 /* CTS always false */
+ blnr CTS; /* input pin, unattached, so false? */
+#endif
+#if 0 /* DCD always false */
+ blnr DCD; /* Data Carrier Detect */
+ /*
+ input pin for mouse interrupts. but since
+ not emulating mouse this way, leave false.
+ */
+#endif
+#if EmLocalTalk
+ /* otherwise RxChrAvail always false */
+ blnr RxChrAvail;
+#endif
+#if 0 /* RxOverrun always false */
+ blnr RxOverrun;
+#endif
+#if 0 /* CRCFramingErr always false */
+ blnr CRCFramingErr;
+#endif
+#if EmLocalTalk
+ /* otherwise EndOfFrame always false */
+ blnr EndOfFrame;
+#endif
+#if 0 /* ParityErr always false */
+ blnr ParityErr;
+#endif
+#if 0 /* ZeroCount always false */
+ blnr ZeroCount;
+#endif
+#if 0 /* BreakAbort always false */
+ blnr BreakAbort;
+#endif
+#if 0 /* SyncHuntIE usually false */
+ blnr SyncHuntIE;
+#endif
+#if SCC_TrackMore /* don't care about CTS_IE */
+ blnr CTS_IE;
+#endif
+#if SCC_TrackMore
+ blnr CRCPreset;
+#endif
+#if SCC_TrackMore
+ blnr BRGEnbl;
+#endif
+#if 0 /* don't care about DCD_IE, always true */
+ blnr DCD_IE;
+#endif
+#if SCC_TrackMore /* don't care about BreakAbortIE */
+ blnr BreakAbortIE;
+#endif
+#if SCC_TrackMore /* don't care about Baud */
+ ui3r BaudLo;
+ ui3r BaudHi;
+#endif
+} Channel_Ty;
+
+typedef struct {
+ Channel_Ty a[2]; /* 0 = channel A, 1 = channel B */
+ int SCC_Interrupt_Type;
+ int PointerBits;
+ ui3b InterruptVector;
+ blnr MIE; /* master interrupt enable */
+#if SCC_TrackMore
+ blnr NoVectorSlct;
+#endif
+#if 0 /* StatusHiLo always false */
+ blnr StatusHiLo;
+#endif
+} SCC_Ty;
+
+LOCALVAR SCC_Ty SCC;
+
+#if 0
+LOCALVAR int ReadPrint;
+LOCALVAR int ReadModem;
+#endif
+
+#if EmLocalTalk
+static int rx_data_offset = 0;
+ /* when data pending, this is used */
+#endif
+
+EXPORTFUNC blnr SCC_InterruptsEnabled(void)
+{
+ return SCC.MIE;
+}
+
+/* ---- */
+
+/* Function used to update the interrupt state of the SCC */
+LOCALPROC CheckSCCInterruptFlag(void)
+{
+#if 0 /* ReceiveAInterrupt always false */
+ blnr ReceiveAInterrupt = falseblnr
+ /*
+ also dependeds on WR1, bits 3 and 4, but
+ this doesn't change that it's all false
+ */
+#if EmLocalTalk
+ /* otherwise RxChrAvail always false */
+ | SCC.a[0].RxChrAvail
+#endif
+#if 0 /* RxOverrun always false */
+ | SCC.a[0].RxOverrun
+#endif
+#if 0 /* CRCFramingErr always false */
+ | SCC.a[0].CRCFramingErr
+#endif
+#if EmLocalTalk
+ /* otherwise EndOfFrame always false */
+ | SCC.a[0].EndOfFrame
+#endif
+#if 0 /* ParityErr always false */
+ | SCC.a[0].ParityErr
+#endif
+ ;
+#endif
+#if 0
+ blnr TransmitAInterrupt = SCC.a[0].TxBufferEmpty;
+ /*
+ but probably looking for transitions not
+ current value
+ */
+#endif
+#if 0
+ blnr ExtStatusAInterrupt = 0
+#if 0 /* ZeroCount always false */
+ | SCC.a[0].ZeroCount
+#endif
+ /* probably want transition for these, not value */
+#if 0 /* DCD always false */
+ | SCC.a[0].DCD /* DCD IE always true */
+#endif
+#if 0 /* CTS always false */
+ | SCC.a[0].CTS /* would depend on CTS_IE */
+#endif
+ | SCC.a[0].SyncHunt /* SyncHuntIE usually false */
+ | SCC.a[0].TxUnderrun /* Tx underrun/EOM IE always false */
+#if 0 /* BreakAbort always false */
+ | SCC.a[0].BreakAbort
+#endif
+ ;
+#endif
+ ui3b NewSCCInterruptRequest;
+
+#if EmLocalTalk
+ blnr ReceiveBInterrupt = falseblnr;
+ blnr RxSpclBInterrupt = falseblnr
+ /* otherwise EndOfFrame always false */
+ | SCC.a[1].EndOfFrame
+ ;
+#endif
+
+#if EmLocalTalk
+ switch (SCC.a[1].RxIntMode) {
+ case 0:
+ /* disabled */
+ RxSpclBInterrupt = falseblnr;
+ break;
+ case 1:
+ /* Rx INT on 1st char or special condition */
+ if (SCC.a[1].RxChrAvail && SCC.a[1].FirstChar) {
+ ReceiveBInterrupt = trueblnr;
+ }
+ break;
+ case 2:
+ /* INT on all Rx char or special condition */
+ if (SCC.a[1].RxChrAvail) {
+ ReceiveBInterrupt = trueblnr;
+ }
+ break;
+ case 3:
+ /* Rx INT on special condition only */
+ break;
+ }
+#endif
+
+ /* Master Interrupt Enable */
+ if (! SCC.MIE) {
+ SCC.SCC_Interrupt_Type = 0;
+ } else
+#if 0
+ /* External Interrupt Enable */
+ if (SCC.a[1].ExtIE) {
+ /* DCD Interrupt Enable */
+ if (SCC.a[1].DCD_IE && 0) { /* dcd unchanged */
+ SCC.SCC_Interrupt_Type = ??;
+ }
+ }
+#endif
+ if (SCC.a[0].TxIP && SCC.a[0].TxIE) {
+ SCC.SCC_Interrupt_Type = SCC_A_Tx_Empty;
+ } else
+#if EmLocalTalk
+ if (ReceiveBInterrupt) {
+ SCC.SCC_Interrupt_Type = SCC_B_Rx;
+ } else
+ if (RxSpclBInterrupt) {
+ SCC.SCC_Interrupt_Type = SCC_B_Rx_Spec;
+ } else
+#endif
+ if (SCC.a[1].TxIP && SCC.a[1].TxIE) {
+ SCC.SCC_Interrupt_Type = SCC_B_Tx_Empty;
+ } else
+ {
+ SCC.SCC_Interrupt_Type = 0;
+ }
+
+ NewSCCInterruptRequest = (SCC.SCC_Interrupt_Type != 0) ? 1 : 0;
+ if (NewSCCInterruptRequest != SCCInterruptRequest) {
+#if SCC_dolog
+ dbglog_WriteSetBool("SCCInterruptRequest change",
+ NewSCCInterruptRequest);
+
+ dbglog_StartLine();
+ dbglog_writeCStr("SCC.SCC_Interrupt_Type <- ");
+ dbglog_writeHex(SCC.SCC_Interrupt_Type);
+ dbglog_writeReturn();
+#endif
+ SCCInterruptRequest = NewSCCInterruptRequest;
+#ifdef SCCinterruptChngNtfy
+ SCCinterruptChngNtfy();
+#endif
+ }
+}
+
+LOCALPROC SCC_InitChannel(int chan)
+{
+ /* anything not done by ResetChannel */
+
+ SCC.a[chan].SyncHunt = trueblnr;
+#if 0 /* DCD always false */
+ SCC.a[chan].DCD = falseblnr; /* input pin, reset doesn't change */
+#endif
+#if 0 /* CTS always false */
+ SCC.a[chan].CTS = falseblnr; /* input pin, reset doesn't change */
+#endif
+#if 0 /* AllSent always true */
+ SCC.a[chan].AllSent = trueblnr;
+#endif
+#if SCC_TrackMore /* don't care about Baud */
+ SCC.a[chan].BaudLo = 0;
+ SCC.a[chan].BaudHi = 0;
+#endif
+#if 0 /* BreakAbort always false */
+ SCC.a[chan].BreakAbort = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].BRGEnbl = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].TRxCsrc = 0;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].TClkSlct = 1;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].RClkSlct = 0;
+#endif
+}
+
+LOCALPROC SCC_ResetChannel(int chan)
+{
+/* RR 0 */
+#if EmLocalTalk
+ SCC.a[chan].RxBuff = 0;
+#endif
+#if EmLocalTalk
+ /* otherwise RxChrAvail always false */
+ SCC.a[chan].RxChrAvail = falseblnr;
+#endif
+#if 0 /* ZeroCount always false */
+ SCC.a[chan].ZeroCount = falseblnr;
+#endif
+#if EmLocalTalk
+ /* otherwise TxBufferEmpty always true */
+ SCC.a[chan].TxBufferEmpty = trueblnr;
+#endif
+ SCC.a[chan].TxUnderrun = trueblnr;
+/* RR 1 */
+#if 0 /* ParityErr always false */
+ SCC.a[chan].ParityErr = falseblnr;
+#endif
+#if 0 /* RxOverrun always false */
+ SCC.a[chan].RxOverrun = falseblnr;
+#endif
+#if 0 /* CRCFramingErr always false */
+ SCC.a[chan].CRCFramingErr = falseblnr;
+#endif
+#if EmLocalTalk
+ /* otherwise EndOfFrame always false */
+ SCC.a[chan].EndOfFrame = falseblnr;
+#endif
+/* RR 3 */
+#if EmLocalTalk || SCC_TrackMore
+ SCC.a[chan].ExtIE = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].RxCRCEnbl = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].TxCRCEnbl = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].RTSctrl = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].SndBrkCtrl = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].DTRctrl = falseblnr;
+#endif
+#if EmLocalTalk || SCC_TrackMore
+ SCC.a[chan].AddrSrchMd = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].SyncChrLdInhb = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].WaitRqstEnbl = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].WaitRqstSlct = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].WaitRqstRT = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].PrtySpclCond = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].PrtyEnable = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].PrtyEven = falseblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].ClockRate = 0;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].DataEncoding = 0;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].RBitsPerChar = 0;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].TBitsPerChar = 0;
+#endif
+#if EmLocalTalk || SCC_TrackMore
+ SCC.a[chan].RxIntMode = 0;
+#endif
+#if EmLocalTalk || SCC_TrackMore
+ SCC.a[chan].FirstChar = falseblnr;
+#endif
+#if EmLocalTalk || SCC_TrackMore
+ SCC.a[chan].SyncMode = 0;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].StopBits = 0;
+#endif
+#if SCC_TrackMore
+ SCC.NoVectorSlct = falseblnr;
+#endif
+ SCC.a[chan].TxIP = falseblnr;
+
+ SCC.a[chan].TxEnable = falseblnr;
+ SCC.a[chan].RxEnable = falseblnr;
+ SCC.a[chan].TxIE = falseblnr;
+
+#if 0 /* don't care about DCD_IE, always true */
+ SCC.a[chan].DCD_IE = trueblnr;
+#endif
+#if SCC_TrackMore /* don't care about CTS_IE */
+ SCC.a[chan].CTS_IE = trueblnr;
+#endif
+#if SCC_TrackMore
+ SCC.a[chan].CRCPreset = falseblnr;
+#endif
+#if 0 /* SyncHuntIE usually false */
+ SCC.a[chan].SyncHuntIE = trueblnr;
+#endif
+#if SCC_TrackMore /* don't care about BreakAbortIE */
+ SCC.a[chan].BreakAbortIE = trueblnr;
+#endif
+
+ SCC.PointerBits = 0;
+
+#if 0
+ if (chan != 0) {
+ ReadPrint = 0;
+ } else {
+ ReadModem = 0;
+ }
+#endif
+}
+
+GLOBALPROC SCC_Reset(void)
+{
+ SCCwaitrq = 1;
+
+ SCC.SCC_Interrupt_Type = 0;
+
+ SCCInterruptRequest = 0;
+ SCC.PointerBits = 0;
+ SCC.MIE = falseblnr;
+ SCC.InterruptVector = 0;
+#if 0 /* StatusHiLo always false */
+ SCC.StatusHiLo = falseblnr;
+#endif
+
+ SCC_InitChannel(1);
+ SCC_InitChannel(0);
+
+ SCC_ResetChannel(1);
+ SCC_ResetChannel(0);
+}
+
+
+#if EmLocalTalk
+
+LOCALVAR blnr CTSpacketPending = falseblnr;
+LOCALVAR ui3r CTSpacketRxDA;
+LOCALVAR ui3r CTSpacketRxSA;
+
+/*
+ Function used when all the tx data is sent to the SCC as indicated
+ by resetting the TX underrun/EOM latch. If the transmit packet is
+ a unicast RTS LAPD packet, we fake the corresponding CTS LAPD
+ packet. This is okay because it is only a collision avoidance
+ mechanism and the Ethernet device itself and BPF automatically
+ handle collision detection and retransmission. Besides this is
+ what a standard AppleTalk (LocalTalk to EtherTalk) bridge does.
+*/
+LOCALPROC process_transmit(void)
+{
+ /* Check for LLAP packets, which we won't send */
+ if (LT_TxBuffSz == 3) {
+ /*
+ We will automatically and immediately acknowledge
+ any non-broadcast RTS packets
+ */
+ if ((LT_TxBuffer[0] != 0xFF) && (LT_TxBuffer[2] == 0x84)) {
+#if SCC_dolog
+ dbglog_WriteNote("SCC LLAP packet in process_transmit");
+#endif
+ if (CTSpacketPending) {
+ ReportAbnormalID(0x0701,
+ "Already CTSpacketPending in process_transmit");
+ } else {
+ CTSpacketRxDA = LT_TxBuffer[1]; /* rx da = tx sa */
+ CTSpacketRxSA = LT_TxBuffer[0]; /* rx sa = tx da */
+ CTSpacketPending = trueblnr;
+ }
+ }
+ } else {
+ LT_TransmitPacket();
+ }
+}
+
+LOCALPROC SCC_TxBuffPut(ui3r Data)
+{
+ /* Buffer the data in the transmit buffer */
+ if (LT_TxBuffSz < LT_TxBfMxSz) {
+ LT_TxBuffer[LT_TxBuffSz] = Data;
+ ++LT_TxBuffSz;
+ }
+}
+
+LOCALVAR ui3b MyCTSBuffer[4];
+
+LOCALPROC GetCTSpacket(void)
+{
+ /* Get a single buffer worth of packets at a time */
+ ui3p device_buffer = MyCTSBuffer;
+
+#if SCC_dolog
+ dbglog_WriteNote("SCC receiving CTS packet");
+#endif
+ /* Create the fake response from the other node */
+ device_buffer[0] = CTSpacketRxDA;
+ device_buffer[1] = CTSpacketRxSA;
+ device_buffer[2] = 0x85; /* llap cts */
+
+ /* Start the receiver */
+ LT_RxBuffer = device_buffer;
+ LT_RxBuffSz = 3;
+
+ CTSpacketPending = falseblnr;
+}
+
+/*
+ This function is called once all the normal packet bytes have been
+ received.
+*/
+LOCALPROC rx_complete(void)
+{
+ if (SCC.a[1].EndOfFrame) {
+ ReportAbnormalID(0x0702, "EndOfFrame true in rx_complete");
+ }
+ if (! SCC.a[1].RxChrAvail) {
+ ReportAbnormalID(0x0703, "RxChrAvail false in rx_complete");
+ }
+ if (SCC.a[1].SyncHunt) {
+ ReportAbnormalID(0x0704, "SyncHunt true in rx_complete");
+ }
+
+ /*
+ Need to wait for rx_eof_pending (end of frame) to clear before
+ preparing the next packet for receive.
+ */
+ LT_RxBuffer = nullpr;
+
+ SCC.a[1].EndOfFrame = trueblnr;
+}
+
+LOCALPROC SCC_RxBuffAdvance(void)
+{
+ ui3r value;
+
+ /*
+ From the manual:
+ "If status is checked, it must be done before the data is read,
+ because the act of reading the data pops both the data and
+ error FIFOs."
+ */
+
+ if (nullpr == LT_RxBuffer) {
+ value = 0x7E;
+ SCC.a[1].RxChrAvail = falseblnr;
+ } else {
+ if (rx_data_offset < LT_RxBuffSz) {
+ value = LT_RxBuffer[rx_data_offset];
+ } else {
+ ui5r i = rx_data_offset - LT_RxBuffSz;
+
+ /* if i==0 in first byte of CRC, have not got EOF yet */
+ if (i == 1) {
+ rx_complete();
+ }
+
+ value = 0;
+ }
+ ++rx_data_offset;
+ }
+
+ SCC.a[1].RxBuff = value;
+}
+
+/* LLAP/SDLC address */
+LOCALVAR ui3b my_node_address = 0;
+
+LOCALPROC GetNextPacketForMe(void)
+{
+ unsigned char dst;
+ unsigned char src;
+
+label_retry:
+ LT_ReceivePacket();
+
+ if (nullpr != LT_RxBuffer) {
+#if SCC_dolog
+ dbglog_WriteNote("SCC receiving packet from BPF");
+#endif
+
+ /* Is this packet destined for me? */
+ dst = LT_RxBuffer[0];
+ src = LT_RxBuffer[1];
+ if (src == my_node_address) {
+#if SCC_dolog
+ dbglog_WriteNote("SCC ignore packet from myself");
+#endif
+ LT_RxBuffer = nullpr;
+ goto label_retry;
+ } else if ((dst == my_node_address)
+ || (dst == 0xFF)
+ || ! SCC.a[1].AddrSrchMd)
+ {
+ /* ok */
+ } else {
+#if SCC_dolog
+ dbglog_WriteNote("SCC ignore packet not for me");
+#endif
+ LT_RxBuffer = nullpr;
+ goto label_retry;
+ }
+ }
+}
+
+/*
+ External function, called periodically, to poll for any new LTOE
+ packets. Any new packets are queued into the packet receipt queue.
+*/
+GLOBALPROC LocalTalkTick(void)
+{
+ if (SCC.a[1].RxEnable
+ && (! SCC.a[1].RxChrAvail))
+ {
+ if (nullpr != LT_RxBuffer) {
+#if SCC_dolog
+ dbglog_WriteNote("SCC recover abandoned packet");
+#endif
+ } else {
+ if (CTSpacketPending) {
+ GetCTSpacket();
+ } else {
+ GetNextPacketForMe();
+ }
+ }
+
+ if (nullpr != LT_RxBuffer) {
+ rx_data_offset = 0;
+ SCC.a[1].EndOfFrame = falseblnr;
+ SCC.a[1].RxChrAvail = trueblnr;
+ SCC.a[1].SyncHunt = falseblnr;
+
+ SCC_RxBuffAdvance();
+ /* We can update the rx interrupt if enabled */
+ CheckSCCInterruptFlag();
+ }
+ }
+}
+
+#endif
+
+
+#if 0
+LOCALPROC SCC_Interrupt(int Type)
+{
+ if (SCC.MIE) { /* Master Interrupt Enable */
+
+ if (Type > SCC.SCC_Interrupt_Type) {
+ SCC.SCC_Interrupt_Type = Type;
+ }
+
+ CheckSCCInterruptFlag();
+ }
+}
+#endif
+
+#if 0
+LOCALPROC SCC_Int(void)
+{
+ /* This should be called at regular intervals */
+
+ /* Turn off Sync/Hunt Mode */
+ if (SCC.a[0].SyncHunt) {
+ SCC.a[0].SyncHunt = falseblnr;
+
+#ifdef _SCC_Debug2
+ vMac_Message("SCC_Int: Disable Sync/Hunt on A");
+#endif
+
+#if 0 /* SyncHuntIE usually false */
+ if (SCC.a[0].SyncHuntIE) {
+ SCC_Interrupt(SCC_A_Ext);
+ }
+#endif
+ }
+ if (SCC.a[1].SyncHunt) {
+ SCC.a[1].SyncHunt = falseblnr;
+
+#ifdef _SCC_Debug2
+ vMac_Message("SCC_Int: Disable Sync/Hunt on B");
+#endif
+
+#if 0 /* SyncHuntIE usually false */
+ if (SCC.a[1].SyncHuntIE) {
+ SCC_Interrupt(SCC_B_Ext);
+ }
+#endif
+ }
+
+#if 0
+ /* Check for incoming data */
+ if (ModemPort)
+ {
+ if (! SCC.a[0].RxEnable) { /* Rx Disabled */
+ ReadModem = 0;
+ }
+
+ if ((ModemBytes > 0) && (ModemCount > ModemBytes - 1))
+ {
+ SCC.a[0].RxChrAvail = falseblnr;
+ ReadModem = ModemBytes = ModemCount = 0;
+ }
+
+ if (ReadModem) {
+ ReadModem = 2;
+
+ SCC.a[0].RxChrAvail = trueblnr;
+
+ if (SCC.a[0].WR[0] & Bit5
+ && ! (SCC.a[0].WR[0] & (Bit4 | Bit3)))
+ {
+ /* Int on next Rx char */
+ SCC_Interrupt(SCC_A_Rx);
+ } else if (SCC.a[0].WR[1] & Bit3
+ && ! (SCC.a[0].WR[1] & Bit4))
+ {
+ /* Int on first Rx char */
+ SCC_Interrupt(SCC_A_Rx);
+ } else if (SCC.a[0].WR[1] & Bit4
+ && ! (SCC.a[0].WR[1] & Bit3))
+ {
+ /* Int on all Rx chars */
+ SCC_Interrupt(SCC_A_Rx);
+ }
+ }
+ }
+ if (PrintPort) {
+ if (! SCC.a[1].RxEnable) {
+ /* Rx Disabled */
+ ReadPrint = 0;
+ }
+
+ if ((PrintBytes > 0) && (PrintCount > PrintBytes - 1)) {
+ SCC.a[1].RxChrAvail = falseblnr;
+ ReadPrint = PrintBytes = PrintCount = 0;
+ }
+
+ if (ReadPrint) {
+ ReadPrint = 2;
+
+ SCC.a[1].RxChrAvail = trueblnr;
+
+ if (SCC.a[1].WR[0] & Bit5
+ && ! (SCC.a[1].WR[0] & (Bit4 | Bit3)))
+ {
+ /* Int on next Rx char */
+ SCC_Interrupt(SCC_B_Rx);
+ } else if (SCC.a[1].WR[1] & Bit3
+ && ! (SCC.a[1].WR[1] & Bit4))
+ {
+ /* Int on first Rx char */
+ SCC_Interrupt(SCC_B_Rx);
+ } else if (SCC.a[1].WR[1] & Bit4
+ && ! (SCC.a[1].WR[1] & Bit3))
+ {
+ /* Int on all Rx chars */
+ SCC_Interrupt(SCC_B_Rx);
+ }
+ }
+ }
+#endif
+}
+#endif
+
+#if SCC_dolog
+LOCALPROC SCC_DbgLogChanStartLine(int chan)
+{
+ dbglog_StartLine();
+ dbglog_writeCStr("SCC chan(");
+ if (chan) {
+ dbglog_writeCStr("B");
+ } else {
+ dbglog_writeCStr("A");
+ }
+ /* dbglog_writeHex(chan); */
+ dbglog_writeCStr(")");
+}
+#endif
+
+LOCALFUNC ui3r SCC_GetRR0(int chan)
+{
+ /* happens on boot always */
+
+ return 0
+#if 0 /* BreakAbort always false */
+ | (SCC.a[chan].BreakAbort ? (1 << 7) : 0)
+#endif
+ | (SCC.a[chan].TxUnderrun ? (1 << 6) : 0)
+#if 0 /* CTS always false */
+ | (SCC.a[chan].CTS ? (1 << 5) : 0)
+#endif
+ | (SCC.a[chan].SyncHunt ? (1 << 4) : 0)
+#if 0 /* DCD always false */
+ | (SCC.a[chan].DCD ? (1 << 3) : 0)
+#endif
+#if EmLocalTalk
+ | (SCC.a[chan].TxBufferEmpty ? (1 << 2) : 0)
+#else
+ /* otherwise TxBufferEmpty always true */
+ | (1 << 2)
+#endif
+#if 0 /* ZeroCount always false */
+ | (SCC.a[chan].ZeroCount ? (1 << 1) : 0)
+#endif
+#if EmLocalTalk
+ /* otherwise RxChrAvail always false */
+ | (SCC.a[chan].RxChrAvail ? (1 << 0) : 0)
+#endif
+ ;
+}
+
+LOCALFUNC ui3r SCC_GetRR1(int chan)
+{
+ /* happens in MacCheck */
+
+ ui3r value;
+#if ! EmLocalTalk
+ UnusedParam(chan);
+#endif
+
+ value = Bit2 | Bit1
+#if 0 /* AllSent always true */
+ | (SCC.a[chan].AllSent ? (1 << 0) : 0)
+#else
+ | Bit0
+#endif
+#if 0 /* ParityErr always false */
+ | (SCC.a[chan].ParityErr ? (1 << 4) : 0)
+#endif
+#if 0 /* RxOverrun always false */
+ | (SCC.a[chan].RxOverrun ? (1 << 5) : 0)
+#endif
+#if 0 /* CRCFramingErr always false */
+ | (SCC.a[chan].CRCFramingErr ? (1 << 6) : 0)
+#endif
+#if EmLocalTalk
+ /* otherwise EndOfFrame always false */
+ | (SCC.a[chan].EndOfFrame ? (1 << 7) : 0)
+#endif
+ ;
+
+ return value;
+}
+
+LOCALFUNC ui3r SCC_GetRR2(int chan)
+{
+ /* happens in MacCheck */
+ /* happens in Print to ImageWriter */
+
+ ui3r value = SCC.InterruptVector;
+
+ if (chan != 0) { /* B Channel */
+#if 0 /* StatusHiLo always false */
+ if (SCC.StatusHiLo) {
+ /* Status High */
+ value = value
+ & (Bit0 | Bit1 | Bit2 | Bit3 | Bit7);
+
+ ReportAbnormalID(0x0705, "Status high/low");
+ switch (SCC.SCC_Interrupt_Type) {
+ case SCC_A_Rx:
+ value |= Bit4 | Bit5;
+ break;
+
+ case SCC_A_Rx_Spec:
+ value |= Bit4 | Bit5 | Bit6;
+ break;
+
+ case SCC_A_Tx_Empty:
+ value |= Bit4;
+ break;
+
+ case SCC_A_Ext:
+ value |= Bit4 | Bit6;
+ break;
+
+ case SCC_B_Rx:
+ value |= Bit5;
+ break;
+
+ case SCC_B_Rx_Spec:
+ value |= Bit5 | Bit6;
+ break;
+
+ case SCC_B_Tx_Empty:
+ value |= 0;
+ break;
+
+ case SCC_B_Ext:
+ value |= Bit6;
+ break;
+
+ default:
+ value |= Bit5 | Bit6;
+ break;
+ }
+ } else
+#endif
+ {
+ /* Status Low */
+ value = value
+ & (Bit0 | Bit4 | Bit5 | Bit6 | Bit7);
+
+ switch (SCC.SCC_Interrupt_Type) {
+ case SCC_A_Rx:
+ value |= Bit3 | Bit2;
+ break;
+
+ case SCC_A_Rx_Spec:
+ value |= Bit3 | Bit2 | Bit1;
+ break;
+
+ case SCC_A_Tx_Empty:
+ value |= Bit3;
+ break;
+
+ case SCC_A_Ext:
+ value |= Bit3 | Bit1;
+ break;
+
+ case SCC_B_Rx:
+ value |= Bit2;
+ break;
+
+ case SCC_B_Rx_Spec:
+ value |= Bit2 | Bit1;
+ break;
+
+ case SCC_B_Tx_Empty:
+ value |= 0;
+ break;
+
+ case SCC_B_Ext:
+ value |= Bit1;
+ break;
+
+ default:
+ value |= Bit2 | Bit1;
+ break;
+ }
+ }
+
+ /* SCC.SCC_Interrupt_Type = 0; */
+ }
+
+ return value;
+}
+
+LOCALFUNC ui3r SCC_GetRR3(int chan)
+{
+ ui3r value = 0;
+
+ UnusedParam(chan);
+ ReportAbnormalID(0x0706, "RR 3");
+
+#if 0
+ if (chan == 0) {
+ value = 0
+ | (SCC.a[1].TxIP ? (1 << 1) : 0)
+ | (SCC.a[0].TxIP ? (1 << 4) : 0)
+ ;
+ } else {
+ value = 0;
+ }
+#endif
+
+ return value;
+}
+
+LOCALFUNC ui3r SCC_GetRR8(int chan)
+{
+ ui3r value = 0;
+
+ /* Receive Buffer */
+ /* happens on boot with appletalk on */
+ if (SCC.a[chan].RxEnable) {
+#if EmLocalTalk
+ if (0 != chan) {
+ /*
+ Check the receive state, handling a complete rx
+ if necessary
+ */
+ value = SCC.a[1].RxBuff;
+ SCC.a[1].FirstChar = falseblnr;
+ SCC_RxBuffAdvance();
+ } else {
+ value = 0x7E;
+ }
+#else
+ /* Rx Enable */
+#if (CurEmMd >= kEmMd_SE) && (CurEmMd <= kEmMd_IIx)
+ /* don't report */
+#else
+ ReportAbnormalID(0x0707, "read rr8 when RxEnable");
+#endif
+
+ /* Input 1 byte from Modem Port/Printer into Data */
+#endif
+ } else {
+ /* happens on boot with appletalk on */
+ }
+
+ return value;
+}
+
+LOCALFUNC ui3r SCC_GetRR10(int chan)
+{
+ /* happens on boot with appletalk on */
+
+ ui3r value = 0;
+ UnusedParam(chan);
+
+#if 0 && EmLocalTalk
+ value = 2;
+#endif
+
+ return value;
+}
+
+LOCALFUNC ui3r SCC_GetRR12(int chan)
+{
+ ui3r value = 0;
+
+#if ! SCC_TrackMore
+ UnusedParam(chan);
+#endif
+ ReportAbnormalID(0x0708, "RR 12");
+
+#if SCC_TrackMore /* don't care about Baud */
+ value = SCC.a[chan].BaudLo;
+#endif
+
+ return value;
+}
+
+LOCALFUNC ui3r SCC_GetRR13(int chan)
+{
+ ui3r value = 0;
+
+#if ! SCC_TrackMore
+ UnusedParam(chan);
+#endif
+ ReportAbnormalID(0x0709, "RR 13");
+
+#if SCC_TrackMore /* don't care about Baud */
+ value = SCC.a[chan].BaudHi;
+#endif
+
+ return value;
+}
+
+LOCALFUNC ui3r SCC_GetRR15(int chan)
+{
+ ui3r value = 0;
+
+ UnusedParam(chan);
+ ReportAbnormalID(0x070A, "RR 15");
+
+#if 0
+ value = 0
+#if 0 /* don't care about DCD_IE, always true */
+ | (SCC.a[chan].DCD_IE ? Bit3 : 0)
+#else
+ | Bit3
+#endif
+#if 0 /* SyncHuntIE usually false */
+ | (SCC.a[chan].SyncHuntIE ? Bit4 : 0)
+#endif
+#if SCC_TrackMore /* don't care about CTS_IE */
+ | (SCC.a[chan].CTS_IE ? Bit5 : 0)
+#endif
+#if SCC_TrackMore /* don't care about BreakAbortIE */
+ | (SCC.a[chan].BreakAbortIE ? Bit7 : 0)
+#endif
+ ;
+#endif
+
+ return value;
+}
+
+#if SCC_dolog
+LOCALPROC SCC_DbgLogChanCmnd(int chan, char *s)
+{
+ SCC_DbgLogChanStartLine(chan);
+ dbglog_writeCStr(" ");
+ dbglog_writeCStr(s);
+ dbglog_writeReturn();
+}
+#endif
+
+#if SCC_dolog
+LOCALPROC SCC_DbgLogChanChngBit(int chan, char *s, blnr v)
+{
+ SCC_DbgLogChanStartLine(chan);
+ dbglog_writeCStr(" ");
+ dbglog_writeCStr(s);
+ dbglog_writeCStr(" <- ");
+ if (v) {
+ dbglog_writeCStr("1");
+ } else {
+ dbglog_writeCStr("0");
+ }
+ dbglog_writeReturn();
+}
+#endif
+
+LOCALPROC SCC_PutWR0(ui3r Data, int chan)
+/*
+ "CRC initialize, initialization commands for the various modes,
+ Register Pointers"
+*/
+{
+ switch ((Data >> 6) & 3) {
+ case 1:
+ ReportAbnormalID(0x070B, "Reset Rx CRC Checker");
+ break;
+ case 2:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "Reset Tx CRC Generator");
+#endif
+ /* happens on boot with appletalk on */
+ break;
+ case 3:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "Reset Tx Underrun/EOM Latch");
+#endif
+ /* happens on boot with appletalk on */
+#if EmLocalTalk
+ /*
+ This is the indication we are done transmitting
+ data for the current packet.
+ */
+ process_transmit();
+#endif
+#if 0 /* It seems to work better without this */
+ if (SCC.a[chan].TxEnable) {
+ /* Tx Enabled */
+ SCC.a[chan].TxUnderrun = falseblnr;
+
+ if (SCC.a[chan].WR[10] & Bit2) {
+ /* Abort/Flag on Underrun */
+ /* Send Abort */
+ SCC.a[chan].TxUnderrun = trueblnr;
+#if 0 /* TxBufferEmpty always true */
+ SCC.a[chan].TxBufferEmpty = trueblnr;
+#endif
+
+ /* Send Flag */
+ }
+ }
+#endif
+ break;
+ case 0:
+ default:
+ /* Null Code */
+ break;
+ }
+ SCC.PointerBits = Data & 0x07;
+ switch ((Data >> 3) & 7) {
+ case 1: /* Point High */
+ SCC.PointerBits |= 8;
+ break;
+ case 2:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "Reset Ext/Status Ints");
+#endif
+ /* happens on boot always */
+ SCC.a[chan].SyncHunt = falseblnr;
+#if 0 /* only in sync mode */
+ SCC.a[chan].TxUnderrun = falseblnr;
+#endif
+#if 0 /* ZeroCount always false */
+ SCC.a[chan].ZeroCount = falseblnr;
+#endif
+#if 0 /* BreakAbort always false */
+ SCC.a[chan].BreakAbort = falseblnr;
+#endif
+ break;
+ case 3:
+ ReportAbnormalID(0x070C, "Send Abort (SDLC)");
+#if EmLocalTalk
+ SCC.a[chan].TxBufferEmpty = trueblnr;
+#endif
+#if 0
+ SCC.a[chan].TxUnderrun = trueblnr;
+#if 0 /* TxBufferEmpty always true */
+ SCC.a[chan].TxBufferEmpty = trueblnr;
+#endif
+#endif
+ break;
+ case 4:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "Enable Int on next Rx char");
+#endif
+#if EmLocalTalk || SCC_TrackMore
+ SCC.a[chan].FirstChar = trueblnr;
+#endif
+ /* happens in MacCheck */
+ break;
+ case 5:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "Reset Tx Int Pending");
+#endif
+ /* happens in MacCheck */
+ /* happens in Print to ImageWriter */
+ SCC.a[chan].TxIP = falseblnr;
+ CheckSCCInterruptFlag();
+ break;
+ case 6:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "Error Reset");
+#endif
+ /* happens on boot with appletalk on */
+#if EmLocalTalk
+ SCC.a[chan].EndOfFrame = falseblnr;
+#endif
+#if 0 /* ParityErr always false */
+ SCC.a[chan].ParityErr = falseblnr;
+#endif
+#if 0 /* RxOverrun always false */
+ SCC.a[chan].RxOverrun = falseblnr;
+#endif
+#if 0 /* CRCFramingErr always false */
+ SCC.a[chan].CRCFramingErr = falseblnr;
+#endif
+ break;
+ case 7:
+ /* happens in "Network Watch" program (Cayman Systems) */
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "Reset Highest IUS");
+#endif
+ break;
+ case 0:
+ default:
+ /* Null Code */
+ break;
+ }
+}
+
+LOCALPROC SCC_PutWR1(ui3r Data, int chan)
+/*
+ "Transmit/Receive interrupt and data transfer mode definition"
+*/
+{
+#if EmLocalTalk || SCC_TrackMore
+ {
+ blnr NewExtIE = (Data & Bit0) != 0;
+ if (SCC.a[chan].ExtIE != NewExtIE) {
+ SCC.a[chan].ExtIE = NewExtIE;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan, "EXT INT Enable",
+ NewExtIE);
+#endif
+ /*
+ set to 1 on start up, set to 0 in MacCheck
+ and in Print to ImageWriter
+ */
+ }
+ }
+#endif
+
+ {
+ blnr NewTxIE = (Data & Bit1) != 0;
+ if (SCC.a[chan].TxIE != NewTxIE) {
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan, "Tx Int Enable",
+ NewTxIE);
+#endif
+ /* happens in MacCheck */
+ /* happens in Print to ImageWriter */
+ SCC.a[chan].TxIE = NewTxIE;
+ CheckSCCInterruptFlag();
+ }
+ }
+
+#if SCC_TrackMore
+ {
+ blnr NewPrtySpclCond = (Data & Bit2) != 0;
+ if (SCC.a[chan].PrtySpclCond != NewPrtySpclCond) {
+ SCC.a[chan].PrtySpclCond = NewPrtySpclCond;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Parity is special condition", NewPrtySpclCond);
+#endif
+ /*
+ set to 1 in MacCheck
+ and in Print to ImageWriter
+ */
+ }
+ }
+#endif
+
+#if EmLocalTalk || SCC_TrackMore
+ {
+ ui3r NewRxIntMode = (Data >> 3) & 3;
+ if (SCC.a[chan].RxIntMode != NewRxIntMode) {
+ SCC.a[chan].RxIntMode = NewRxIntMode;
+
+ switch (NewRxIntMode) {
+ case 0:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "Rx INT Disable");
+#endif
+ /* happens on boot always */
+ break;
+ case 1:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "Rx INT on 1st char"
+ " or special condition");
+#endif
+ SCC.a[chan].FirstChar = trueblnr;
+ /* happens on boot with appletalk on */
+ break;
+ case 2:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "INT on all Rx char"
+ " or special condition");
+#endif
+ /* happens in MacCheck */
+ /* happens in Print to ImageWriter */
+ break;
+ case 3:
+ ReportAbnormalID(0x070D,
+ "Rx INT on special condition only");
+ break;
+ }
+ }
+ }
+#endif
+
+#if SCC_TrackMore
+ {
+ blnr NewWaitRqstRT = (Data & Bit5) != 0;
+ if (SCC.a[chan].WaitRqstRT != NewWaitRqstRT) {
+ SCC.a[chan].WaitRqstRT = NewWaitRqstRT;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Wait/DMA request on receive/transmit",
+ NewWaitRqstRT);
+#endif
+ /* happens in MacCheck */
+ }
+ }
+#endif
+
+#if SCC_TrackMore
+ {
+ blnr NewWaitRqstSlct = (Data & Bit6) != 0;
+ if (SCC.a[chan].WaitRqstSlct != NewWaitRqstSlct) {
+ SCC.a[chan].WaitRqstSlct = NewWaitRqstSlct;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Wait/DMA request function", NewWaitRqstSlct);
+#endif
+ /* happens in MacCheck */
+ }
+ }
+#endif
+
+#if SCC_TrackMore
+ {
+ blnr NewWaitRqstEnbl = (Data & Bit7) != 0;
+ if (SCC.a[chan].WaitRqstEnbl != NewWaitRqstEnbl) {
+ SCC.a[chan].WaitRqstEnbl = NewWaitRqstEnbl;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Wait/DMA request enable", NewWaitRqstEnbl);
+#endif
+ /* happens in MacCheck */
+ }
+ }
+#endif
+}
+
+LOCALPROC SCC_PutWR2(ui3r Data, int chan)
+/* "Interrupt Vector (accessed through either channel)" */
+{
+ /*
+ Only 1 interrupt vector for the SCC, which
+ is stored in channels A and B. B is modified
+ when read.
+ */
+
+ /* happens on boot always */
+
+#if ! SCC_dolog
+ UnusedParam(chan);
+#endif
+
+ if (SCC.InterruptVector != Data) {
+#if SCC_dolog
+ SCC_DbgLogChanStartLine(chan);
+ dbglog_writeCStr(" InterruptVector <- ");
+ dbglog_writeHex(Data);
+ dbglog_writeReturn();
+#endif
+ SCC.InterruptVector = Data;
+ }
+ if ((Data & Bit0) != 0) { /* interrupt vector 0 */
+ ReportAbnormalID(0x070E, "interrupt vector 0");
+ }
+ if ((Data & Bit1) != 0) { /* interrupt vector 1 */
+ ReportAbnormalID(0x070F, "interrupt vector 1");
+ }
+ if ((Data & Bit2) != 0) { /* interrupt vector 2 */
+ ReportAbnormalID(0x0710, "interrupt vector 2");
+ }
+ if ((Data & Bit3) != 0) { /* interrupt vector 3 */
+ ReportAbnormalID(0x0711, "interrupt vector 3");
+ }
+ if ((Data & Bit4) != 0) { /* interrupt vector 4 */
+ /* happens on boot with appletalk on */
+ }
+ if ((Data & Bit5) != 0) { /* interrupt vector 5 */
+ /* happens on boot with appletalk on */
+ }
+ if ((Data & Bit6) != 0) { /* interrupt vector 6 */
+ ReportAbnormalID(0x0712, "interrupt vector 6");
+ }
+ if ((Data & Bit7) != 0) { /* interrupt vector 7 */
+ ReportAbnormalID(0x0713, "interrupt vector 7");
+ }
+}
+
+LOCALPROC SCC_PutWR3(ui3r Data, int chan)
+/* "Receive parameters and control" */
+{
+#if SCC_TrackMore
+ {
+ ui3r NewRBitsPerChar = (Data >> 6) & 3;
+ if (SCC.a[chan].RBitsPerChar != NewRBitsPerChar) {
+ SCC.a[chan].RBitsPerChar = NewRBitsPerChar;
+
+ switch (NewRBitsPerChar) {
+ case 0:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "Rx Bits/Character <- 5");
+#endif
+ break;
+ case 1:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "Rx Bits/Character <- 7");
+#endif
+ break;
+ case 2:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "Rx Bits/Character <- 6");
+#endif
+ break;
+ case 3:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "Rx Bits/Character <- 8");
+#endif
+ break;
+ }
+ }
+ }
+#endif
+
+ if ((Data & Bit5) != 0) { /* Auto Enables */
+ /*
+ use DCD input as receiver enable,
+ and set RTS output when transmit buffer empty
+ */
+ ReportAbnormalID(0x0714, "Auto Enables");
+ }
+
+ if ((Data & Bit4) != 0) { /* Enter Hunt Mode */
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "Enter Hunt Mode");
+#endif
+ /* happens on boot with appletalk on */
+ if (! (SCC.a[chan].SyncHunt)) {
+ SCC.a[chan].SyncHunt = trueblnr;
+
+#if 0 /* SyncHuntIE usually false */
+ if (SCC.a[chan].SyncHuntIE) {
+ SCC_Interrupt((chan == 0)
+ ? SCC_A_Ext
+ : SCC_B_Ext);
+ }
+#endif
+ }
+ }
+
+#if SCC_TrackMore
+ {
+ blnr NewRxCRCEnbl = (Data & Bit3) != 0;
+ if (SCC.a[chan].RxCRCEnbl != NewRxCRCEnbl) {
+ SCC.a[chan].RxCRCEnbl = NewRxCRCEnbl;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Rx CRC Enable", NewRxCRCEnbl);
+#endif
+ /* happens on boot with appletalk on */
+ }
+ }
+#endif
+
+#if EmLocalTalk || SCC_TrackMore
+ {
+ blnr NewAddrSrchMd = (Data & Bit2) != 0;
+ if (SCC.a[chan].AddrSrchMd != NewAddrSrchMd) {
+ SCC.a[chan].AddrSrchMd = NewAddrSrchMd;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Addr Search Mode (SDLC)", NewAddrSrchMd);
+#endif
+ /* happens on boot with appletalk on */
+ }
+ }
+#endif
+
+#if SCC_TrackMore
+ {
+ blnr NewSyncChrLdInhb = (Data & Bit1) != 0;
+ if (SCC.a[chan].SyncChrLdInhb != NewSyncChrLdInhb) {
+ SCC.a[chan].SyncChrLdInhb = NewSyncChrLdInhb;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Sync Char Load Inhibit", NewSyncChrLdInhb);
+#endif
+ /* happens on boot with appletalk on */
+ }
+ }
+#endif
+
+ {
+ blnr NewRxEnable = (Data & Bit0) != 0;
+ if (SCC.a[chan].RxEnable != NewRxEnable) {
+ SCC.a[chan].RxEnable = NewRxEnable;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Rx Enable", NewRxEnable);
+#endif
+ /* true on boot with appletalk on */
+ /* true on Print to ImageWriter */
+
+#if EmLocalTalk
+ if (! NewRxEnable) {
+#if SCC_dolog
+ if ((0 != chan) && (nullpr != LT_RxBuffer)) {
+ dbglog_WriteNote("SCC abandon packet");
+ }
+#endif
+
+ /*
+ Go back into the idle state if we were
+ waiting for EOF
+ */
+ SCC.a[chan].EndOfFrame = falseblnr;
+ SCC.a[chan].RxChrAvail = falseblnr;
+ SCC.a[chan].SyncHunt = trueblnr;
+ } else {
+ /* look for a packet */
+ LocalTalkTick();
+ }
+#endif
+ }
+ }
+}
+
+LOCALPROC SCC_PutWR4(ui3r Data, int chan)
+/* "Transmit/Receive miscellaneous parameters and modes" */
+{
+#if ! (EmLocalTalk || SCC_TrackMore)
+ UnusedParam(Data);
+ UnusedParam(chan);
+#endif
+
+#if SCC_TrackMore
+ {
+ blnr NewPrtyEnable = (Data & Bit0) != 0;
+ if (SCC.a[chan].PrtyEnable != NewPrtyEnable) {
+ SCC.a[chan].PrtyEnable = NewPrtyEnable;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Parity Enable", NewPrtyEnable);
+#endif
+ }
+ }
+#endif
+
+#if SCC_TrackMore
+ {
+ blnr NewPrtyEven = (Data & Bit1) != 0;
+ if (SCC.a[chan].PrtyEven != NewPrtyEven) {
+ SCC.a[chan].PrtyEven = NewPrtyEven;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Parity Enable", NewPrtyEven);
+#endif
+ }
+ }
+#endif
+
+#if SCC_TrackMore
+ {
+ ui3r NewStopBits = (Data >> 2) & 3;
+ if (SCC.a[chan].StopBits != NewStopBits) {
+ SCC.a[chan].StopBits = NewStopBits;
+
+ /* SCC_SetStopBits(chan, NewStopBits); */
+ switch (NewStopBits) {
+ case 0:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "Sync Modes Enable");
+#endif
+ break;
+ case 1:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "1 Stop Bit");
+#endif
+ break;
+ case 2:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "1 1/2 Stop Bits");
+#endif
+ break;
+ case 3:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "2 Stop Bits");
+#endif
+ break;
+ }
+ }
+ }
+#endif
+
+#if EmLocalTalk || SCC_TrackMore
+ {
+ ui3r NewSyncMode = (Data >> 4) & 3;
+ if (SCC.a[chan].SyncMode != NewSyncMode) {
+ SCC.a[chan].SyncMode = NewSyncMode;
+
+ switch (NewSyncMode) {
+ case 0:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "8 bit sync char");
+#endif
+ /* happens on boot always */
+ break;
+ case 1:
+ ReportAbnormalID(0x0715, "16 bit sync char");
+ break;
+ case 2:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "SDLC MODE");
+#endif
+ /* happens on boot with appletalk on */
+#if EmLocalTalk
+ SCC.a[chan].TxBufferEmpty = trueblnr;
+#endif
+ break;
+ case 3:
+ ReportAbnormalID(0x0716, "External sync mode");
+ break;
+ }
+ }
+ }
+#endif
+
+#if SCC_TrackMore
+ {
+ ui3r NewClockRate = (Data >> 6) & 3;
+ if (SCC.a[chan].ClockRate != NewClockRate) {
+ SCC.a[chan].ClockRate = NewClockRate;
+
+ switch (NewClockRate) {
+ case 0:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "Clock Rate <- X1");
+#endif
+ /* happens on boot with appletalk on */
+ break;
+ case 1:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "Clock Rate <- X16");
+#endif
+ /* happens on boot always */
+ break;
+ case 2:
+ ReportAbnormalID(0x0717, "Clock Rate <- X32");
+ break;
+ case 3:
+ ReportAbnormalID(0x0718, "Clock Rate <- X64");
+ break;
+ }
+ }
+ }
+#endif
+}
+
+LOCALPROC SCC_PutWR5(ui3r Data, int chan)
+/* "Transmit parameters and controls" */
+{
+ /* happens on boot with appletalk on */
+ /* happens in Print to ImageWriter */
+
+#if SCC_TrackMore
+ {
+ blnr NewTxCRCEnbl = (Data & Bit0) != 0;
+ if (SCC.a[chan].TxCRCEnbl != NewTxCRCEnbl) {
+ SCC.a[chan].TxCRCEnbl = NewTxCRCEnbl;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Tx CRC Enable", NewTxCRCEnbl);
+#endif
+ /* both values on boot with appletalk on */
+ }
+ }
+#endif
+
+#if SCC_TrackMore
+ {
+ blnr NewRTSctrl = (Data & Bit1) != 0;
+ if (SCC.a[chan].RTSctrl != NewRTSctrl) {
+ SCC.a[chan].RTSctrl = NewRTSctrl;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "RTS Control", NewRTSctrl);
+#endif
+ /* both values on boot with appletalk on */
+ /*
+ value of Request To Send output pin, when
+ Auto Enable is off
+ */
+ }
+ }
+#endif
+
+ if ((Data & Bit2) != 0) { /* SDLC/CRC-16 */
+ ReportAbnormalID(0x0719, "SDLC/CRC-16");
+ }
+
+ {
+ blnr NewTxEnable = (Data & Bit3) != 0;
+ if (SCC.a[chan].TxEnable != NewTxEnable) {
+ SCC.a[chan].TxEnable = NewTxEnable;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Tx Enable", NewTxEnable);
+#endif
+
+ if (NewTxEnable) {
+ /* happens on boot with appletalk on */
+ /* happens in Print to ImageWriter */
+#if EmLocalTalk
+ LT_TxBuffSz = 0;
+#endif
+ } else {
+#if EmLocalTalk
+ SCC.a[chan].TxBufferEmpty = trueblnr;
+#endif
+ }
+ }
+ }
+
+#if SCC_TrackMore
+ {
+ blnr NewSndBrkCtrl = (Data & Bit4) != 0;
+ if (SCC.a[chan].SndBrkCtrl != NewSndBrkCtrl) {
+ SCC.a[chan].SndBrkCtrl = NewSndBrkCtrl;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Send Break Control", NewSndBrkCtrl);
+#endif
+ /* true in Print to LaserWriter 300 */
+ }
+ }
+#endif
+
+#if SCC_TrackMore
+ {
+ ui3r NewTBitsPerChar = (Data >> 5) & 3;
+ if (SCC.a[chan].TBitsPerChar != NewTBitsPerChar) {
+ SCC.a[chan].TBitsPerChar = NewTBitsPerChar;
+
+ switch (NewTBitsPerChar) {
+ case 0:
+ ReportAbnormalID(0x071A, "Tx Bits/Character <- 5");
+ break;
+ case 1:
+ ReportAbnormalID(0x071B, "Tx Bits/Character <- 7");
+ break;
+ case 2:
+ ReportAbnormalID(0x071C, "Tx Bits/Character <- 6");
+ break;
+ case 3:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "Tx Bits/Character <- 8");
+#endif
+ /* happens on boot with appletalk on */
+ /* happens in Print to ImageWriter */
+ break;
+ }
+ }
+ }
+#endif
+
+#if SCC_TrackMore
+ {
+ blnr NewDTRctrl = (Data & Bit7) != 0;
+ if (SCC.a[chan].DTRctrl != NewDTRctrl) {
+ SCC.a[chan].DTRctrl = NewDTRctrl;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "Data Terminal Ready Control", NewDTRctrl);
+#endif
+ /* zero happens in MacCheck */
+ /*
+ value of Data Terminal Ready output pin,
+ when WR14 D2 = 0 (DTR/request function)
+ */
+ }
+ }
+#endif
+}
+
+LOCALPROC SCC_PutWR6(ui3r Data, int chan)
+/* "Sync characters or SDLC address field" */
+{
+ /* happens on boot with appletalk on */
+
+#if ! (EmLocalTalk || SCC_dolog)
+ UnusedParam(Data);
+#endif
+#if ! SCC_dolog
+ UnusedParam(chan);
+#endif
+
+#if SCC_dolog
+ SCC_DbgLogChanStartLine(chan);
+ dbglog_writeCStr(" Sync Char <- ");
+ dbglog_writeHex(Data);
+ dbglog_writeReturn();
+#endif
+
+#if EmLocalTalk
+ if (0 != Data) {
+ my_node_address = Data;
+ }
+#endif
+}
+
+LOCALPROC SCC_PutWR7(ui3r Data, int chan)
+/* "Sync character or SDLC flag" */
+{
+ /* happens on boot with appletalk on */
+
+#if ! SCC_TrackMore
+ UnusedParam(Data);
+ UnusedParam(chan);
+#endif
+
+#if SCC_TrackMore
+ if (2 == SCC.a[chan].SyncMode) {
+ if (0x7E != Data) {
+ ReportAbnormalID(0x071D,
+ "unexpect flag character for SDLC");
+ }
+ } else {
+ ReportAbnormalID(0x071E, "WR7 and not SDLC");
+ }
+#endif
+}
+
+LOCALPROC SCC_PutWR8(ui3r Data, int chan)
+/* "Transmit Buffer" */
+{
+ /* happens on boot with appletalk on */
+ /* happens in Print to ImageWriter */
+
+#if ! (EmLocalTalk || SCC_dolog)
+ UnusedParam(Data);
+#endif
+
+#if SCC_dolog
+ SCC_DbgLogChanStartLine(chan);
+ dbglog_writeCStr(" Transmit Buffer");
+ dbglog_writeCStr(" <- ");
+ dbglog_writeHex(Data);
+ dbglog_writeCStr(" '");
+ dbglog_writeMacChar(Data);
+ dbglog_writeCStr("'");
+ dbglog_writeReturn();
+#endif
+
+ if (SCC.a[chan].TxEnable) { /* Tx Enable */
+ /* Output (Data) to Modem(B) or Printer(A) Port */
+
+ /* happens on boot with appletalk on */
+#if EmLocalTalk
+ if (chan != 0) {
+ SCC_TxBuffPut(Data);
+ }
+#else
+#if 0 /* TxBufferEmpty always true */
+ SCC.a[chan].TxBufferEmpty = trueblnr;
+#endif
+ SCC.a[chan].TxUnderrun = trueblnr; /* underrun ? */
+#endif
+
+ SCC.a[chan].TxIP = trueblnr;
+ CheckSCCInterruptFlag();
+ } else {
+ ReportAbnormalID(0x071F,
+ "write when Transmit Buffer not Enabled");
+#if 0 /* TxBufferEmpty always true */
+ SCC.a[chan].TxBufferEmpty = falseblnr;
+#endif
+ }
+}
+
+LOCALPROC SCC_PutWR9(ui3r Data, int chan)
+/*
+ "Master interrupt control and reset
+ (accessed through either channel)"
+*/
+{
+ /* Only 1 WR9 in the SCC */
+
+ UnusedParam(chan);
+
+ if ((Data & Bit0) != 0) { /* VIS */
+ ReportAbnormalID(0x0720, "VIS");
+ }
+
+#if SCC_TrackMore
+ {
+ blnr NewNoVectorSlct = (Data & Bit1) != 0;
+ if (SCC.NoVectorSlct != NewNoVectorSlct) {
+ SCC.NoVectorSlct = NewNoVectorSlct;
+#if SCC_dolog
+ dbglog_WriteSetBool("SCC No Vector select",
+ NewNoVectorSlct);
+#endif
+ /* has both values on boot always */
+ }
+ }
+#endif
+
+ if ((Data & Bit2) != 0) { /* DLC */
+ ReportAbnormalID(0x0723, "DLC");
+ }
+
+ {
+ blnr NewMIE = (Data & Bit3) != 0;
+ /* has both values on boot always */
+ if (SCC.MIE != NewMIE) {
+ SCC.MIE = NewMIE;
+#if SCC_dolog
+ dbglog_WriteSetBool("SCC Master Interrupt Enable",
+ NewMIE);
+#endif
+ CheckSCCInterruptFlag();
+ }
+ }
+
+#if 0 /* StatusHiLo always false */
+ SCC.StatusHiLo = (Data & Bit4) != 0;
+#else
+ if ((Data & Bit4) != 0) { /* Status high/low */
+ ReportAbnormalID(0x0724, "Status high/low");
+ }
+#endif
+ if ((Data & Bit5) != 0) { /* WR9 b5 should be 0 */
+ ReportAbnormalID(0x0725, "WR9 b5 should be 0");
+ }
+
+ switch ((Data >> 6) & 3) {
+ case 1:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(1, "Channel Reset");
+#endif
+ /* happens on boot always */
+ SCC_ResetChannel(1);
+ CheckSCCInterruptFlag();
+ break;
+ case 2:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(0, "Channel Reset");
+#endif
+ /* happens on boot always */
+ SCC_ResetChannel(0);
+ CheckSCCInterruptFlag();
+ break;
+ case 3:
+#if SCC_dolog
+ dbglog_WriteNote("SCC Force Hardware Reset");
+#endif
+#if (CurEmMd >= kEmMd_SE) && (CurEmMd <= kEmMd_IIx)
+ /* don't report */
+#else
+ ReportAbnormalID(0x0726, "SCC_Reset");
+#endif
+ SCC_Reset();
+ CheckSCCInterruptFlag();
+ break;
+ case 0: /* No Reset */
+ default:
+ break;
+ }
+}
+
+LOCALPROC SCC_PutWR10(ui3r Data, int chan)
+/* "Miscellaneous transmitter/receiver control bits" */
+{
+ /* happens on boot with appletalk on */
+ /* happens in Print to ImageWriter */
+
+#if ! SCC_TrackMore
+ UnusedParam(chan);
+#endif
+
+ if ((Data & Bit0) != 0) { /* 6 bit/8 bit sync */
+ ReportAbnormalID(0x0727, "6 bit/8 bit sync");
+ }
+ if ((Data & Bit1) != 0) { /* loop mode */
+ ReportAbnormalID(0x0728, "loop mode");
+ }
+ if ((Data & Bit2) != 0) { /* abort/flag on underrun */
+ ReportAbnormalID(0x0729, "abort/flag on underrun");
+ }
+ if ((Data & Bit3) != 0) { /* mark/flag idle */
+ ReportAbnormalID(0x072A, "mark/flag idle");
+ }
+ if ((Data & Bit4) != 0) { /* go active on poll */
+ ReportAbnormalID(0x072B, "go active on poll");
+ }
+
+#if SCC_TrackMore
+ {
+ ui3r NewDataEncoding = (Data >> 5) & 3;
+ if (SCC.a[chan].DataEncoding != NewDataEncoding) {
+ SCC.a[chan].DataEncoding = NewDataEncoding;
+
+ switch (NewDataEncoding) {
+ case 0:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "Data Encoding <- NRZ");
+#endif
+ /* happens in MacCheck */
+ /* happens in Print to ImageWriter */
+ break;
+ case 1:
+ ReportAbnormalID(0x072C, "Data Encoding <- NRZI");
+ break;
+ case 2:
+ ReportAbnormalID(0x072D, "Data Encoding <- FM1");
+ break;
+ case 3:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "Data Encoding <- FM0");
+#endif
+ /* happens on boot with appletalk on */
+ break;
+ }
+ }
+ }
+#endif
+
+#if SCC_TrackMore
+ {
+ blnr NewCRCPreset = (Data & Bit7) != 0;
+ if (SCC.a[chan].CRCPreset != NewCRCPreset) {
+ SCC.a[chan].CRCPreset = NewCRCPreset;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "CRC preset I/O", NewCRCPreset);
+#endif
+ /* false happens in MacCheck */
+ /* true happens in Print to ImageWriter */
+ }
+ }
+#endif
+}
+
+LOCALPROC SCC_PutWR11(ui3r Data, int chan)
+/* "Clock mode control" */
+{
+ /* happens on boot with appletalk on */
+ /* happens in Print to ImageWriter */
+ /* happens in MacCheck */
+
+#if ! SCC_TrackMore
+ UnusedParam(chan);
+#endif
+
+#if SCC_TrackMore
+ /* Transmit External Control Selection */
+ {
+ ui3r NewTRxCsrc = Data & 3;
+ if (SCC.a[chan].TRxCsrc != NewTRxCsrc) {
+ SCC.a[chan].TRxCsrc = NewTRxCsrc;
+
+ switch (NewTRxCsrc) {
+ case 0:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "TRxC OUT = XTAL output");
+#endif
+ /* happens on boot with appletalk on */
+ /* happens in Print to ImageWriter */
+ /* happens in MacCheck */
+ break;
+ case 1:
+ ReportAbnormalID(0x072E,
+ "TRxC OUT = transmit clock");
+ break;
+ case 2:
+ ReportAbnormalID(0x072F,
+ "TRxC OUT = BR generator output");
+ break;
+ case 3:
+ ReportAbnormalID(0x0730, "TRxC OUT = dpll output");
+ break;
+ }
+ }
+ }
+#endif
+
+ if ((Data & Bit2) != 0) {
+ ReportAbnormalID(0x0731, "TRxC O/I");
+ }
+
+#if SCC_TrackMore
+ {
+ ui3r NewTClkSlct = (Data >> 3) & 3;
+ if (SCC.a[chan].TClkSlct != NewTClkSlct) {
+ SCC.a[chan].TClkSlct = NewTClkSlct;
+
+ switch (NewTClkSlct) {
+ case 0:
+ ReportAbnormalID(0x0732,
+ "transmit clock = RTxC pin");
+ break;
+ case 1:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "transmit clock = TRxC pin");
+#endif
+ /* happens in Print to LaserWriter 300 */
+ break;
+ case 2:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "transmit clock = BR generator output");
+#endif
+ /* happens on boot with appletalk on */
+ /* happens in Print to ImageWriter */
+ /* happens in MacCheck */
+ break;
+ case 3:
+ ReportAbnormalID(0x0733,
+ "transmit clock = dpll output");
+ break;
+ }
+ }
+ }
+#endif
+
+#if SCC_TrackMore
+ {
+ ui3r NewRClkSlct = (Data >> 5) & 3;
+ if (SCC.a[chan].RClkSlct != NewRClkSlct) {
+ SCC.a[chan].RClkSlct = NewRClkSlct;
+
+ switch (NewRClkSlct) {
+ case 0:
+ ReportAbnormalID(0x0734,
+ "receive clock = RTxC pin");
+ break;
+ case 1:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "receive clock = TRxC pin");
+#endif
+ /* happens in Print to LaserWriter 300 */
+ break;
+ case 2:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "receive clock = BR generator output");
+#endif
+ /* happens in MacCheck */
+ /* happens in Print to ImageWriter */
+ break;
+ case 3:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan,
+ "receive clock = dpll output");
+#endif
+ /* happens on boot with appletalk on */
+ break;
+ }
+ }
+ }
+#endif
+
+ if ((Data & Bit7) != 0) {
+ ReportAbnormalID(0x0735, "RTxC XTAL/NO XTAL");
+ }
+}
+
+LOCALPROC SCC_PutWR12(ui3r Data, int chan)
+/* "Lower byte of baud rate generator time constant" */
+{
+ /* happens on boot with appletalk on */
+ /* happens in Print to ImageWriter */
+
+#if ! SCC_TrackMore
+ UnusedParam(Data);
+ UnusedParam(chan);
+#endif
+
+#if SCC_TrackMore /* don't care about Baud */
+ if (SCC.a[chan].BaudLo != Data) {
+ SCC.a[chan].BaudLo = Data;
+
+#if SCC_dolog
+ SCC_DbgLogChanStartLine(chan);
+ dbglog_writeCStr(" BaudLo <- ");
+ dbglog_writeHex(Data);
+ dbglog_writeReturn();
+#endif
+ }
+#endif
+
+#if 0
+ SCC_SetBaud(chan,
+ SCC.a[chan].BaudLo + (SCC.a[chan].BaudHi << 8));
+ /* 380: BaudRate = 300 */
+ /* 94: BaudRate = 1200 */
+ /* 46: BaudRate = 2400 */
+ /* 22: BaudRate = 4800 */
+ /* 10: BaudRate = 9600 */
+ /* 4: BaudRate = 19200 */
+ /* 1: BaudRate = 38400 */
+ /* 0: BaudRate = 57600 */
+#endif
+}
+
+LOCALPROC SCC_PutWR13(ui3r Data, int chan)
+/* "Upper byte of baud rate generator time constant" */
+{
+ /* happens on boot with appletalk on */
+ /* happens in Print to ImageWriter */
+
+#if ! SCC_TrackMore
+ UnusedParam(Data);
+ UnusedParam(chan);
+#endif
+
+#if SCC_TrackMore /* don't care about Baud */
+ if (SCC.a[chan].BaudHi != Data) {
+ SCC.a[chan].BaudHi = Data;
+
+#if SCC_dolog
+ SCC_DbgLogChanStartLine(chan);
+ dbglog_writeCStr(" BaudHi <- ");
+ dbglog_writeHex(Data);
+ dbglog_writeReturn();
+#endif
+ }
+#endif
+
+#if 0
+ SCC_SetBaud(chan,
+ SCC.a[chan].BaudLo + (SCC.a[chan].BaudHi << 8));
+#endif
+}
+
+LOCALPROC SCC_PutWR14(ui3r Data, int chan)
+/* "Miscellaneous control bits" */
+{
+ /* happens on boot with appletalk on */
+
+#if ! (SCC_TrackMore || SCC_dolog)
+ UnusedParam(chan);
+#endif
+
+#if SCC_TrackMore
+ {
+ blnr NewBRGEnbl = (Data & Bit0) != 0;
+ if (SCC.a[chan].BRGEnbl != NewBRGEnbl) {
+ SCC.a[chan].BRGEnbl = NewBRGEnbl;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "BR generator enable", NewBRGEnbl);
+#endif
+ /* both values on boot with appletalk on */
+ /* true happens in Print to ImageWriter */
+ }
+ }
+#endif
+
+ if ((Data & Bit1) != 0) { /* BR generator source */
+ ReportAbnormalID(0x0736, "BR generator source");
+ }
+ if ((Data & Bit2) != 0) { /* DTR/request function */
+ ReportAbnormalID(0x0737, "DTR/request function");
+ }
+ if ((Data & Bit3) != 0) { /* auto echo */
+ ReportAbnormalID(0x0738, "auto echo");
+ }
+ if ((Data & Bit4) != 0) { /* local loopback */
+ ReportAbnormalID(0x0739, "local loopback");
+ }
+
+ switch ((Data >> 5) & 7) {
+ case 1:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "enter search mode");
+#endif
+ /* happens on boot with appletalk on */
+ break;
+ case 2:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "reset missing clock");
+#endif
+ /* happens on boot with appletalk on */
+ /*
+ should clear Bit 6 and Bit 7 of RR[10], but
+ since these are never set, don't need
+ to do anything
+ */
+ break;
+ case 3:
+ ReportAbnormalID(0x073A, "disable dpll");
+ /*
+ should clear Bit 6 and Bit 7 of RR[10], but
+ since these are never set, don't need
+ to do anything
+ */
+ break;
+ case 4:
+ ReportAbnormalID(0x073B, "set source = br generator");
+ break;
+ case 5:
+ ReportAbnormalID(0x073C, "set source = RTxC");
+ break;
+ case 6:
+#if SCC_dolog
+ SCC_DbgLogChanCmnd(chan, "set FM mode");
+#endif
+ /* happens on boot with appletalk on */
+ break;
+ case 7:
+ ReportAbnormalID(0x073D, "set NRZI mode");
+ break;
+ case 0: /* No Reset */
+ default:
+ break;
+ }
+}
+
+LOCALPROC SCC_PutWR15(ui3r Data, int chan)
+/* "External/Status interrupt control" */
+{
+ /* happens on boot always */
+
+#if ! SCC_TrackMore
+ UnusedParam(chan);
+#endif
+
+ if ((Data & Bit0) != 0) { /* WR15 b0 should be 0 */
+ ReportAbnormalID(0x073E, "WR15 b0 should be 0");
+ }
+ if ((Data & Bit1) != 0) { /* zero count IE */
+ ReportAbnormalID(0x073F, "zero count IE");
+ }
+ if ((Data & Bit2) != 0) { /* WR15 b2 should be 0 */
+ ReportAbnormalID(0x0740, "WR15 b2 should be 0");
+ }
+
+#if 0 /* don't care about DCD_IE, always true */
+ SCC.a[chan].DCD_IE = (Data & Bit3) != 0;
+#else
+ if ((Data & Bit3) == 0) { /* DCD_IE */
+#if (CurEmMd >= kEmMd_SE) && (CurEmMd <= kEmMd_IIx)
+ /* don't report */
+#else
+ ReportAbnormalID(0x0741, "not DCD IE");
+#endif
+ }
+#endif
+
+#if 0 /* SyncHuntIE usually false */
+ SCC.a[chan].SyncHuntIE = (Data & Bit4) != 0;
+#else
+ if ((Data & Bit4) != 0) {
+ /* SYNC/HUNT IE */
+ ReportAbnormalID(0x0742, "SYNC/HUNT IE");
+ }
+#endif
+
+#if SCC_TrackMore /* don't care about CTS_IE */
+ {
+ blnr NewCTS_IE = (Data & Bit5) != 0;
+ if (SCC.a[chan].CTS_IE != NewCTS_IE) {
+ SCC.a[chan].CTS_IE = NewCTS_IE;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "CTS IE", NewCTS_IE);
+#endif
+ /* happens in MacCheck */
+ /* happens in Print to ImageWriter */
+ }
+ }
+#endif
+
+ if ((Data & Bit6) != 0) { /* Tx underrun/EOM IE */
+ ReportAbnormalID(0x0743, "Tx underrun/EOM IE");
+ }
+
+#if SCC_TrackMore
+ {
+ blnr NewBreakAbortIE = (Data & Bit7) != 0;
+ if (SCC.a[chan].BreakAbortIE != NewBreakAbortIE) {
+ SCC.a[chan].BreakAbortIE = NewBreakAbortIE;
+#if SCC_dolog
+ SCC_DbgLogChanChngBit(chan,
+ "BreakAbort IE", NewBreakAbortIE);
+#endif
+ /* happens in MacCheck */
+ /* happens in Print to ImageWriter */
+ }
+ }
+#endif
+}
+
+LOCALFUNC ui3r SCC_GetReg(int chan, ui3r SCC_Reg)
+{
+ ui3r value;
+
+ switch (SCC_Reg) {
+ case 0:
+ value = SCC_GetRR0(chan);
+ break;
+ case 1:
+ value = SCC_GetRR1(chan);
+ break;
+ case 2:
+ value = SCC_GetRR2(chan);
+ break;
+ case 3:
+ value = SCC_GetRR3(chan);
+ break;
+ case 4:
+ ReportAbnormalID(0x0744, "RR 4"); /* same as RR0 */
+ value = SCC_GetRR0(chan);
+ break;
+ case 5:
+ ReportAbnormalID(0x0745, "RR 5"); /* same as RR1 */
+ value = SCC_GetRR1(chan);
+ break;
+ case 6:
+ ReportAbnormalID(0x0746, "RR 6"); /* same as RR2 */
+ value = SCC_GetRR2(chan);
+ break;
+ case 7:
+ ReportAbnormalID(0x0747, "RR 7"); /* same as RR3 */
+ value = SCC_GetRR3(chan);
+ break;
+ case 8:
+ value = SCC_GetRR8(chan);
+ break;
+ case 9:
+ ReportAbnormalID(0x0748, "RR 9"); /* same as RR13 */
+ value = SCC_GetRR13(chan);
+ break;
+ case 10:
+ value = SCC_GetRR10(chan);
+ break;
+ case 11:
+ ReportAbnormalID(0x0749, "RR 11"); /* same as RR15 */
+ value = SCC_GetRR15(chan);
+ break;
+ case 12:
+ value = SCC_GetRR12(chan);
+ break;
+ case 13:
+ value = SCC_GetRR13(chan);
+ break;
+ case 14:
+ ReportAbnormalID(0x074A, "RR 14");
+ value = 0;
+ break;
+ case 15:
+ value = SCC_GetRR15(chan);
+ break;
+ default:
+ ReportAbnormalID(0x074B,
+ "unexpected SCC_Reg in SCC_GetReg");
+ value = 0;
+ break;
+ }
+
+#if EmLocalTalk
+ /*
+ Always check to see if interrupt state changed after
+ ANY register access
+ */
+ CheckSCCInterruptFlag();
+#endif
+
+#if SCC_dolog
+ SCC_DbgLogChanStartLine(chan);
+ dbglog_writeCStr(" RR[");
+ dbglog_writeHex(SCC_Reg);
+ dbglog_writeCStr("] -> ");
+ dbglog_writeHex(value);
+ dbglog_writeReturn();
+#endif
+
+ return value;
+}
+
+LOCALPROC SCC_PutReg(ui3r Data, int chan, ui3r SCC_Reg)
+{
+#if SCC_dolog && 0
+ SCC_DbgLogChanStartLine(chan);
+ dbglog_writeCStr(" WR[");
+ dbglog_writeHex(SCC_Reg);
+ dbglog_writeCStr("] <- ");
+ dbglog_writeHex(Data);
+ dbglog_writeReturn();
+#endif
+
+ switch (SCC_Reg) {
+ case 0:
+ SCC_PutWR0(Data, chan);
+ break;
+ case 1:
+ SCC_PutWR1(Data, chan);
+ break;
+ case 2:
+ SCC_PutWR2(Data, chan);
+ break;
+ case 3:
+ SCC_PutWR3(Data, chan);
+ break;
+ case 4:
+ SCC_PutWR4(Data, chan);
+ break;
+ case 5:
+ SCC_PutWR5(Data, chan);
+ break;
+ case 6:
+ SCC_PutWR6(Data, chan);
+ break;
+ case 7:
+ SCC_PutWR7(Data, chan);
+ break;
+ case 8:
+ SCC_PutWR8(Data, chan);
+ break;
+ case 9:
+ SCC_PutWR9(Data, chan);
+ break;
+ case 10:
+ SCC_PutWR10(Data, chan);
+ break;
+ case 11:
+ SCC_PutWR11(Data, chan);
+ break;
+ case 12:
+ SCC_PutWR12(Data, chan);
+ break;
+ case 13:
+ SCC_PutWR13(Data, chan);
+ break;
+ case 14:
+ SCC_PutWR14(Data, chan);
+ break;
+ case 15:
+ SCC_PutWR15(Data, chan);
+ break;
+ default:
+ ReportAbnormalID(0x074C,
+ "unexpected SCC_Reg in SCC_PutReg");
+ break;
+ }
+
+#if EmLocalTalk
+ /*
+ Always check to see if interrupt state changed after ANY
+ register access
+ */
+ CheckSCCInterruptFlag();
+#endif
+}
+
+GLOBALFUNC ui5b SCC_Access(ui5b Data, blnr WriteMem, CPTR addr)
+{
+#if EmLocalTalk
+ /*
+ Determine channel, data, and access type from address. The bus
+ for the 8350 is non-standard, so the Macintosh connects address
+ bus lines to various signals on the 8350 as shown below. The
+ 68K will use the upper byte of the data bus for odd addresses,
+ and the 8350 is only wired to the upper byte, therefore use
+ only odd addresses or you risk resetting the 8350.
+
+ 68k 8350
+ ----- ------
+ a1 a/b
+ a2 d/c
+ a21 wr/rd
+ */
+#endif
+ ui3b SCC_Reg;
+ int chan = (~ addr) & 1; /* 0=modem, 1=printer */
+ if (((addr >> 1) & 1) == 0) {
+ /* Channel Control */
+ SCC_Reg = SCC.PointerBits;
+ SCC.PointerBits = 0;
+ } else {
+ /* Channel Data */
+ SCC_Reg = 8;
+ }
+ if (WriteMem) {
+ SCC_PutReg(Data, chan, SCC_Reg);
+ } else {
+ Data = SCC_GetReg(chan, SCC_Reg);
+ }
+
+ return Data;
+}
--- /dev/null
+++ b/src/SCCEMDEV.h
@@ -1,0 +1,32 @@
+/*
+ SCCEMDEV.h
+
+ Copyright (C) 2004 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef SCCEMDEV_H
+#error "header already included"
+#else
+#define SCCEMDEV_H
+#endif
+
+EXPORTPROC SCC_Reset(void);
+
+EXPORTFUNC ui5b SCC_Access(ui5b Data, blnr WriteMem, CPTR addr);
+
+EXPORTFUNC blnr SCC_InterruptsEnabled(void);
+
+#if EmLocalTalk
+EXPORTPROC LocalTalkTick(void);
+EXPORTFUNC int InitLocalTalk(void);
+#endif
--- /dev/null
+++ b/src/SCRNEMDV.c
@@ -1,0 +1,59 @@
+/*
+ SCRNEMDV.c
+
+ Copyright (C) 2006 Philip Cummins, Richard F. Bannister,
+ Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ SCReeN EMulated DeVice
+
+ Emulation of the screen in the Mac Plus.
+
+ This code descended from "Screen-MacOS.c" in Richard F. Bannister's
+ Macintosh port of vMac, by Philip Cummins.
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+#include "MYOSGLUE.h"
+#include "ENDIANAC.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#endif
+
+#include "SCRNEMDV.h"
+
+#if ! IncludeVidMem
+#define kMain_Offset 0x5900
+#define kAlternate_Offset 0xD900
+#define kMain_Buffer (kRAM_Size - kMain_Offset)
+#define kAlternate_Buffer (kRAM_Size - kAlternate_Offset)
+#endif
+
+GLOBALPROC Screen_EndTickNotify(void)
+{
+ ui3p screencurrentbuff;
+
+#if IncludeVidMem
+ screencurrentbuff = VidMem;
+#else
+ if (SCRNvPage2 == 1) {
+ screencurrentbuff = get_ram_address(kMain_Buffer);
+ } else {
+ screencurrentbuff = get_ram_address(kAlternate_Buffer);
+ }
+#endif
+
+ Screen_OutputFrame(screencurrentbuff);
+}
--- /dev/null
+++ b/src/SCRNEMDV.h
@@ -1,0 +1,24 @@
+/*
+ SCRNEMDV.h
+
+ Copyright (C) 2006 Philip Cummins, Richard F. Bannister,
+ Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef SCRNEMDV_H
+#error "header already included"
+#else
+#define SCRNEMDV_H
+#endif
+
+EXPORTPROC Screen_EndTickNotify(void);
--- /dev/null
+++ b/src/SCRNHACK.h
@@ -1,0 +1,397 @@
+/*
+ SCRNHACK.h
+
+ Copyright (C) 2007 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ SCReeN Hack
+
+ Patch ROM to support other screen sizes.
+*/
+
+
+#if CurEmMd <= kEmMd_128K
+ do_put_mem_long(112 + ROM, kVidMem_Base);
+ do_put_mem_long(260 + ROM, kVidMem_Base);
+ do_put_mem_long(292 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 + 9) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 24))
+ / 8);
+
+ /* sad mac, error code */
+ do_put_mem_word(330 + ROM, vMacScreenWidth / 8);
+ do_put_mem_word(342 + ROM, vMacScreenWidth / 8);
+ do_put_mem_word(350 + ROM, vMacScreenWidth / 4 * 3 - 1);
+ /* sad mac, blink pixels */
+ do_put_mem_word(358 + ROM, vMacScreenWidth - 4);
+
+ do_put_mem_word(456 + ROM,
+ (vMacScreenHeight * vMacScreenWidth / 32) - 1 + 32);
+
+ /* screen setup, main */
+ {
+ pto = 862 + ROM;
+ do_put_mem_word(pto, 0x4EB9); /* JSR */
+ pto += 2;
+ do_put_mem_long(pto, kROM_Base + (patchp - ROM));
+ pto += 4;
+
+ do_put_mem_word(patchp, 0x21FC); /* MOVE.L */
+ patchp += 2;
+ do_put_mem_long(patchp, kVidMem_Base); /* kVidMem_Base */
+ patchp += 4;
+ do_put_mem_word(patchp, 0x0824); /* (ScrnBase) */
+ patchp += 2;
+ do_put_mem_word(patchp, 0x4E75); /* RTS */
+ patchp += 2;
+ }
+ do_put_mem_word(892 + ROM, vMacScreenHeight - 1);
+ do_put_mem_word(894 + ROM, vMacScreenWidth - 1);
+
+ /* blink floppy, disk icon */
+ do_put_mem_long(1388 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 - 25) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 16))
+ / 8);
+ /* blink floppy, question mark */
+ do_put_mem_long(1406 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 - 10) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 8))
+ / 8);
+
+ /* blink floppy and sadmac, position */
+ do_put_mem_word(1966 + ROM, vMacScreenWidth / 8 - 4);
+ do_put_mem_word(1982 + ROM, vMacScreenWidth / 8);
+ /* sad mac, mac icon */
+ do_put_mem_long(2008 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 - 25) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 16))
+ / 8);
+ /* sad mac, frown */
+ do_put_mem_long(2020 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 - 19) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 8))
+ / 8);
+ do_put_mem_word(2052 + ROM, vMacScreenWidth / 8 - 2);
+
+ /* cursor handling */
+#if vMacScreenWidth >= 1024
+ pto = 3448 + ROM;
+ do_put_mem_word(pto, 0x4EB9); /* JSR */
+ pto += 2;
+ do_put_mem_long(pto, kROM_Base + (patchp - ROM));
+ pto += 4;
+
+ do_put_mem_word(patchp, 0x41F8); /* Lea.L (CrsrSave),A0 */
+ patchp += 2;
+ do_put_mem_word(patchp, 0x088C);
+ patchp += 2;
+ do_put_mem_word(patchp, 0x203C); /* MOVE.L #$x,D0 */
+ patchp += 2;
+ do_put_mem_long(patchp, (vMacScreenWidth / 8));
+ patchp += 4;
+ do_put_mem_word(patchp, 0x4E75); /* RTS */
+ patchp += 2;
+#else
+ do_put_mem_word(3452 + ROM, 0x7000 + (vMacScreenWidth / 8));
+#endif
+ do_put_mem_word(3572 + ROM, vMacScreenWidth - 32);
+ do_put_mem_word(3578 + ROM, vMacScreenWidth - 32);
+ do_put_mem_word(3610 + ROM, vMacScreenHeight - 16);
+ do_put_mem_word(3616 + ROM, vMacScreenHeight);
+#if vMacScreenWidth >= 1024
+ pto = 3646 + ROM;
+ do_put_mem_word(pto, 0x4EB9); /* JSR */
+ pto += 2;
+ do_put_mem_long(pto, kROM_Base + (patchp - ROM));
+ pto += 4;
+
+ do_put_mem_word(patchp, 0x2A3C); /* MOVE.L #$x,D5 */
+ patchp += 2;
+ do_put_mem_long(patchp, (vMacScreenWidth / 8));
+ patchp += 4;
+ do_put_mem_word(patchp, 0xC2C5); /* MulU D5,D1 */
+ patchp += 2;
+ do_put_mem_word(patchp, 0xD3C1); /* AddA.L D1,A1 */
+ patchp += 2;
+ do_put_mem_word(patchp, 0x4E75); /* RTS */
+ patchp += 2;
+#else
+ do_put_mem_word(3646 + ROM, 0x7A00 + (vMacScreenWidth / 8));
+#endif
+
+ /* set up screen bitmap */
+ do_put_mem_word(3832 + ROM, vMacScreenHeight);
+ do_put_mem_word(3838 + ROM, vMacScreenWidth);
+ /* do_put_mem_word(7810 + ROM, vMacScreenHeight); */
+
+#elif CurEmMd <= kEmMd_Plus
+
+ do_put_mem_long(138 + ROM, kVidMem_Base);
+ do_put_mem_long(326 + ROM, kVidMem_Base);
+ do_put_mem_long(356 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 + 9) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 24))
+ / 8);
+
+ /* sad mac, error code */
+ do_put_mem_word(392 + ROM, vMacScreenWidth / 8);
+ do_put_mem_word(404 + ROM, vMacScreenWidth / 8);
+ do_put_mem_word(412 + ROM, vMacScreenWidth / 4 * 3 - 1);
+ /* sad mac, blink pixels */
+ do_put_mem_long(420 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 + 17) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 8))
+ / 8);
+
+ do_put_mem_word(494 + ROM,
+ (vMacScreenHeight * vMacScreenWidth / 32) - 1);
+
+ /* screen setup, main */
+ {
+ pto = 1132 + ROM;
+ do_put_mem_word(pto, 0x4EB9); /* JSR */
+ pto += 2;
+ do_put_mem_long(pto, kROM_Base + (patchp - ROM));
+ pto += 4;
+
+ do_put_mem_word(patchp, 0x21FC); /* MOVE.L */
+ patchp += 2;
+ do_put_mem_long(patchp, kVidMem_Base); /* kVidMem_Base */
+ patchp += 4;
+ do_put_mem_word(patchp, 0x0824); /* (ScrnBase) */
+ patchp += 2;
+ do_put_mem_word(patchp, 0x4E75); /* RTS */
+ patchp += 2;
+ }
+ do_put_mem_word(1140 + ROM, vMacScreenWidth / 8);
+ do_put_mem_word(1172 + ROM, vMacScreenHeight);
+ do_put_mem_word(1176 + ROM, vMacScreenWidth);
+
+ /* blink floppy, disk icon */
+ do_put_mem_long(2016 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 - 25) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 16))
+ / 8);
+ /* blink floppy, question mark */
+ do_put_mem_long(2034 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 - 10) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 8))
+ / 8);
+
+ do_put_mem_word(2574 + ROM, vMacScreenHeight);
+ do_put_mem_word(2576 + ROM, vMacScreenWidth);
+
+ /* blink floppy and sadmac, position */
+ do_put_mem_word(3810 + ROM, vMacScreenWidth / 8 - 4);
+ do_put_mem_word(3826 + ROM, vMacScreenWidth / 8);
+ /* sad mac, mac icon */
+ do_put_mem_long(3852 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 - 25) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 16))
+ / 8);
+ /* sad mac, frown */
+ do_put_mem_long(3864 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 - 19) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 8))
+ / 8);
+ do_put_mem_word(3894 + ROM, vMacScreenWidth / 8 - 2);
+
+ /* cursor handling */
+#if vMacScreenWidth >= 1024
+ pto = 7372 + ROM;
+ do_put_mem_word(pto, 0x4EB9); /* JSR */
+ pto += 2;
+ do_put_mem_long(pto, kROM_Base + (patchp - ROM));
+ pto += 4;
+
+ do_put_mem_word(patchp, 0x41F8); /* Lea.L (CrsrSave), A0 */
+ patchp += 2;
+ do_put_mem_word(patchp, 0x088C);
+ patchp += 2;
+ do_put_mem_word(patchp, 0x203C); /* MOVE.L #$x, D0 */
+ patchp += 2;
+ do_put_mem_long(patchp, (vMacScreenWidth / 8));
+ patchp += 4;
+ do_put_mem_word(patchp, 0x4E75); /* RTS */
+ patchp += 2;
+#else
+ do_put_mem_word(7376 + ROM, 0x7000 + (vMacScreenWidth / 8));
+#endif
+ do_put_mem_word(7496 + ROM, vMacScreenWidth - 32);
+ do_put_mem_word(7502 + ROM, vMacScreenWidth - 32);
+ do_put_mem_word(7534 + ROM, vMacScreenHeight - 16);
+ do_put_mem_word(7540 + ROM, vMacScreenHeight);
+#if vMacScreenWidth >= 1024
+ pto = 7570 + ROM;
+ do_put_mem_word(pto, 0x4EB9); /* JSR */
+ pto += 2;
+ do_put_mem_long(pto, kROM_Base + (patchp - ROM));
+ pto += 4;
+
+ do_put_mem_word(patchp, 0x2A3C); /* MOVE.L #$x,D5 */
+ patchp += 2;
+ do_put_mem_long(patchp, (vMacScreenWidth / 8));
+ patchp += 4;
+ do_put_mem_word(patchp, 0xC2C5); /* MulU D5,D1 */
+ patchp += 2;
+ do_put_mem_word(patchp, 0xD3C1); /* AddA.L D1,A1 */
+ patchp += 2;
+ do_put_mem_word(patchp, 0x4E75); /* RTS */
+ patchp += 2;
+#else
+ do_put_mem_word(7570 + ROM, 0x7A00 + (vMacScreenWidth / 8));
+#endif
+
+ /* set up screen bitmap */
+ do_put_mem_word(7784 + ROM, vMacScreenHeight);
+ do_put_mem_word(7790 + ROM, vMacScreenWidth);
+ do_put_mem_word(7810 + ROM, vMacScreenHeight);
+
+#if 0
+ /*
+ Haven't got these working. Alert outlines ok, but
+ not contents. Perhaps global position of contents
+ stored in system resource file.
+ */
+
+ /* perhaps switch disk alert */
+ do_put_mem_word(10936 + ROM, vMacScreenHeight / 2 - 91);
+ do_put_mem_word(10938 + ROM, vMacScreenWidth / 2 - 136);
+ do_put_mem_word(10944 + ROM, vMacScreenHeight / 2 - 19);
+ do_put_mem_word(10946 + ROM, vMacScreenWidth / 2 + 149);
+
+ do_put_mem_word(11008 + ROM, ?);
+ do_put_mem_word(11010 + ROM, ?);
+
+ /* DSAlertRect */
+ do_put_mem_word(4952 + ROM, vMacScreenHeight / 2 - 107);
+ do_put_mem_word(4954 + ROM, vMacScreenWidth / 2 - 236);
+ do_put_mem_word(4958 + ROM, vMacScreenHeight / 2 + 19);
+ do_put_mem_word(4960 + ROM, vMacScreenWidth / 2 + 236);
+
+ do_put_mem_word(5212 + ROM, vMacScreenHeight / 2 - 101);
+ do_put_mem_word(5214 + ROM, vMacScreenWidth / 2 - 218);
+#endif
+
+#elif CurEmMd <= kEmMd_Classic
+
+ /* screen setup, main */
+ {
+ pto = 1482 + ROM;
+ do_put_mem_word(pto, 0x4EB9); /* JSR */
+ pto += 2;
+ do_put_mem_long(pto, kROM_Base + (patchp - ROM));
+ pto += 4;
+
+ do_put_mem_word(patchp, 0x21FC); /* MOVE.L */
+ patchp += 2;
+ do_put_mem_long(patchp, kVidMem_Base); /* kVidMem_Base */
+ patchp += 4;
+ do_put_mem_word(patchp, 0x0824); /* (ScrnBase) */
+ patchp += 2;
+ do_put_mem_word(patchp, 0x4E75); /* RTS */
+ patchp += 2;
+ }
+ do_put_mem_word(1490 + ROM, vMacScreenWidth / 8);
+ do_put_mem_word(1546 + ROM, vMacScreenHeight);
+ do_put_mem_word(1550 + ROM, vMacScreenWidth);
+
+ do_put_mem_word(2252 + ROM, vMacScreenHeight);
+ do_put_mem_word(2254 + ROM, vMacScreenWidth);
+
+ /* blink floppy, disk icon */
+ do_put_mem_long(3916 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 - 25) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 16))
+ / 8);
+ /* blink floppy, question mark */
+ do_put_mem_long(3934 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 - 10) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 8))
+ / 8);
+
+ do_put_mem_long(4258 + ROM, kVidMem_Base);
+ do_put_mem_word(4264 + ROM, vMacScreenHeight);
+ do_put_mem_word(4268 + ROM, vMacScreenWidth);
+ do_put_mem_word(4272 + ROM, vMacScreenWidth / 8);
+ do_put_mem_long(4276 + ROM, vMacScreenNumBytes);
+
+ /* sad mac, mac icon */
+ do_put_mem_long(4490 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 - 25) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 16))
+ / 8);
+ /* sad mac, frown */
+ do_put_mem_long(4504 + ROM, kVidMem_Base
+ + (((vMacScreenHeight / 4) * 2 - 19) * vMacScreenWidth
+ + (vMacScreenWidth / 2 - 8))
+ / 8);
+ do_put_mem_word(4528 + ROM, vMacScreenWidth / 8);
+ /* blink floppy and sadmac, position */
+ do_put_mem_word(4568 + ROM, vMacScreenWidth / 8);
+ do_put_mem_word(4586 + ROM, vMacScreenWidth / 8);
+
+ /* cursor handling */
+#if vMacScreenWidth >= 1024
+ pto = 101886 + ROM;
+ do_put_mem_word(pto, 0x4EB9); /* JSR */
+ pto += 2;
+ do_put_mem_long(pto, kROM_Base + (patchp - ROM));
+ pto += 4;
+
+ do_put_mem_word(patchp, 0x41F8); /* Lea.L (CrsrSave),A0 */
+ patchp += 2;
+ do_put_mem_word(patchp, 0x088C);
+ patchp += 2;
+ do_put_mem_word(patchp, 0x203C); /* MOVE.L #$x,D0 */
+ patchp += 2;
+ do_put_mem_long(patchp, (vMacScreenWidth / 8));
+ patchp += 4;
+ do_put_mem_word(patchp, 0x4E75); /* RTS */
+ patchp += 2;
+#else
+ do_put_mem_word(101890 + ROM, 0x7000 + (vMacScreenWidth / 8));
+#endif
+ do_put_mem_word(102010 + ROM, vMacScreenWidth - 32);
+ do_put_mem_word(102016 + ROM, vMacScreenWidth - 32);
+ do_put_mem_word(102048 + ROM, vMacScreenHeight - 16);
+ do_put_mem_word(102054 + ROM, vMacScreenHeight);
+#if vMacScreenWidth >= 1024
+ pto = 102084 + ROM;
+ do_put_mem_word(pto, 0x4EB9); /* JSR */
+ pto += 2;
+ do_put_mem_long(pto, kROM_Base + (patchp - ROM));
+ pto += 4;
+
+ do_put_mem_word(patchp, 0x2A3C); /* MOVE.L #$x, D5 */
+ patchp += 2;
+ do_put_mem_long(patchp, (vMacScreenWidth / 8));
+ patchp += 4;
+ do_put_mem_word(patchp, 0xC2C5); /* MulU D5, D1 */
+ patchp += 2;
+ do_put_mem_word(patchp, 0xD3C1); /* AddA.L D1, A1 */
+ patchp += 2;
+ do_put_mem_word(patchp, 0x4E75); /* RTS */
+ patchp += 2;
+#else
+ do_put_mem_word(102084 + ROM, 0x7A00 + (vMacScreenWidth / 8));
+#endif
+
+ /* set up screen bitmap */
+ do_put_mem_word(102298 + ROM, vMacScreenHeight);
+ do_put_mem_word(102304 + ROM, vMacScreenWidth);
+ do_put_mem_word(102324 + ROM, vMacScreenHeight);
+
+#endif
--- /dev/null
+++ b/src/SCRNMAPR.h
@@ -1,0 +1,168 @@
+/*
+ SCRNMAPR.h
+
+ Copyright (C) 2012 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ SCReeN MAPpeR
+*/
+
+/* required arguments for this template */
+
+#ifndef ScrnMapr_DoMap /* procedure to be created by this template */
+#error "ScrnMapr_DoMap not defined"
+#endif
+#ifndef ScrnMapr_Src
+#error "ScrnMapr_Src not defined"
+#endif
+#ifndef ScrnMapr_Dst
+#error "ScrnMapr_Dst not defined"
+#endif
+#ifndef ScrnMapr_SrcDepth
+#error "ScrnMapr_SrcDepth not defined"
+#endif
+#ifndef ScrnMapr_DstDepth
+#error "ScrnMapr_DstDepth not defined"
+#endif
+#ifndef ScrnMapr_Map
+#error "ScrnMapr_Map not defined"
+#endif
+
+/* optional argument for this template */
+
+#ifndef ScrnMapr_Scale
+#define ScrnMapr_Scale 1
+#endif
+
+/* check of parameters */
+
+#if (ScrnMapr_SrcDepth < 0) || (ScrnMapr_SrcDepth > 3)
+#error "bad ScrnMapr_SrcDepth"
+#endif
+
+#if (ScrnMapr_DstDepth < ScrnMapr_SrcDepth)
+#error "bad ScrnMapr_Dst"
+#endif
+
+/* calculate a few things local to this template */
+
+#define ScrnMapr_MapElSz \
+ (ScrnMapr_Scale << (ScrnMapr_DstDepth - ScrnMapr_SrcDepth))
+
+#if 0 == (ScrnMapr_MapElSz & 3)
+#define ScrnMapr_TranT ui5b
+#define ScrnMapr_TranLn2Sz 2
+#elif 0 == (ScrnMapr_MapElSz & 1)
+#define ScrnMapr_TranT ui4b
+#define ScrnMapr_TranLn2Sz 1
+#else
+#define ScrnMapr_TranT ui3b
+#define ScrnMapr_TranLn2Sz 0
+#endif
+
+#define ScrnMapr_TranN (ScrnMapr_MapElSz >> ScrnMapr_TranLn2Sz)
+
+#define ScrnMapr_ScrnWB (vMacScreenWidth >> (3 - ScrnMapr_SrcDepth))
+
+/* now define the procedure */
+
+LOCALPROC ScrnMapr_DoMap(si4b top, si4b left,
+ si4b bottom, si4b right)
+{
+ int i;
+ int j;
+#if (ScrnMapr_TranN > 4) || (ScrnMapr_Scale > 2)
+ int k;
+#endif
+ ui5r t0;
+ ScrnMapr_TranT *pMap;
+#if ScrnMapr_Scale > 1
+ ScrnMapr_TranT *p3;
+#endif
+
+ ui4r leftB = left >> (3 - ScrnMapr_SrcDepth);
+ ui4r rightB = (right + (1 << (3 - ScrnMapr_SrcDepth)) - 1)
+ >> (3 - ScrnMapr_SrcDepth);
+ ui4r jn = rightB - leftB;
+ ui4r SrcSkip = ScrnMapr_ScrnWB - jn;
+ ui3b *pSrc = ((ui3b *)ScrnMapr_Src)
+ + leftB + ScrnMapr_ScrnWB * (ui5r)top;
+ ScrnMapr_TranT *pDst = ((ScrnMapr_TranT *)ScrnMapr_Dst)
+ + ((leftB + ScrnMapr_ScrnWB * ScrnMapr_Scale * (ui5r)top)
+ * ScrnMapr_TranN);
+ ui5r DstSkip = SrcSkip * ScrnMapr_TranN;
+
+ for (i = bottom - top; --i >= 0; ) {
+#if ScrnMapr_Scale > 1
+ p3 = pDst;
+#endif
+
+ for (j = jn; --j >= 0; ) {
+ t0 = *pSrc++;
+ pMap =
+ &((ScrnMapr_TranT *)ScrnMapr_Map)[t0 * ScrnMapr_TranN];
+
+#if ScrnMapr_TranN > 4
+ for (k = ScrnMapr_TranN; --k >= 0; ) {
+ *pDst++ = *pMap++;
+ }
+#else
+
+#if ScrnMapr_TranN >= 2
+ *pDst++ = *pMap++;
+#endif
+#if ScrnMapr_TranN >= 3
+ *pDst++ = *pMap++;
+#endif
+#if ScrnMapr_TranN >= 4
+ *pDst++ = *pMap++;
+#endif
+ *pDst++ = *pMap;
+
+#endif /* ! ScrnMapr_TranN > 4 */
+
+ }
+ pSrc += SrcSkip;
+ pDst += DstSkip;
+
+#if ScrnMapr_Scale > 1
+#if ScrnMapr_Scale > 2
+ for (k = ScrnMapr_Scale - 1; --k >= 0; )
+#endif
+ {
+ pMap = p3;
+ for (j = ScrnMapr_TranN * jn; --j >= 0; ) {
+ *pDst++ = *pMap++;
+ }
+ pDst += DstSkip;
+ }
+#endif /* ScrnMapr_Scale > 1 */
+ }
+}
+
+/* undefine template locals and parameters */
+
+#undef ScrnMapr_ScrnWB
+#undef ScrnMapr_TranN
+#undef ScrnMapr_TranLn2Sz
+#undef ScrnMapr_TranT
+#undef ScrnMapr_MapElSz
+
+#undef ScrnMapr_DoMap
+#undef ScrnMapr_Src
+#undef ScrnMapr_Dst
+#undef ScrnMapr_SrcDepth
+#undef ScrnMapr_DstDepth
+#undef ScrnMapr_Map
+#undef ScrnMapr_Scale
--- /dev/null
+++ b/src/SCRNTRNS.h
@@ -1,0 +1,161 @@
+/*
+ SCRNTRNS.h
+
+ Copyright (C) 2012 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ SCReeN TRaNSlater
+*/
+
+/* required arguments for this template */
+
+#ifndef ScrnTrns_DoTrans /* procedure to be created by this template */
+#error "ScrnTrns_DoTrans not defined"
+#endif
+#ifndef ScrnTrns_Src
+#error "ScrnTrns_Src not defined"
+#endif
+#ifndef ScrnTrns_Dst
+#error "ScrnTrns_Dst not defined"
+#endif
+#ifndef ScrnTrns_SrcDepth
+#error "ScrnTrns_SrcDepth not defined"
+#endif
+#ifndef ScrnTrns_DstDepth
+#error "ScrnTrns_DstDepth not defined"
+#endif
+
+/* optional argument for this template */
+
+#ifndef ScrnTrns_Scale
+#define ScrnTrns_Scale 1
+#endif
+
+#ifndef ScrnTrns_DstZLo
+#define ScrnTrns_DstZLo 0
+#endif
+
+/* check of parameters */
+
+#if (ScrnTrns_SrcDepth < 4)
+#error "bad ScrnTrns_SrcDepth"
+#endif
+
+#if (ScrnTrns_DstDepth < 4)
+#error "bad ScrnTrns_Dst"
+#endif
+
+/* now define the procedure */
+
+LOCALPROC ScrnTrns_DoTrans(si4b top, si4b left,
+ si4b bottom, si4b right)
+{
+ int i;
+ int j;
+ ui5b t0;
+ ui5b t1;
+ ui4r jn = right - left;
+ ui4r SrcSkip = vMacScreenByteWidth
+ - (jn << (ScrnTrns_SrcDepth - 3));
+ ui3b *pSrc = ((ui3b *)ScrnTrns_Src)
+ + (left << (ScrnTrns_SrcDepth - 3))
+ + vMacScreenByteWidth * (ui5r)top;
+ ui5b *pDst = ((ui5b *)ScrnTrns_Dst)
+ + left * ScrnTrns_Scale
+ + (ui5r)vMacScreenWidth * ScrnTrns_Scale * ScrnTrns_Scale * top;
+ ui4r DstSkip = (vMacScreenWidth - jn) * ScrnTrns_Scale;
+#if ScrnTrns_Scale > 1
+ int k;
+ ui5b *p3;
+ ui5b *p4;
+#endif
+
+ for (i = bottom - top; --i >= 0; ) {
+#if ScrnTrns_Scale > 1
+ p3 = pDst;
+#endif
+
+ for (j = jn; --j >= 0; ) {
+#if 4 == ScrnTrns_SrcDepth
+ t0 = do_get_mem_word(pSrc);
+ pSrc += 2;
+ t1 =
+#if ScrnTrns_DstZLo
+ ((t0 & 0x7C00) << 17) |
+ ((t0 & 0x7000) << 12) |
+ ((t0 & 0x03E0) << 14) |
+ ((t0 & 0x0380) << 9) |
+ ((t0 & 0x001F) << 11) |
+ ((t0 & 0x001C) << 6);
+#else
+ ((t0 & 0x7C00) << 9) |
+ ((t0 & 0x7000) << 4) |
+ ((t0 & 0x03E0) << 6) |
+ ((t0 & 0x0380) << 1) |
+ ((t0 & 0x001F) << 3) |
+ ((t0 & 0x001C) >> 2);
+#endif
+#if 0
+ ((t0 & 0x7C00) << 1) |
+ ((t0 & 0x7000) >> 4) |
+ ((t0 & 0x03E0) << 14) |
+ ((t0 & 0x0380) << 9) |
+ ((t0 & 0x001F) << 27) |
+ ((t0 & 0x001C) << 22);
+#endif
+
+#elif 5 == ScrnTrns_SrcDepth
+ t0 = do_get_mem_long(pSrc);
+ pSrc += 4;
+#if ScrnTrns_DstZLo
+ t1 = t0 << 8;
+#else
+ t1 = t0;
+#endif
+#endif
+
+#if ScrnTrns_Scale > 1
+ for (k = ScrnTrns_Scale; --k >= 0; )
+#endif
+ {
+ *pDst++ = t1;
+ }
+ }
+ pSrc += SrcSkip;
+ pDst += DstSkip;
+
+#if ScrnTrns_Scale > 1
+#if ScrnTrns_Scale > 2
+ for (k = ScrnTrns_Scale - 1; --k >= 0; )
+#endif
+ {
+ p4 = p3;
+ for (j = ScrnTrns_Scale * jn; --j >= 0; ) {
+ *pDst++ = *p4++;
+ }
+ pDst += DstSkip;
+ }
+#endif /* ScrnTrns_Scale > 1 */
+ }
+}
+
+/* undefine template locals and parameters */
+
+#undef ScrnTrns_DoTrans
+#undef ScrnTrns_Src
+#undef ScrnTrns_Dst
+#undef ScrnTrns_SrcDepth
+#undef ScrnTrns_DstDepth
+#undef ScrnTrns_Scale
+#undef ScrnTrns_DstZLo
--- /dev/null
+++ b/src/SCSIEMDV.c
@@ -1,0 +1,156 @@
+/*
+ SCSIEMDV.c
+
+ Copyright (C) 2004 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Small Computer System Interface EMulated DeVice
+
+ Emulates the SCSI found in the Mac Plus.
+
+ This code adapted from "SCSI.c" in vMac by Philip Cummins.
+*/
+
+/* NCR5380 chip emulation by Yoav Shadmi, 1998 */
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+
+#include "ENDIANAC.h"
+#include "MYOSGLUE.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#include "MINEM68K.h"
+#endif
+
+#include "SCSIEMDV.h"
+
+#define scsiRd 0x00
+#define scsiWr 0x01
+
+#define sCDR 0x00 /* current scsi data register (r/o) */
+#define sODR 0x00 /* output data register (w/o) */
+#define sICR 0x02 /* initiator command register (r/w) */
+#define sMR 0x04 /* mode register (r/w) */
+#define sTCR 0x06 /* target command register (r/w) */
+#define sCSR 0x08 /* current SCSI bus status (r/o) */
+#define sSER 0x08 /* select enable register (w/o) */
+#define sBSR 0x0A /* bus and status register (r/o) */
+#define sDMAtx 0x0A /* start DMA send (w/o) */
+#define sIDR 0x0C /* input data register (r/o) */
+#define sTDMArx 0x0C /* start DMA target receive (w/o) */
+#define sRESET 0x0E /* reset parity/interrupt (r/o) */
+#define sIDMArx 0x0E /* start DMA initiator receive (w/o) */
+
+#define kSCSI_Size 0x00010
+
+LOCALVAR ui3b SCSI[kSCSI_Size];
+
+GLOBALPROC SCSI_Reset(void)
+{
+ int i;
+
+ for (i = 0; i < kSCSI_Size; i++) {
+ SCSI[i] = 0;
+ }
+}
+
+LOCALPROC SCSI_BusReset(void)
+{
+ SCSI[scsiRd + sCDR] = 0;
+ SCSI[scsiWr + sODR] = 0;
+ SCSI[scsiRd + sICR] = 0x80;
+ SCSI[scsiWr + sICR] &= 0x80;
+ SCSI[scsiRd + sMR] &= 0x40;
+ SCSI[scsiWr + sMR] &= 0x40;
+ SCSI[scsiRd + sTCR] = 0;
+ SCSI[scsiWr + sTCR] = 0;
+ SCSI[scsiRd + sCSR] = 0x80;
+ SCSI[scsiWr + sSER] = 0;
+ SCSI[scsiRd + sBSR] = 0x10;
+ SCSI[scsiWr + sDMAtx] = 0;
+ SCSI[scsiRd + sIDR] = 0;
+ SCSI[scsiWr + sTDMArx] = 0;
+ SCSI[scsiRd + sRESET] = 0;
+ SCSI[scsiWr + sIDMArx] = 0;
+#if 0
+ SCSI[scsiRd + sODR + dackWr] = 0;
+ SCSI[scsiWr + sIDR + dackRd] = 0;
+#endif
+
+ /* The missing piece of the puzzle.. :) */
+ put_ram_word(0xb22, get_ram_word(0xb22) | 0x8000);
+}
+
+LOCALPROC SCSI_Check(void)
+{
+ /*
+ The arbitration select/reselect scenario
+ [stub.. doesn't really work...]
+ */
+ if ((SCSI[scsiWr + sODR] >> 7) == 1) {
+ /* Check if the Mac tries to be an initiator */
+ if ((SCSI[scsiWr + sMR] & 1) == 1) {
+ /* the Mac set arbitration in progress */
+ /*
+ stub! tell the mac that there
+ is arbitration in progress...
+ */
+ SCSI[scsiRd + sICR] |= 0x40;
+ /* ... that we didn't lose arbitration ... */
+ SCSI[scsiRd + sICR] &= ~ 0x20;
+ /*
+ ... and that there isn't a higher priority ID present...
+ */
+ SCSI[scsiRd + sCDR] = 0x00;
+
+ /*
+ ... the arbitration and selection/reselection is
+ complete. the initiator tries to connect to the SCSI
+ device, fails and returns after timeout.
+ */
+ }
+ }
+
+ /* check the chip registers, AS SET BY THE CPU */
+ if ((SCSI[scsiWr + sICR] >> 7) == 1) {
+ /* Check Assert RST */
+ SCSI_BusReset();
+ } else {
+ SCSI[scsiRd + sICR] &= ~ 0x80;
+ SCSI[scsiRd + sCSR] &= ~ 0x80;
+ }
+
+ if ((SCSI[scsiWr + sICR] >> 2) == 1) {
+ /* Check Assert SEL */
+ SCSI[scsiRd + sCSR] |= 0x02;
+ SCSI[scsiRd + sBSR] = 0x10;
+ } else {
+ SCSI[scsiRd + sCSR] &= ~ 0x02;
+ }
+}
+
+GLOBALFUNC ui5b SCSI_Access(ui5b Data, blnr WriteMem, CPTR addr)
+{
+ if (addr < (kSCSI_Size / 2)) {
+ addr *= 2;
+ if (WriteMem) {
+ SCSI[addr + 1] = Data;
+ SCSI_Check();
+ } else {
+ Data = SCSI[addr];
+ }
+ }
+ return Data;
+}
--- /dev/null
+++ b/src/SCSIEMDV.h
@@ -1,0 +1,25 @@
+/*
+ SCSIEMDV.h
+
+ Copyright (C) 2004 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef SCSIEMDV_H
+#error "header already included"
+#else
+#define SCSIEMDV_H
+#endif
+
+EXPORTPROC SCSI_Reset(void);
+
+EXPORTFUNC ui5b SCSI_Access(ui5b Data, blnr WriteMem, CPTR addr);
--- /dev/null
+++ b/src/SGLUALSA.h
@@ -1,0 +1,1618 @@
+/*
+ SGLUALSA.h
+
+ Copyright (C) 2012 Stephan Kochen, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Sound GLUe for ALSA
+
+ ALSA sound support by Stephan Kochen.
+*/
+
+#ifndef RaspbianWorkAround
+#define RaspbianWorkAround 0
+#endif
+
+#if 0
+
+#include "alsa/asoundlib.h"
+ /* and link with "-lasound" */
+
+#define My_snd_pcm_t snd_pcm_t
+#define My_snd_pcm_hw_params_t snd_pcm_hw_params_t
+#define My_snd_pcm_sw_params_t snd_pcm_sw_params_t
+#define My_snd_pcm_state_t snd_pcm_state_t
+#if RaspbianWorkAround
+#define My_snd_pcm_status_t snd_pcm_status_t
+#endif
+
+#define My_SND_PCM_STATE_OPEN SND_PCM_STATE_OPEN
+#define My_SND_PCM_STATE_SETUP SND_PCM_STATE_SETUP
+#define My_SND_PCM_STATE_PREPARED SND_PCM_STATE_PREPARED
+#define My_SND_PCM_STATE_RUNNING SND_PCM_STATE_RUNNING
+#define My_SND_PCM_STATE_XRUN SND_PCM_STATE_XRUN
+#define My_SND_PCM_STATE_DRAINING SND_PCM_STATE_DRAINING
+#define My_SND_PCM_STATE_PAUSED SND_PCM_STATE_PAUSED
+#define My_SND_PCM_STATE_SUSPENDED SND_PCM_STATE_SUSPENDED
+#define My_SND_PCM_STATE_DISCONNECTED SND_PCM_STATE_DISCONNECTED
+#define My_SND_PCM_STATE_LAST SND_PCM_STATE_LAST
+
+#define My_snd_pcm_stream_t snd_pcm_stream_t
+
+#define My_SND_PCM_STREAM_PLAYBACK SND_PCM_STREAM_PLAYBACK
+#define My_SND_PCM_STREAM_CAPTURE SND_PCM_STREAM_CAPTURE
+#define My_SND_PCM_STREAM_LAST SND_PCM_STREAM_LAST
+
+#define My_snd_pcm_access_t snd_pcm_access_t
+
+#define My_SND_PCM_ACCESS_MMAP_INTERLEAVED \
+ SND_PCM_ACCESS_MMAP_INTERLEAVED
+#define My_SND_PCM_ACCESS_MMAP_NONINTERLEAVED \
+ SND_PCM_ACCESS_MMAP_NONINTERLEAVED
+#define My_SND_PCM_ACCESS_MMAP_COMPLEX \
+ SND_PCM_ACCESS_MMAP_COMPLEX
+#define My_SND_PCM_ACCESS_RW_INTERLEAVED \
+ SND_PCM_ACCESS_RW_INTERLEAVED
+#define My_SND_PCM_ACCESS_RW_NONINTERLEAVED \
+ SND_PCM_ACCESS_RW_NONINTERLEAVED
+#define My_SND_PCM_ACCESS_LAST \
+ SND_PCM_ACCESS_LAST
+
+#define My_snd_pcm_format_t snd_pcm_format_t
+
+#define My_SND_PCM_FORMAT_UNKNOWN SND_PCM_FORMAT_UNKNOWN
+#define My_SND_PCM_FORMAT_S8 SND_PCM_FORMAT_S8
+#define My_SND_PCM_FORMAT_U8 SND_PCM_FORMAT_U8
+#define My_SND_PCM_FORMAT_S16_LE SND_PCM_FORMAT_S16_LE
+#define My_SND_PCM_FORMAT_S16_BE SND_PCM_FORMAT_S16_BE
+#define My_SND_PCM_FORMAT_U16_LE SND_PCM_FORMAT_U16_LE
+#define My_SND_PCM_FORMAT_U16_BE SND_PCM_FORMAT_U16_BE
+#define My_SND_PCM_FORMAT_S24_LE SND_PCM_FORMAT_S24_LE
+#define My_SND_PCM_FORMAT_S24_BE SND_PCM_FORMAT_S24_BE
+#define My_SND_PCM_FORMAT_U24_LE SND_PCM_FORMAT_U24_LE
+#define My_SND_PCM_FORMAT_U24_BE SND_PCM_FORMAT_U24_BE
+#define My_SND_PCM_FORMAT_S32_LE SND_PCM_FORMAT_S32_LE
+#define My_SND_PCM_FORMAT_S32_BE SND_PCM_FORMAT_S32_BE
+#define My_SND_PCM_FORMAT_U32_LE SND_PCM_FORMAT_U32_LE
+#define My_SND_PCM_FORMAT_U32_BE SND_PCM_FORMAT_U32_BE
+#define My_SND_PCM_FORMAT_FLOAT_LE SND_PCM_FORMAT_FLOAT_LE
+#define My_SND_PCM_FORMAT_FLOAT_BE SND_PCM_FORMAT_FLOAT_BE
+#define My_SND_PCM_FORMAT_FLOAT64_LE SND_PCM_FORMAT_FLOAT64_LE
+#define My_SND_PCM_FORMAT_FLOAT64_BE SND_PCM_FORMAT_FLOAT64_BE
+#define My_SND_PCM_FORMAT_IEC958_SUBFRAME_LE \
+ SND_PCM_FORMAT_IEC958_SUBFRAME_LE
+#define My_SND_PCM_FORMAT_IEC958_SUBFRAME_BE \
+ SND_PCM_FORMAT_IEC958_SUBFRAME_BE
+#define My_SND_PCM_FORMAT_MU_LAW SND_PCM_FORMAT_MU_LAW
+#define My_SND_PCM_FORMAT_A_LAW SND_PCM_FORMAT_A_LAW
+#define My_SND_PCM_FORMAT_IMA_ADPCM SND_PCM_FORMAT_IMA_ADPCM
+#define My_SND_PCM_FORMAT_MPEG SND_PCM_FORMAT_MPEG
+#define My_SND_PCM_FORMAT_GSM SND_PCM_FORMAT_GSM
+#define My_SND_PCM_FORMAT_SPECIAL SND_PCM_FORMAT_SPECIAL
+#define My_SND_PCM_FORMAT_S24_3LE SND_PCM_FORMAT_S24_3LE
+#define My_SND_PCM_FORMAT_S24_3BE SND_PCM_FORMAT_S24_3BE
+#define My_SND_PCM_FORMAT_U24_3LE SND_PCM_FORMAT_U24_3LE
+#define My_SND_PCM_FORMAT_U24_3BE SND_PCM_FORMAT_U24_3BE
+#define My_SND_PCM_FORMAT_S20_3LE SND_PCM_FORMAT_S20_3LE
+#define My_SND_PCM_FORMAT_S20_3BE SND_PCM_FORMAT_S20_3BE
+#define My_SND_PCM_FORMAT_U20_3LE SND_PCM_FORMAT_U20_3LE
+#define My_SND_PCM_FORMAT_U20_3BE SND_PCM_FORMAT_U20_3BE
+#define My_SND_PCM_FORMAT_S18_3LE SND_PCM_FORMAT_S18_3LE
+#define My_SND_PCM_FORMAT_S18_3BE SND_PCM_FORMAT_S18_3BE
+#define My_SND_PCM_FORMAT_U18_3LE SND_PCM_FORMAT_U18_3LE
+#define My_SND_PCM_FORMAT_U18_3BE SND_PCM_FORMAT_U18_3BE
+#define My_SND_PCM_FORMAT_LAST SND_PCM_FORMAT_LAST
+
+#define My_SND_PCM_FORMAT_S16 SND_PCM_FORMAT_S16
+#define My_SND_PCM_FORMAT_U16 SND_PCM_FORMAT_U16
+#define My_SND_PCM_FORMAT_S24 SND_PCM_FORMAT_S24
+#define My_SND_PCM_FORMAT_U24 SND_PCM_FORMAT_U24
+#define My_SND_PCM_FORMAT_S32 SND_PCM_FORMAT_S32
+#define My_SND_PCM_FORMAT_U32 SND_PCM_FORMAT_U32
+#define My_SND_PCM_FORMAT_FLOAT SND_PCM_FORMAT_FLOAT
+#define My_SND_PCM_FORMAT_FLOAT64 SND_PCM_FORMAT_FLOAT64
+#define My_SND_PCM_FORMAT_IEC958_SUBFRAME SND_PCM_FORMAT_FLOAT64
+
+#define My_snd_pcm_uframes_t snd_pcm_uframes_t
+#define My_snd_pcm_sframes_t snd_pcm_sframes_t
+
+#define My_SND_PCM_NONBLOCK SND_PCM_NONBLOCK
+
+#define My_snd_pcm_open snd_pcm_open
+#define HaveMy_snd_pcm_open() (1)
+
+#define My_snd_pcm_close snd_pcm_close
+#define HaveMy_snd_pcm_close() (1)
+
+#define My_snd_pcm_hw_params_malloc snd_pcm_hw_params_malloc
+#define HaveMy_snd_pcm_hw_params_malloc() (1)
+
+#define My_snd_pcm_hw_params_free snd_pcm_hw_params_free
+#define HaveMy_snd_pcm_hw_params_free() (1)
+
+#define My_snd_pcm_hw_params_any snd_pcm_hw_params_any
+#define HaveMy_snd_pcm_hw_params_any() (1)
+
+#define My_snd_pcm_hw_params_set_access snd_pcm_hw_params_set_access
+#define HaveMy_snd_pcm_hw_params_set_access() (1)
+
+#define My_snd_pcm_hw_params_set_format snd_pcm_hw_params_set_format
+#define HaveMy_snd_pcm_hw_params_set_format() (1)
+
+#define My_snd_pcm_hw_params_set_rate_near \
+ snd_pcm_hw_params_set_rate_near
+#define HaveMy_snd_pcm_hw_params_set_rate_near() (1)
+
+#define My_snd_pcm_hw_params_set_channels \
+ snd_pcm_hw_params_set_channels
+#define HaveMy_snd_pcm_hw_params_set_channels() (1)
+
+#define My_snd_pcm_hw_params_set_buffer_size_near \
+ snd_pcm_hw_params_set_buffer_size_near
+#define HaveMy_snd_pcm_hw_params_set_buffer_size_near() (1)
+
+#define My_snd_pcm_hw_params_set_period_size_near \
+ snd_pcm_hw_params_set_period_size_near
+#define HaveMy_snd_pcm_hw_params_set_period_size_near() (1)
+
+#define My_snd_pcm_hw_params snd_pcm_hw_params
+#define HaveMy_snd_pcm_hw_params() (1)
+
+#define My_snd_pcm_sw_params_malloc snd_pcm_sw_params_malloc
+#define HaveMy_snd_pcm_sw_params_malloc() (1)
+
+#define My_snd_pcm_sw_params_free snd_pcm_sw_params_free
+#define HaveMy_snd_pcm_sw_params_free() (1)
+
+#define My_snd_pcm_sw_params_current snd_pcm_sw_params_current
+#define HaveMy_snd_pcm_sw_params_current() (1)
+
+#define My_snd_pcm_sw_params_set_start_threshold \
+ snd_pcm_sw_params_set_start_threshold
+#define HaveMy_snd_pcm_sw_params_set_start_threshold() (1)
+
+#define My_snd_pcm_sw_params_set_avail_min \
+ snd_pcm_sw_params_set_avail_min
+#define HaveMy_snd_pcm_sw_params_set_avail_min() (1)
+
+#define My_snd_pcm_sw_params_set_xfer_align \
+ snd_pcm_sw_params_set_xfer_align
+#define HaveMy_snd_pcm_sw_params_set_xfer_align() (1)
+
+#define My_snd_pcm_sw_params snd_pcm_sw_params
+#define HaveMy_snd_pcm_sw_params() (1)
+
+#define My_snd_pcm_nonblock snd_pcm_nonblock
+#define HaveMy_snd_pcm_nonblock() (1)
+
+#define My_snd_pcm_state snd_pcm_state
+#define HaveMy_snd_pcm_state() (1)
+
+#define My_snd_pcm_prepare snd_pcm_prepare
+#define HaveMy_snd_pcm_prepare() (1)
+
+#define My_snd_pcm_start snd_pcm_start
+#define HaveMy_snd_pcm_start() (1)
+
+#define My_snd_pcm_resume snd_pcm_resume
+#define HaveMy_snd_pcm_resume() (1)
+
+#define My_snd_pcm_avail_update snd_pcm_avail_update
+#define HaveMy_snd_pcm_avail_update() (1)
+
+#define My_snd_pcm_writei snd_pcm_writei
+#define HaveMy_snd_pcm_writei() (1)
+
+#define My_snd_pcm_drop snd_pcm_drop
+#define HaveMy_snd_pcm_drop() (1)
+
+#if RaspbianWorkAround
+#define My_snd_pcm_status_malloc snd_pcm_status_malloc
+#define HaveMy_snd_pcm_status_malloc() (1)
+
+#define My_snd_pcm_status snd_pcm_status
+#define HaveMy_snd_pcm_status() (1)
+
+#define My_snd_pcm_status_get_avail snd_pcm_status_get_avail
+#define HaveMy_snd_pcm_status_get_avail() (1)
+#endif
+
+#define My_snd_strerror snd_strerror
+#define HaveMy_snd_strerror() (1)
+
+#define MyCloseAlsaLib()
+
+#else
+
+static void *alsa_handle = NULL;
+
+LOCALVAR blnr DidAlsaLib = falseblnr;
+
+LOCALFUNC blnr HaveAlsaLib(void)
+{
+ if (! DidAlsaLib) {
+ alsa_handle = dlopen("libasound.so.2", RTLD_NOW);
+ if (NULL == alsa_handle) {
+ fprintf(stderr, "dlopen libasound failed\n");
+ }
+ DidAlsaLib = trueblnr;
+ }
+ return (alsa_handle != NULL);
+}
+
+LOCALPROC MyCloseAlsaLib(void)
+{
+ if (NULL != alsa_handle) {
+ if (0 != dlclose(alsa_handle)) {
+ fprintf(stderr, "dlclose libasound failed\n");
+ }
+ alsa_handle = NULL;
+ }
+}
+
+/* PCM handle */
+typedef struct My__snd_pcm My_snd_pcm_t;
+/* PCM hardware configuration space container */
+typedef struct My__snd_pcm_hw_params My_snd_pcm_hw_params_t;
+/* PCM software configuration container */
+typedef struct My__snd_pcm_sw_params My_snd_pcm_sw_params_t;
+
+#if RaspbianWorkAround
+/* PCM status container */
+typedef struct My__snd_pcm_status My_snd_pcm_status_t;
+#endif
+
+/* PCM state */
+typedef enum My__snd_pcm_state {
+ /* Open */
+ My_SND_PCM_STATE_OPEN = 0,
+ /* Setup installed */
+ My_SND_PCM_STATE_SETUP,
+ /* Ready to start */
+ My_SND_PCM_STATE_PREPARED,
+ /* Running */
+ My_SND_PCM_STATE_RUNNING,
+ /* Stopped: underrun (playback) or overrun (capture) detected */
+ My_SND_PCM_STATE_XRUN,
+ /* Draining: running (playback) or stopped (capture) */
+ My_SND_PCM_STATE_DRAINING,
+ /* Paused */
+ My_SND_PCM_STATE_PAUSED,
+ /* Hardware is suspended */
+ My_SND_PCM_STATE_SUSPENDED,
+ /* Hardware is disconnected */
+ My_SND_PCM_STATE_DISCONNECTED,
+ My_SND_PCM_STATE_LAST = My_SND_PCM_STATE_DISCONNECTED
+} My_snd_pcm_state_t;
+
+/* PCM stream (direction) */
+typedef enum My__snd_pcm_stream {
+ /* Playback stream */
+ My_SND_PCM_STREAM_PLAYBACK = 0,
+ /* Capture stream */
+ My_SND_PCM_STREAM_CAPTURE,
+ My_SND_PCM_STREAM_LAST = My_SND_PCM_STREAM_CAPTURE
+} My_snd_pcm_stream_t;
+
+/* PCM access type */
+typedef enum My__snd_pcm_access {
+ /* mmap access with simple interleaved channels */
+ My_SND_PCM_ACCESS_MMAP_INTERLEAVED = 0,
+ /* mmap access with simple non interleaved channels */
+ My_SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
+ /* mmap access with complex placement */
+ My_SND_PCM_ACCESS_MMAP_COMPLEX,
+ /* snd_pcm_readi/snd_pcm_writei access */
+ My_SND_PCM_ACCESS_RW_INTERLEAVED,
+ /* snd_pcm_readn/snd_pcm_writen access */
+ My_SND_PCM_ACCESS_RW_NONINTERLEAVED,
+ My_SND_PCM_ACCESS_LAST = My_SND_PCM_ACCESS_RW_NONINTERLEAVED
+} My_snd_pcm_access_t;
+
+/* PCM sample format */
+typedef enum My__snd_pcm_format {
+ /* Unknown */
+ My_SND_PCM_FORMAT_UNKNOWN = -1,
+ /* Signed 8 bit */
+ My_SND_PCM_FORMAT_S8 = 0,
+ /* Unsigned 8 bit */
+ My_SND_PCM_FORMAT_U8,
+ /* Signed 16 bit Little Endian */
+ My_SND_PCM_FORMAT_S16_LE,
+ /* Signed 16 bit Big Endian */
+ My_SND_PCM_FORMAT_S16_BE,
+ /* Unsigned 16 bit Little Endian */
+ My_SND_PCM_FORMAT_U16_LE,
+ /* Unsigned 16 bit Big Endian */
+ My_SND_PCM_FORMAT_U16_BE,
+ /*
+ Signed 24 bit Little Endian using low three bytes in 32-bit word
+ */
+ My_SND_PCM_FORMAT_S24_LE,
+ /* Signed 24 bit Big Endian using low three bytes in 32-bit word */
+ My_SND_PCM_FORMAT_S24_BE,
+ /*
+ Unsigned 24 bit Little Endian using low three bytes in
+ 32-bit word
+ */
+ My_SND_PCM_FORMAT_U24_LE,
+ /*
+ Unsigned 24 bit Big Endian using low three bytes in 32-bit word
+ */
+ My_SND_PCM_FORMAT_U24_BE,
+ /* Signed 32 bit Little Endian */
+ My_SND_PCM_FORMAT_S32_LE,
+ /* Signed 32 bit Big Endian */
+ My_SND_PCM_FORMAT_S32_BE,
+ /* Unsigned 32 bit Little Endian */
+ My_SND_PCM_FORMAT_U32_LE,
+ /* Unsigned 32 bit Big Endian */
+ My_SND_PCM_FORMAT_U32_BE,
+ /* Float 32 bit Little Endian, Range -1.0 to 1.0 */
+ My_SND_PCM_FORMAT_FLOAT_LE,
+ /* Float 32 bit Big Endian, Range -1.0 to 1.0 */
+ My_SND_PCM_FORMAT_FLOAT_BE,
+ /* Float 64 bit Little Endian, Range -1.0 to 1.0 */
+ My_SND_PCM_FORMAT_FLOAT64_LE,
+ /* Float 64 bit Big Endian, Range -1.0 to 1.0 */
+ My_SND_PCM_FORMAT_FLOAT64_BE,
+ /* IEC-958 Little Endian */
+ My_SND_PCM_FORMAT_IEC958_SUBFRAME_LE,
+ /* IEC-958 Big Endian */
+ My_SND_PCM_FORMAT_IEC958_SUBFRAME_BE,
+ /* Mu-Law */
+ My_SND_PCM_FORMAT_MU_LAW,
+ /* A-Law */
+ My_SND_PCM_FORMAT_A_LAW,
+ /* Ima-ADPCM */
+ My_SND_PCM_FORMAT_IMA_ADPCM,
+ /* MPEG */
+ My_SND_PCM_FORMAT_MPEG,
+ /* GSM */
+ My_SND_PCM_FORMAT_GSM,
+ /* Special */
+ My_SND_PCM_FORMAT_SPECIAL = 31,
+ /* Signed 24bit Little Endian in 3bytes format */
+ My_SND_PCM_FORMAT_S24_3LE = 32,
+ /* Signed 24bit Big Endian in 3bytes format */
+ My_SND_PCM_FORMAT_S24_3BE,
+ /* Unsigned 24bit Little Endian in 3bytes format */
+ My_SND_PCM_FORMAT_U24_3LE,
+ /* Unsigned 24bit Big Endian in 3bytes format */
+ My_SND_PCM_FORMAT_U24_3BE,
+ /* Signed 20bit Little Endian in 3bytes format */
+ My_SND_PCM_FORMAT_S20_3LE,
+ /* Signed 20bit Big Endian in 3bytes format */
+ My_SND_PCM_FORMAT_S20_3BE,
+ /* Unsigned 20bit Little Endian in 3bytes format */
+ My_SND_PCM_FORMAT_U20_3LE,
+ /* Unsigned 20bit Big Endian in 3bytes format */
+ My_SND_PCM_FORMAT_U20_3BE,
+ /* Signed 18bit Little Endian in 3bytes format */
+ My_SND_PCM_FORMAT_S18_3LE,
+ /* Signed 18bit Big Endian in 3bytes format */
+ My_SND_PCM_FORMAT_S18_3BE,
+ /* Unsigned 18bit Little Endian in 3bytes format */
+ My_SND_PCM_FORMAT_U18_3LE,
+ /* Unsigned 18bit Big Endian in 3bytes format */
+ My_SND_PCM_FORMAT_U18_3BE,
+ My_SND_PCM_FORMAT_LAST = My_SND_PCM_FORMAT_U18_3BE,
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ /* Signed 16 bit CPU endian */
+ My_SND_PCM_FORMAT_S16 = My_SND_PCM_FORMAT_S16_LE,
+ /* Unsigned 16 bit CPU endian */
+ My_SND_PCM_FORMAT_U16 = My_SND_PCM_FORMAT_U16_LE,
+ /* Signed 24 bit CPU endian */
+ My_SND_PCM_FORMAT_S24 = My_SND_PCM_FORMAT_S24_LE,
+ /* Unsigned 24 bit CPU endian */
+ My_SND_PCM_FORMAT_U24 = My_SND_PCM_FORMAT_U24_LE,
+ /* Signed 32 bit CPU endian */
+ My_SND_PCM_FORMAT_S32 = My_SND_PCM_FORMAT_S32_LE,
+ /* Unsigned 32 bit CPU endian */
+ My_SND_PCM_FORMAT_U32 = My_SND_PCM_FORMAT_U32_LE,
+ /* Float 32 bit CPU endian */
+ My_SND_PCM_FORMAT_FLOAT = My_SND_PCM_FORMAT_FLOAT_LE,
+ /* Float 64 bit CPU endian */
+ My_SND_PCM_FORMAT_FLOAT64 = My_SND_PCM_FORMAT_FLOAT64_LE,
+ /* IEC-958 CPU Endian */
+ My_SND_PCM_FORMAT_IEC958_SUBFRAME =
+ My_SND_PCM_FORMAT_IEC958_SUBFRAME_LE
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ /* Signed 16 bit CPU endian */
+ My_SND_PCM_FORMAT_S16 = My_SND_PCM_FORMAT_S16_BE,
+ /* Unsigned 16 bit CPU endian */
+ My_SND_PCM_FORMAT_U16 = My_SND_PCM_FORMAT_U16_BE,
+ /* Signed 24 bit CPU endian */
+ My_SND_PCM_FORMAT_S24 = My_SND_PCM_FORMAT_S24_BE,
+ /* Unsigned 24 bit CPU endian */
+ My_SND_PCM_FORMAT_U24 = My_SND_PCM_FORMAT_U24_BE,
+ /* Signed 32 bit CPU endian */
+ My_SND_PCM_FORMAT_S32 = My_SND_PCM_FORMAT_S32_BE,
+ /* Unsigned 32 bit CPU endian */
+ My_SND_PCM_FORMAT_U32 = My_SND_PCM_FORMAT_U32_BE,
+ /* Float 32 bit CPU endian */
+ My_SND_PCM_FORMAT_FLOAT = My_SND_PCM_FORMAT_FLOAT_BE,
+ /* Float 64 bit CPU endian */
+ My_SND_PCM_FORMAT_FLOAT64 = My_SND_PCM_FORMAT_FLOAT64_BE,
+ /* IEC-958 CPU Endian */
+ My_SND_PCM_FORMAT_IEC958_SUBFRAME =
+ My_SND_PCM_FORMAT_IEC958_SUBFRAME_BE
+#else
+#error "Unknown endian"
+#endif
+} My_snd_pcm_format_t;
+
+/* Unsigned frames quantity */
+typedef unsigned long My_snd_pcm_uframes_t;
+/* Signed frames quantity */
+typedef long My_snd_pcm_sframes_t;
+
+/* Non blocking mode (flag for open mode) \hideinitializer */
+#define My_SND_PCM_NONBLOCK 0x00000001
+
+typedef int (*snd_pcm_open_ProcPtr)
+ (My_snd_pcm_t **pcm, const char *name, My_snd_pcm_stream_t stream,
+ int mode);
+LOCALVAR snd_pcm_open_ProcPtr My_snd_pcm_open = NULL;
+LOCALVAR blnr Did_snd_pcm_open = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_open(void)
+{
+ if (! Did_snd_pcm_open) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_open = (snd_pcm_open_ProcPtr)dlsym(alsa_handle,
+ "snd_pcm_open");
+ if (NULL == My_snd_pcm_open) {
+ fprintf(stderr, "dlsym snd_pcm_open failed\n");
+ }
+ }
+ Did_snd_pcm_open = trueblnr;
+ }
+ return (My_snd_pcm_open != NULL);
+}
+
+typedef int (*snd_pcm_close_ProcPtr)(My_snd_pcm_t *pcm);
+LOCALVAR snd_pcm_close_ProcPtr My_snd_pcm_close = NULL;
+LOCALVAR blnr Did_snd_pcm_close = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_close(void)
+{
+ if (! Did_snd_pcm_close) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_close = (snd_pcm_close_ProcPtr)dlsym(alsa_handle,
+ "snd_pcm_close");
+ if (NULL == My_snd_pcm_close) {
+ fprintf(stderr, "dlsym snd_pcm_close failed\n");
+ }
+ }
+ Did_snd_pcm_close = trueblnr;
+ }
+ return (My_snd_pcm_close != NULL);
+}
+
+typedef int (*snd_pcm_hw_params_malloc_ProcPtr)
+ (My_snd_pcm_hw_params_t **ptr);
+LOCALVAR snd_pcm_hw_params_malloc_ProcPtr My_snd_pcm_hw_params_malloc
+ = NULL;
+LOCALVAR blnr Did_snd_pcm_hw_params_malloc = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_hw_params_malloc(void)
+{
+ if (! Did_snd_pcm_hw_params_malloc) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_hw_params_malloc =
+ (snd_pcm_hw_params_malloc_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_hw_params_malloc");
+ if (NULL == My_snd_pcm_hw_params_malloc) {
+ fprintf(stderr,
+ "dlsym snd_pcm_hw_params_malloc failed\n");
+ }
+ }
+ Did_snd_pcm_hw_params_malloc = trueblnr;
+ }
+ return (My_snd_pcm_hw_params_malloc != NULL);
+}
+
+typedef void (*snd_pcm_hw_params_free_ProcPtr)
+ (My_snd_pcm_hw_params_t *obj);
+LOCALVAR snd_pcm_hw_params_free_ProcPtr
+ My_snd_pcm_hw_params_free = NULL;
+LOCALVAR blnr Did_snd_pcm_hw_params_free = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_hw_params_free(void)
+{
+ if (! Did_snd_pcm_hw_params_free) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_hw_params_free = (snd_pcm_hw_params_free_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_hw_params_free");
+ if (NULL == My_snd_pcm_hw_params_free) {
+ fprintf(stderr,
+ "dlsym snd_pcm_hw_params_free failed\n");
+ }
+ }
+ Did_snd_pcm_hw_params_free = trueblnr;
+ }
+ return (My_snd_pcm_hw_params_free != NULL);
+}
+
+typedef int (*snd_pcm_hw_params_any_ProcPtr)
+ (My_snd_pcm_t *pcm, My_snd_pcm_hw_params_t *params);
+LOCALVAR snd_pcm_hw_params_any_ProcPtr My_snd_pcm_hw_params_any = NULL;
+LOCALVAR blnr Did_snd_pcm_hw_params_any = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_hw_params_any(void)
+{
+ if (! Did_snd_pcm_hw_params_any) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_hw_params_any = (snd_pcm_hw_params_any_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_hw_params_any");
+ if (NULL == My_snd_pcm_hw_params_any) {
+ fprintf(stderr, "dlsym snd_pcm_hw_params_any failed\n");
+ }
+ }
+ Did_snd_pcm_hw_params_any = trueblnr;
+ }
+ return (My_snd_pcm_hw_params_any != NULL);
+}
+
+typedef int (*snd_pcm_hw_params_set_access_ProcPtr)
+ (My_snd_pcm_t *pcm, My_snd_pcm_hw_params_t *params,
+ My_snd_pcm_access_t _access);
+LOCALVAR snd_pcm_hw_params_set_access_ProcPtr
+ My_snd_pcm_hw_params_set_access = NULL;
+LOCALVAR blnr Did_snd_pcm_hw_params_set_access = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_hw_params_set_access(void)
+{
+ if (! Did_snd_pcm_hw_params_set_access) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_hw_params_set_access =
+ (snd_pcm_hw_params_set_access_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_hw_params_set_access");
+ if (NULL == My_snd_pcm_hw_params_set_access) {
+ fprintf(stderr,
+ "dlsym snd_pcm_hw_params_set_access failed\n");
+ }
+ }
+ Did_snd_pcm_hw_params_set_access = trueblnr;
+ }
+ return (My_snd_pcm_hw_params_set_access != NULL);
+}
+
+typedef int (*snd_pcm_hw_params_set_format_ProcPtr)
+ (My_snd_pcm_t *pcm, My_snd_pcm_hw_params_t *params,
+ My_snd_pcm_format_t val);
+LOCALVAR snd_pcm_hw_params_set_format_ProcPtr
+ My_snd_pcm_hw_params_set_format = NULL;
+LOCALVAR blnr Did_snd_pcm_hw_params_set_format = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_hw_params_set_format(void)
+{
+ if (! Did_snd_pcm_hw_params_set_format) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_hw_params_set_format =
+ (snd_pcm_hw_params_set_format_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_hw_params_set_format");
+ if (NULL == My_snd_pcm_hw_params_set_format) {
+ fprintf(stderr,
+ "dlsym snd_pcm_hw_params_set_format failed\n");
+ }
+ }
+ Did_snd_pcm_hw_params_set_format = trueblnr;
+ }
+ return (My_snd_pcm_hw_params_set_format != NULL);
+}
+
+typedef int (*snd_pcm_hw_params_set_rate_near_ProcPtr)
+ (My_snd_pcm_t *pcm, My_snd_pcm_hw_params_t *params,
+ unsigned int *val, int *dir);
+LOCALVAR snd_pcm_hw_params_set_rate_near_ProcPtr
+ My_snd_pcm_hw_params_set_rate_near = NULL;
+LOCALVAR blnr Did_snd_pcm_hw_params_set_rate_near = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_hw_params_set_rate_near(void)
+{
+ if (! Did_snd_pcm_hw_params_set_rate_near) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_hw_params_set_rate_near =
+ (snd_pcm_hw_params_set_rate_near_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_hw_params_set_rate_near");
+ if (NULL == My_snd_pcm_hw_params_set_rate_near) {
+ fprintf(stderr,
+ "dlsym snd_pcm_hw_params_set_rate_near failed\n");
+ }
+ }
+ Did_snd_pcm_hw_params_set_rate_near = trueblnr;
+ }
+ return (My_snd_pcm_hw_params_set_rate_near != NULL);
+}
+
+typedef int (*snd_pcm_hw_params_set_channels_ProcPtr)
+ (My_snd_pcm_t *pcm, My_snd_pcm_hw_params_t *params,
+ unsigned int val);
+LOCALVAR snd_pcm_hw_params_set_channels_ProcPtr
+ My_snd_pcm_hw_params_set_channels = NULL;
+LOCALVAR blnr Did_snd_pcm_hw_params_set_channels = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_hw_params_set_channels(void)
+{
+ if (! Did_snd_pcm_hw_params_set_channels) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_hw_params_set_channels =
+ (snd_pcm_hw_params_set_channels_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_hw_params_set_channels");
+ if (NULL == My_snd_pcm_hw_params_set_channels) {
+ fprintf(stderr,
+ "dlsym snd_pcm_hw_params_set_channels failed\n");
+ }
+ }
+ Did_snd_pcm_hw_params_set_channels = trueblnr;
+ }
+ return (My_snd_pcm_hw_params_set_channels != NULL);
+}
+
+typedef int (*snd_pcm_hw_params_set_buffer_size_near_ProcPtr)
+ (My_snd_pcm_t *pcm, My_snd_pcm_hw_params_t *params,
+ My_snd_pcm_uframes_t *val);
+LOCALVAR snd_pcm_hw_params_set_buffer_size_near_ProcPtr
+ My_snd_pcm_hw_params_set_buffer_size_near = NULL;
+LOCALVAR blnr Did_snd_pcm_hw_params_set_buffer_size_near = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_hw_params_set_buffer_size_near(void)
+{
+ if (! Did_snd_pcm_hw_params_set_buffer_size_near) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_hw_params_set_buffer_size_near =
+ (snd_pcm_hw_params_set_buffer_size_near_ProcPtr)
+ dlsym(alsa_handle,
+ "snd_pcm_hw_params_set_buffer_size_near");
+ if (NULL == My_snd_pcm_hw_params_set_buffer_size_near) {
+ fprintf(stderr,
+ "dlsym snd_pcm_hw_params_set_buffer_size_near"
+ " failed\n");
+ }
+ }
+ Did_snd_pcm_hw_params_set_buffer_size_near = trueblnr;
+ }
+ return (My_snd_pcm_hw_params_set_buffer_size_near != NULL);
+}
+
+typedef int (*snd_pcm_hw_params_set_period_size_near_ProcPtr)
+ (My_snd_pcm_t *pcm, My_snd_pcm_hw_params_t *params,
+ My_snd_pcm_uframes_t *val, int *dir);
+LOCALVAR snd_pcm_hw_params_set_period_size_near_ProcPtr
+ My_snd_pcm_hw_params_set_period_size_near = NULL;
+LOCALVAR blnr Did_snd_pcm_hw_params_set_period_size_near = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_hw_params_set_period_size_near(void)
+{
+ if (! Did_snd_pcm_hw_params_set_period_size_near) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_hw_params_set_period_size_near =
+ (snd_pcm_hw_params_set_period_size_near_ProcPtr)
+ dlsym(alsa_handle,
+ "snd_pcm_hw_params_set_period_size_near");
+ if (NULL == My_snd_pcm_hw_params_set_period_size_near) {
+ fprintf(stderr,
+ "dlsym snd_pcm_hw_params_set_period_size_near"
+ " failed\n");
+ }
+ }
+ Did_snd_pcm_hw_params_set_period_size_near = trueblnr;
+ }
+ return (My_snd_pcm_hw_params_set_period_size_near != NULL);
+}
+
+typedef int (*snd_pcm_hw_params_ProcPtr)
+ (My_snd_pcm_t *pcm, My_snd_pcm_hw_params_t *params);
+LOCALVAR snd_pcm_hw_params_ProcPtr My_snd_pcm_hw_params = NULL;
+LOCALVAR blnr Did_snd_pcm_hw_params = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_hw_params(void)
+{
+ if (! Did_snd_pcm_hw_params) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_hw_params = (snd_pcm_hw_params_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_hw_params");
+ if (NULL == My_snd_pcm_hw_params) {
+ fprintf(stderr, "dlsym snd_pcm_hw_params failed\n");
+ }
+ }
+ Did_snd_pcm_hw_params = trueblnr;
+ }
+ return (My_snd_pcm_hw_params != NULL);
+}
+
+typedef int (*snd_pcm_sw_params_malloc_ProcPtr)
+ (My_snd_pcm_sw_params_t **ptr);
+LOCALVAR snd_pcm_sw_params_malloc_ProcPtr
+ My_snd_pcm_sw_params_malloc = NULL;
+LOCALVAR blnr Did_snd_pcm_sw_params_malloc = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_sw_params_malloc(void)
+{
+ if (! Did_snd_pcm_sw_params_malloc) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_sw_params_malloc =
+ (snd_pcm_sw_params_malloc_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_sw_params_malloc");
+ if (NULL == My_snd_pcm_sw_params_malloc) {
+ fprintf(stderr,
+ "dlsym snd_pcm_sw_params_malloc failed\n");
+ }
+ }
+ Did_snd_pcm_sw_params_malloc = trueblnr;
+ }
+ return (My_snd_pcm_sw_params_malloc != NULL);
+}
+
+typedef void (*snd_pcm_sw_params_free_ProcPtr)
+ (My_snd_pcm_sw_params_t *obj);
+LOCALVAR snd_pcm_sw_params_free_ProcPtr
+ My_snd_pcm_sw_params_free = NULL;
+LOCALVAR blnr Did_snd_pcm_sw_params_free = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_sw_params_free(void)
+{
+ if (! Did_snd_pcm_sw_params_free) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_sw_params_free = (snd_pcm_sw_params_free_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_sw_params_free");
+ if (NULL == My_snd_pcm_sw_params_free) {
+ fprintf(stderr,
+ "dlsym snd_pcm_sw_params_free failed\n");
+ }
+ }
+ Did_snd_pcm_sw_params_free = trueblnr;
+ }
+ return (My_snd_pcm_sw_params_free != NULL);
+}
+
+typedef int (*snd_pcm_sw_params_current_ProcPtr)
+ (My_snd_pcm_t *pcm, My_snd_pcm_sw_params_t *params);
+LOCALVAR snd_pcm_sw_params_current_ProcPtr
+ My_snd_pcm_sw_params_current = NULL;
+LOCALVAR blnr Did_snd_pcm_sw_params_current = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_sw_params_current(void)
+{
+ if (! Did_snd_pcm_sw_params_current) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_sw_params_current =
+ (snd_pcm_sw_params_current_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_sw_params_current");
+ if (NULL == My_snd_pcm_sw_params_current) {
+ fprintf(stderr,
+ "dlsym snd_pcm_sw_params_current failed\n");
+ }
+ }
+ Did_snd_pcm_sw_params_current = trueblnr;
+ }
+ return (My_snd_pcm_sw_params_current != NULL);
+}
+
+typedef int (*snd_pcm_sw_params_set_start_threshold_ProcPtr)
+ (My_snd_pcm_t *pcm, My_snd_pcm_sw_params_t *params,
+ My_snd_pcm_uframes_t val);
+LOCALVAR snd_pcm_sw_params_set_start_threshold_ProcPtr
+ My_snd_pcm_sw_params_set_start_threshold = NULL;
+LOCALVAR blnr Did_snd_pcm_sw_params_set_start_threshold = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_sw_params_set_start_threshold(void)
+{
+ if (! Did_snd_pcm_sw_params_set_start_threshold) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_sw_params_set_start_threshold =
+ (snd_pcm_sw_params_set_start_threshold_ProcPtr)
+ dlsym(alsa_handle,
+ "snd_pcm_sw_params_set_start_threshold");
+ if (NULL == My_snd_pcm_sw_params_set_start_threshold) {
+ fprintf(stderr,
+ "dlsym snd_pcm_sw_params_set_start_threshold"
+ " failed\n");
+ }
+ }
+ Did_snd_pcm_sw_params_set_start_threshold = trueblnr;
+ }
+ return (My_snd_pcm_sw_params_set_start_threshold != NULL);
+}
+
+typedef int (*snd_pcm_sw_params_set_avail_min_ProcPtr)
+ (My_snd_pcm_t *pcm, My_snd_pcm_sw_params_t *params,
+ My_snd_pcm_uframes_t val);
+LOCALVAR snd_pcm_sw_params_set_avail_min_ProcPtr
+ My_snd_pcm_sw_params_set_avail_min = NULL;
+LOCALVAR blnr Did_snd_pcm_sw_params_set_avail_min = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_sw_params_set_avail_min(void)
+{
+ if (! Did_snd_pcm_sw_params_set_avail_min) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_sw_params_set_avail_min =
+ (snd_pcm_sw_params_set_avail_min_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_sw_params_set_avail_min");
+ if (NULL == My_snd_pcm_sw_params_set_avail_min) {
+ fprintf(stderr,
+ "dlsym snd_pcm_sw_params_set_avail_min failed\n");
+ }
+ }
+ Did_snd_pcm_sw_params_set_avail_min = trueblnr;
+ }
+ return (My_snd_pcm_sw_params_set_avail_min != NULL);
+}
+
+typedef int (*snd_pcm_sw_params_set_xfer_align_ProcPtr)
+ (My_snd_pcm_t *pcm, My_snd_pcm_sw_params_t *params,
+ My_snd_pcm_uframes_t val);
+LOCALVAR snd_pcm_sw_params_set_xfer_align_ProcPtr
+ My_snd_pcm_sw_params_set_xfer_align = NULL;
+LOCALVAR blnr Did_snd_pcm_sw_params_set_xfer_align = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_sw_params_set_xfer_align(void)
+{
+ if (! Did_snd_pcm_sw_params_set_xfer_align) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_sw_params_set_xfer_align =
+ (snd_pcm_sw_params_set_xfer_align_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_sw_params_set_xfer_align");
+ if (NULL == My_snd_pcm_sw_params_set_xfer_align) {
+ fprintf(stderr,
+ "dlsym snd_pcm_sw_params_set_xfer_align failed\n");
+ }
+ }
+ Did_snd_pcm_sw_params_set_xfer_align = trueblnr;
+ }
+ return (My_snd_pcm_sw_params_set_xfer_align != NULL);
+}
+
+typedef int (*snd_pcm_sw_params_ProcPtr)
+ (My_snd_pcm_t *pcm, My_snd_pcm_sw_params_t *params);
+LOCALVAR snd_pcm_sw_params_ProcPtr My_snd_pcm_sw_params = NULL;
+LOCALVAR blnr Did_snd_pcm_sw_params = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_sw_params(void)
+{
+ if (! Did_snd_pcm_sw_params) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_sw_params = (snd_pcm_sw_params_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_sw_params");
+ if (NULL == My_snd_pcm_sw_params) {
+ fprintf(stderr, "dlsym snd_pcm_sw_params failed\n");
+ }
+ }
+ Did_snd_pcm_sw_params = trueblnr;
+ }
+ return (My_snd_pcm_sw_params != NULL);
+}
+
+typedef int (*snd_pcm_nonblock_ProcPtr)
+ (My_snd_pcm_t *pcm, int nonblock);
+LOCALVAR snd_pcm_nonblock_ProcPtr My_snd_pcm_nonblock = NULL;
+LOCALVAR blnr Did_snd_pcm_nonblock = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_nonblock(void)
+{
+ if (! Did_snd_pcm_nonblock) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_nonblock = (snd_pcm_nonblock_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_nonblock");
+ if (NULL == My_snd_pcm_nonblock) {
+ fprintf(stderr, "dlsym snd_pcm_nonblock failed\n");
+ }
+ }
+ Did_snd_pcm_nonblock = trueblnr;
+ }
+ return (My_snd_pcm_nonblock != NULL);
+}
+
+typedef My_snd_pcm_state_t (*snd_pcm_state_ProcPtr)(My_snd_pcm_t *pcm);
+LOCALVAR snd_pcm_state_ProcPtr My_snd_pcm_state = NULL;
+LOCALVAR blnr Did_snd_pcm_state = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_state(void)
+{
+ if (! Did_snd_pcm_state) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_state = (snd_pcm_state_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_state");
+ if (NULL == My_snd_pcm_state) {
+ fprintf(stderr, "dlsym snd_pcm_state failed\n");
+ }
+ }
+ Did_snd_pcm_state = trueblnr;
+ }
+ return (My_snd_pcm_state != NULL);
+}
+
+typedef int (*snd_pcm_prepare_ProcPtr)(My_snd_pcm_t *pcm);
+LOCALVAR snd_pcm_prepare_ProcPtr My_snd_pcm_prepare = NULL;
+LOCALVAR blnr Did_snd_pcm_prepare = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_prepare(void)
+{
+ if (! Did_snd_pcm_prepare) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_prepare = (snd_pcm_prepare_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_prepare");
+ if (NULL == My_snd_pcm_prepare) {
+ fprintf(stderr, "dlsym snd_pcm_prepare failed\n");
+ }
+ }
+ Did_snd_pcm_prepare = trueblnr;
+ }
+ return (My_snd_pcm_prepare != NULL);
+}
+
+typedef int (*snd_pcm_start_ProcPtr)(My_snd_pcm_t *pcm);
+LOCALVAR snd_pcm_start_ProcPtr My_snd_pcm_start = NULL;
+LOCALVAR blnr Did_snd_pcm_start = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_start(void)
+{
+ if (! Did_snd_pcm_start) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_start = (snd_pcm_start_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_start");
+ if (NULL == My_snd_pcm_start) {
+ fprintf(stderr, "dlsym snd_pcm_start failed\n");
+ }
+ }
+ Did_snd_pcm_start = trueblnr;
+ }
+ return (My_snd_pcm_start != NULL);
+}
+
+typedef int (*snd_pcm_resume_ProcPtr)(My_snd_pcm_t *pcm);
+LOCALVAR snd_pcm_resume_ProcPtr My_snd_pcm_resume = NULL;
+LOCALVAR blnr Did_snd_pcm_resume = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_resume(void)
+{
+ if (! Did_snd_pcm_resume) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_resume = (snd_pcm_resume_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_resume");
+ if (NULL == My_snd_pcm_resume) {
+ fprintf(stderr, "dlsym snd_pcm_resume failed\n");
+ }
+ }
+ Did_snd_pcm_resume = trueblnr;
+ }
+ return (My_snd_pcm_resume != NULL);
+}
+
+typedef My_snd_pcm_sframes_t (*snd_pcm_avail_update_ProcPtr)
+ (My_snd_pcm_t *pcm);
+LOCALVAR snd_pcm_avail_update_ProcPtr My_snd_pcm_avail_update = NULL;
+LOCALVAR blnr Did_snd_pcm_avail_update = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_avail_update(void)
+{
+ if (! Did_snd_pcm_avail_update) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_avail_update = (snd_pcm_avail_update_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_avail_update");
+ if (NULL == My_snd_pcm_avail_update) {
+ fprintf(stderr, "dlsym snd_pcm_avail_update failed\n");
+ }
+ }
+ Did_snd_pcm_avail_update = trueblnr;
+ }
+ return (My_snd_pcm_avail_update != NULL);
+}
+
+typedef My_snd_pcm_sframes_t (*snd_pcm_writei_ProcPtr)
+ (My_snd_pcm_t *pcm, const void *buffer, My_snd_pcm_uframes_t size);
+LOCALVAR snd_pcm_writei_ProcPtr My_snd_pcm_writei = NULL;
+LOCALVAR blnr Did_snd_pcm_writei = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_writei(void)
+{
+ if (! Did_snd_pcm_writei) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_writei = (snd_pcm_writei_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_writei");
+ if (NULL == My_snd_pcm_writei) {
+ fprintf(stderr, "dlsym snd_pcm_writei failed\n");
+ }
+ }
+ Did_snd_pcm_writei = trueblnr;
+ }
+ return (My_snd_pcm_writei != NULL);
+}
+
+typedef int (*snd_pcm_drop_ProcPtr)(My_snd_pcm_t *pcm);
+LOCALVAR snd_pcm_drop_ProcPtr My_snd_pcm_drop = NULL;
+LOCALVAR blnr Did_snd_pcm_drop = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_drop(void)
+{
+ if (! Did_snd_pcm_drop) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_drop = (snd_pcm_drop_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_drop");
+ if (NULL == My_snd_pcm_drop) {
+ fprintf(stderr, "dlsym snd_pcm_drop failed\n");
+ }
+ }
+ Did_snd_pcm_drop = trueblnr;
+ }
+ return (My_snd_pcm_drop != NULL);
+}
+
+#if RaspbianWorkAround
+typedef int (*snd_pcm_status_malloc_ProcPtr)
+ (My_snd_pcm_status_t **ptr);
+LOCALVAR snd_pcm_status_malloc_ProcPtr My_snd_pcm_status_malloc = NULL;
+LOCALVAR blnr Did_snd_pcm_status_malloc = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_status_malloc(void)
+{
+ if (! Did_snd_pcm_status_malloc) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_status_malloc = (snd_pcm_status_malloc_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_status_malloc");
+ if (NULL == My_snd_pcm_status_malloc) {
+ fprintf(stderr, "dlsym snd_pcm_status_malloc failed\n");
+ }
+ }
+ Did_snd_pcm_status_malloc = trueblnr;
+ }
+ return (My_snd_pcm_status_malloc != NULL);
+}
+#endif
+
+#if RaspbianWorkAround
+typedef int (*snd_pcm_status_ProcPtr)(My_snd_pcm_t *pcm,
+ My_snd_pcm_status_t *status);
+LOCALVAR snd_pcm_status_ProcPtr My_snd_pcm_status = NULL;
+LOCALVAR blnr Did_snd_pcm_status = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_status(void)
+{
+ if (! Did_snd_pcm_status) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_status = (snd_pcm_status_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_status");
+ if (NULL == My_snd_pcm_status) {
+ fprintf(stderr, "dlsym snd_pcm_status failed\n");
+ }
+ }
+ Did_snd_pcm_status = trueblnr;
+ }
+ return (My_snd_pcm_status != NULL);
+}
+#endif
+
+#if RaspbianWorkAround
+typedef My_snd_pcm_uframes_t (*snd_pcm_status_get_avail_ProcPtr)
+ (const My_snd_pcm_status_t *obj);
+LOCALVAR snd_pcm_status_get_avail_ProcPtr
+ My_snd_pcm_status_get_avail = NULL;
+LOCALVAR blnr Did_snd_pcm_status_get_avail = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_pcm_status_get_avail(void)
+{
+ if (! Did_snd_pcm_status_get_avail) {
+ if (HaveAlsaLib()) {
+ My_snd_pcm_status_get_avail =
+ (snd_pcm_status_get_avail_ProcPtr)
+ dlsym(alsa_handle, "snd_pcm_status_get_avail");
+ if (NULL == My_snd_pcm_status_get_avail) {
+ fprintf(stderr,
+ "dlsym snd_pcm_status_get_avail failed\n");
+ }
+ }
+ Did_snd_pcm_status_get_avail = trueblnr;
+ }
+ return (My_snd_pcm_status_get_avail != NULL);
+}
+#endif
+
+typedef const char * (*snd_strerror_ProcPtr)(int errnum);
+LOCALVAR snd_strerror_ProcPtr My_snd_strerror = NULL;
+LOCALVAR blnr Did_snd_strerror = falseblnr;
+
+LOCALFUNC blnr HaveMy_snd_strerror(void)
+{
+ if (! Did_snd_strerror) {
+ if (HaveAlsaLib()) {
+ My_snd_strerror = (snd_strerror_ProcPtr)
+ dlsym(alsa_handle, "snd_strerror");
+ if (NULL == My_snd_strerror) {
+ fprintf(stderr, "dlsym snd_strerror failed\n");
+ }
+ }
+ Did_snd_strerror = trueblnr;
+ }
+ return (My_snd_strerror != NULL);
+}
+
+#endif
+
+
+/*
+ The elaborate private buffer is mostly
+ redundant since alsa has its own ring
+ buffer. But using it keeps the code
+ closer to the other ports. And anyway
+ there is no guarantee just what size
+ buffer you'll get from alsa.
+*/
+
+
+#if 4 == kLn2SoundSampSz
+LOCALPROC ConvertSoundBlockToNative(tpSoundSamp p)
+{
+ int i;
+
+ for (i = kOneBuffLen; --i >= 0; ) {
+ *p++ -= 0x8000;
+ }
+}
+#else
+#define ConvertSoundBlockToNative(p)
+#endif
+
+#define desired_alsa_buffer_size kAllBuffLen
+#define desired_alsa_period_size kOneBuffLen
+
+LOCALVAR char *alsadev_name = NULL;
+
+LOCALVAR My_snd_pcm_t *pcm_handle = NULL;
+LOCALVAR My_snd_pcm_uframes_t buffer_size;
+LOCALVAR My_snd_pcm_uframes_t period_size;
+
+
+LOCALVAR blnr MySound_StartPend = falseblnr;
+
+#if RaspbianWorkAround
+LOCALVAR My_snd_pcm_status_t *my_status = NULL;
+
+LOCALFUNC blnr HaveMyStatusAlloc(void)
+{
+ if (NULL == my_status) {
+ if (HaveMy_snd_pcm_status_malloc())
+ if (HaveMy_snd_pcm_status())
+ if (HaveMy_snd_pcm_status_get_avail())
+ {
+ if (My_snd_pcm_status_malloc(&my_status) < 0) {
+ my_status = NULL; /* just to make sure */
+ } else {
+ /* snd_pcm_status_free(my_status); */
+ }
+ }
+ }
+
+ return NULL != my_status;
+}
+#endif
+
+LOCALPROC MySound_WriteOut(void)
+{
+ int retry_count = 32;
+
+label_retry:
+ if (--retry_count > 0) {
+ My_snd_pcm_sframes_t avail;
+ int err;
+ My_snd_pcm_state_t cur_state = My_snd_pcm_state(pcm_handle);
+
+ if (My_SND_PCM_STATE_PREPARED == cur_state) {
+ if (! MySound_StartPend) {
+ if (TheFillOffset - ThePlayOffset >= kAllBuffLen) {
+ MySound_StartPend = trueblnr;
+ }
+ }
+ if (MySound_StartPend) {
+ cur_state = My_SND_PCM_STATE_RUNNING;
+ }
+ }
+
+ if (My_SND_PCM_STATE_RUNNING != cur_state) {
+ switch (cur_state) {
+ case My_SND_PCM_STATE_SETUP:
+ case My_SND_PCM_STATE_XRUN:
+ err = My_snd_pcm_prepare(pcm_handle);
+ if (err < 0) {
+ fprintf(stderr, "pcm prepare error: %s\n",
+ My_snd_strerror(err));
+ } else {
+ /* fprintf(stderr, "prepare succeeded\n"); */
+ goto label_retry;
+ }
+ break;
+ case My_SND_PCM_STATE_SUSPENDED:
+ err = My_snd_pcm_resume(pcm_handle);
+ if (err < 0) {
+ fprintf(stderr, "pcm resume error: %s\n",
+ My_snd_strerror(err));
+ } else {
+ /* fprintf(stderr, "resume succeeded\n"); */
+ goto label_retry;
+ }
+ break;
+ case My_SND_PCM_STATE_DISCONNECTED:
+ /* just abort ? */
+ break;
+ case My_SND_PCM_STATE_PREPARED:
+ /* leave */
+ break;
+ default:
+ fprintf(stderr, "unknown alsa pcm state\n");
+ break;
+ }
+ } else if ((avail = My_snd_pcm_avail_update(pcm_handle)) < 0) {
+ fprintf(stderr, "pcm update error: %s\n",
+ My_snd_strerror(avail));
+ } else {
+ tpSoundSamp NextPlayPtr;
+ ui4b PlayNowSize = 0;
+ ui4b MaskedFillOffset = ThePlayOffset & kOneBuffMask;
+
+#if RaspbianWorkAround
+ if ((avail > buffer_size) || (avail < 0)) {
+ /*
+ fprintf(stderr, "need avail workaround: %d\n",
+ (int)avail);
+ */
+ /* work around bug observed in Raspbian */
+ if (HaveMyStatusAlloc()) {
+ if (My_snd_pcm_status(pcm_handle, my_status) >= 0) {
+ avail = My_snd_pcm_status_get_avail(my_status);
+ }
+ }
+ }
+#endif
+
+ if (! MySound_StartPend) {
+ My_snd_pcm_uframes_t used = buffer_size - avail;
+ ui4b TotPendBuffs = used >> kLnOneBuffLen;
+
+ if (TotPendBuffs < MinFilledSoundBuffs) {
+ MinFilledSoundBuffs = TotPendBuffs;
+ }
+ /* fprintf(stderr, "buffer used %d\n", (int)used); */
+ }
+
+ if (MaskedFillOffset != 0) {
+ /* take care of left overs */
+ PlayNowSize = kOneBuffLen - MaskedFillOffset;
+ NextPlayPtr =
+ TheSoundBuffer + (ThePlayOffset & kAllBuffMask);
+ } else if (0 !=
+ ((TheFillOffset - ThePlayOffset) >> kLnOneBuffLen))
+ {
+ PlayNowSize = kOneBuffLen;
+ NextPlayPtr =
+ TheSoundBuffer + (ThePlayOffset & kAllBuffMask);
+ } else {
+ /* nothing to play now */
+ }
+
+ if (PlayNowSize > avail) {
+ /*
+ This isn't supposed to be needed with nonblock
+ mode. But in Ubuntu 7.04 running in Parallels,
+ snd_pcm_writei seemed to block anyway.
+ */
+ PlayNowSize = avail;
+ }
+
+ if (0 != PlayNowSize) {
+ err = My_snd_pcm_writei(
+ pcm_handle, NextPlayPtr, PlayNowSize);
+ if (err < 0) {
+ if ((- EAGAIN == err) || (- ESTRPIPE == err)) {
+ /* buffer full, try again later */
+ /* fprintf(stderr, "pcm write: EAGAIN\n"); */
+ } else if (- EPIPE == err) {
+ /* buffer seems to have emptied */
+ /* fprintf(stderr, "pcm write emptied\n"); */
+ goto label_retry;
+ } else {
+ fprintf(stderr, "pcm write error: %s\n",
+ My_snd_strerror(err));
+ }
+ } else {
+ ThePlayOffset += err;
+ goto label_retry;
+ }
+ } else if (MySound_StartPend) {
+ MySound_StartPend = falseblnr;
+ if ((err = My_snd_pcm_start(pcm_handle)) < 0) {
+ fprintf(stderr, "pcm start error: %s\n",
+ My_snd_strerror(err));
+ }
+ }
+ }
+ }
+}
+
+LOCALPROC MySound_Start(void)
+{
+ if (pcm_handle != NULL) {
+ MySound_Start0();
+ }
+}
+
+LOCALPROC MySound_Stop(void)
+{
+ if (pcm_handle != NULL) {
+ My_snd_pcm_drop(pcm_handle);
+ }
+}
+
+LOCALFUNC blnr HaveAlsaRoutines(void)
+{
+ blnr IsOk = falseblnr;
+
+ if (HaveMy_snd_pcm_open())
+ if (HaveMy_snd_pcm_close())
+ if (HaveMy_snd_pcm_hw_params_malloc())
+ if (HaveMy_snd_pcm_hw_params_free())
+ if (HaveMy_snd_pcm_hw_params_any())
+ if (HaveMy_snd_pcm_hw_params_set_access())
+ if (HaveMy_snd_pcm_hw_params_set_format())
+ if (HaveMy_snd_pcm_hw_params_set_rate_near())
+ if (HaveMy_snd_pcm_hw_params_set_channels())
+ if (HaveMy_snd_pcm_hw_params_set_buffer_size_near())
+ if (HaveMy_snd_pcm_hw_params_set_period_size_near())
+ if (HaveMy_snd_pcm_hw_params())
+ if (HaveMy_snd_pcm_sw_params_malloc())
+ if (HaveMy_snd_pcm_sw_params_free())
+ if (HaveMy_snd_pcm_sw_params_current())
+ if (HaveMy_snd_pcm_sw_params_set_start_threshold())
+ if (HaveMy_snd_pcm_sw_params_set_avail_min())
+ if (HaveMy_snd_pcm_sw_params())
+ if (HaveMy_snd_pcm_nonblock())
+ if (HaveMy_snd_pcm_state())
+ if (HaveMy_snd_pcm_prepare())
+ if (HaveMy_snd_pcm_start())
+ if (HaveMy_snd_pcm_resume())
+ if (HaveMy_snd_pcm_avail_update())
+ if (HaveMy_snd_pcm_writei())
+ if (HaveMy_snd_pcm_drop())
+ if (HaveMy_snd_strerror())
+ {
+ IsOk = trueblnr;
+ }
+
+ return IsOk;
+}
+
+#if 4 == kLn2SoundSampSz
+#define MyDesiredFormat My_SND_PCM_FORMAT_S16
+#else
+#define MyDesiredFormat My_SND_PCM_FORMAT_U8
+#endif
+
+LOCALPROC MySound_Init0(void)
+{
+ My_snd_pcm_hw_params_t *hw_params = NULL;
+ My_snd_pcm_sw_params_t *sw_params = NULL;
+ unsigned int rrate = SOUND_SAMPLERATE;
+ int err;
+
+ buffer_size = desired_alsa_buffer_size;
+ period_size = desired_alsa_period_size;
+
+ /* Open the sound device */
+ if (NULL == alsadev_name) {
+ alsadev_name = getenv("AUDIODEV");
+ if (NULL == alsadev_name) {
+ alsadev_name = strdup("default");
+ }
+ }
+
+ if ((err = My_snd_pcm_open(&pcm_handle, alsadev_name,
+ My_SND_PCM_STREAM_PLAYBACK, My_SND_PCM_NONBLOCK)) < 0)
+ {
+ fprintf(stderr, "cannot open audio device %s (%s)\n",
+ alsadev_name, My_snd_strerror(err));
+ pcm_handle = NULL;
+ } else
+ /* Set some hardware parameters */
+ if ((err = My_snd_pcm_hw_params_malloc(&hw_params)) < 0) {
+ fprintf(stderr,
+ "cannot allocate hardware parameter structure (%s)\n",
+ My_snd_strerror(err));
+ hw_params = NULL;
+ } else
+ if ((err = My_snd_pcm_hw_params_any(pcm_handle, hw_params)) < 0) {
+ fprintf(stderr,
+ "cannot initialize hardware parameter structure (%s)\n",
+ My_snd_strerror(err));
+ } else
+ if ((err = My_snd_pcm_hw_params_set_access(pcm_handle,
+ hw_params, My_SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
+ {
+ fprintf(stderr, "cannot set access type (%s)\n",
+ My_snd_strerror(err));
+ } else
+ if ((err = My_snd_pcm_hw_params_set_format(pcm_handle,
+ hw_params, MyDesiredFormat)) < 0)
+ {
+ fprintf(stderr, "cannot set sample format (%s)\n",
+ My_snd_strerror(err));
+ } else
+ if ((err = My_snd_pcm_hw_params_set_rate_near(pcm_handle,
+ hw_params, &rrate, NULL)) < 0)
+ {
+ fprintf(stderr, "cannot set sample rate (%s)\n",
+ My_snd_strerror(err));
+ } else
+ if ((err = My_snd_pcm_hw_params_set_channels(pcm_handle,
+ hw_params, 1)) < 0)
+ {
+ fprintf(stderr, "cannot set channel count (%s)\n",
+ My_snd_strerror(err));
+ } else
+ if ((err = My_snd_pcm_hw_params_set_buffer_size_near(pcm_handle,
+ hw_params, &buffer_size)) < 0)
+ {
+ fprintf(stderr, "cannot set buffer size count (%s)\n",
+ My_snd_strerror(err));
+ } else
+ if ((err = My_snd_pcm_hw_params_set_period_size_near(pcm_handle,
+ hw_params, &period_size, NULL)) < 0)
+ {
+ fprintf(stderr, "cannot set period size count (%s)\n",
+ My_snd_strerror(err));
+ } else
+ if ((err = My_snd_pcm_hw_params(pcm_handle, hw_params)) < 0) {
+ fprintf(stderr, "cannot set parameters (%s)\n",
+ My_snd_strerror(err));
+ } else
+ {
+ if (rrate != SOUND_SAMPLERATE) {
+ fprintf(stderr, "Warning: sample rate is off by %i Hz\n",
+ SOUND_SAMPLERATE - rrate);
+ }
+
+#if 0
+ if (buffer_size != desired_alsa_buffer_size) {
+ fprintf(stderr,
+ "Warning: buffer size is off,"
+ " desired %li, actual %li\n",
+ desired_alsa_buffer_size, buffer_size);
+ }
+
+ if (period_size != desired_alsa_period_size) {
+ fprintf(stderr,
+ "Warning: period size is off,"
+ " desired %li, actual %li\n",
+ desired_alsa_period_size, period_size);
+ }
+#endif
+
+ My_snd_pcm_hw_params_free(hw_params);
+ hw_params = NULL;
+
+ /* Set some software parameters */
+ if ((err = My_snd_pcm_sw_params_malloc(&sw_params)) < 0) {
+ fprintf(stderr,
+ "cannot allocate software parameter structure (%s)\n",
+ My_snd_strerror(err));
+ sw_params = NULL;
+ } else
+ if ((err = My_snd_pcm_sw_params_current(pcm_handle,
+ sw_params)) < 0)
+ {
+ fprintf(stderr,
+ "Unable to determine current"
+ " sw_params for playback: %s\n",
+ My_snd_strerror(err));
+ } else
+ if ((err = My_snd_pcm_sw_params_set_start_threshold(pcm_handle,
+ sw_params, 0x7FFFFFFF /* buffer_size - period_size */)) < 0)
+ {
+ fprintf(stderr,
+ "Unable to set start threshold mode for playback: %s\n",
+ My_snd_strerror(err));
+ } else
+#if 0
+ if ((err = My_snd_pcm_sw_params_set_avail_min(pcm_handle,
+ sw_params, period_size)) < 0)
+ {
+ fprintf(stderr,
+ "Unable to set avail min for playback: %s\n",
+ My_snd_strerror(err));
+ } else
+#endif
+ /*
+ snd_pcm_sw_params_set_xfer_align deprecated, but
+ call if available. According to one report, bad results
+ in old version of alsa lib if not called.
+ */
+ if (HaveMy_snd_pcm_sw_params_set_xfer_align()
+ && ((err = My_snd_pcm_sw_params_set_xfer_align(pcm_handle,
+ sw_params, 1)) < 0))
+ {
+ fprintf(stderr,
+ "Unable to set transfer align for playback: %s\n",
+ My_snd_strerror(err));
+ } else
+ if ((err = My_snd_pcm_sw_params(pcm_handle, sw_params)) < 0) {
+ fprintf(stderr,
+ "Unable to set sw params for playback: %s\n",
+ My_snd_strerror(err));
+ } else
+ {
+ My_snd_pcm_sw_params_free(sw_params);
+ sw_params = NULL;
+
+ My_snd_pcm_nonblock(pcm_handle, 0);
+
+ goto label_done; /* success */
+ }
+ }
+
+ /* clean up after failure */
+
+ if (sw_params != NULL) {
+ My_snd_pcm_sw_params_free(sw_params);
+ }
+ if (hw_params != NULL) {
+ My_snd_pcm_hw_params_free(hw_params);
+ }
+ if (pcm_handle != NULL) {
+ My_snd_pcm_close(pcm_handle);
+ pcm_handle = NULL;
+ }
+
+label_done:
+ ;
+}
+
+LOCALFUNC blnr MySound_Init(void)
+{
+ if (HaveAlsaRoutines()) {
+ MySound_Init0();
+ }
+
+ return trueblnr; /* keep going, even if no sound */
+}
+
+LOCALPROC MySound_UnInit(void)
+{
+ if (NULL != pcm_handle) {
+ if (HaveMy_snd_pcm_close()) {
+ My_snd_pcm_close(pcm_handle);
+ }
+ pcm_handle = NULL;
+ }
+ MyCloseAlsaLib();
+}
+
+GLOBALOSGLUPROC MySound_EndWrite(ui4r actL)
+{
+ if (MySound_EndWrite0(actL)) {
+ ConvertSoundBlockToNative(TheSoundBuffer
+ + ((TheFillOffset - kOneBuffLen) & kAllBuffMask));
+ if (NULL != pcm_handle) {
+ MySound_WriteOut();
+ }
+ }
+}
+
+LOCALPROC MySound_SecondNotify(void)
+{
+ if (NULL != pcm_handle) {
+ MySound_SecondNotify0();
+ }
+}
+
+#define UsingAlsa 1
--- /dev/null
+++ b/src/SGLUDDSP.h
@@ -1,0 +1,228 @@
+/*
+ SGLUDDSP.h
+
+ Copyright (C) 2012 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Sound GLUe for "/Dev/DSP"
+ OSS and related, accessed through "/dev/dsp"
+*/
+
+LOCALVAR int audio_fd = -1;
+LOCALVAR blnr audio_started;
+
+#if 4 == kLn2SoundSampSz
+LOCALPROC ConvertSoundBlockToNative(tpSoundSamp p)
+{
+ int i;
+
+ for (i = kOneBuffLen; --i >= 0; ) {
+ *p++ -= 0x8000;
+ }
+}
+#else
+#define ConvertSoundBlockToNative(p)
+#endif
+
+LOCALPROC MySound_WriteOut(void)
+{
+ int retry_count = 32;
+
+label_retry:
+ if (--retry_count > 0) {
+ int err;
+ struct audio_buf_info info;
+
+ if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) != 0) {
+ fprintf(stderr, "SNDCTL_DSP_GETOSPACE fails\n");
+ } else {
+ tpSoundSamp NextPlayPtr;
+ ui4b PlayNowSize = 0;
+ ui4b MaskedFillOffset = ThePlayOffset & kOneBuffMask;
+ ui4b PrivateBuffUsed = TheFillOffset - ThePlayOffset;
+ int used = (info.fragstotal * info.fragsize) - info.bytes;
+
+ if (audio_started) {
+ ui4b TotPendBuffs = used >> kLnOneBuffSz;
+
+ if (TotPendBuffs < MinFilledSoundBuffs) {
+ MinFilledSoundBuffs = TotPendBuffs;
+ }
+ /* fprintf(stderr, "buffer used %d\n", (int)used); */
+ } else {
+ if (PrivateBuffUsed >= kAllBuffLen - kOneBuffLen) {
+ audio_started = trueblnr;
+ } else {
+ info.bytes = 0;
+ }
+ }
+
+ if (MaskedFillOffset != 0) {
+ /* take care of left overs */
+ PlayNowSize = kOneBuffLen - MaskedFillOffset;
+ NextPlayPtr =
+ TheSoundBuffer + (ThePlayOffset & kAllBuffMask);
+ } else if (0 !=
+ ((TheFillOffset - ThePlayOffset) >> kLnOneBuffLen))
+ {
+ PlayNowSize = kOneBuffLen;
+ NextPlayPtr =
+ TheSoundBuffer + (ThePlayOffset & kAllBuffMask);
+ } else {
+ /* nothing to play now */
+ }
+
+#if 4 == kLn2SoundSampSz
+ PlayNowSize <<= 1;
+#endif
+
+ if (PlayNowSize > info.bytes) {
+ PlayNowSize = info.bytes;
+ }
+
+ if (0 != PlayNowSize) {
+ err = write(
+ audio_fd, NextPlayPtr, PlayNowSize);
+ if (err < 0) {
+ if (- EAGAIN == err) {
+ /* buffer full, try again later */
+ fprintf(stderr, "pcm write: EAGAIN\n");
+ } else if (- EPIPE == err) {
+ /* buffer seems to have emptied */
+ fprintf(stderr, "pcm write emptied\n");
+ goto label_retry;
+ } else {
+ fprintf(stderr, "audio_fd write error: %d\n",
+ err);
+ }
+ } else {
+ ThePlayOffset += err
+#if 4 == kLn2SoundSampSz
+ >> 1
+#endif
+ ;
+ goto label_retry;
+ }
+ }
+ }
+ }
+}
+
+LOCALPROC MySound_Start(void)
+{
+ if (audio_fd >= 0) {
+ MySound_Start0();
+ audio_started = falseblnr;
+ }
+}
+
+LOCALPROC MySound_Stop(void)
+{
+ if (audio_fd >= 0) {
+ if (0 !=
+ ioctl(audio_fd, SNDCTL_DSP_RESET /* SNDCTL_DSP_HALT */,
+ NULL))
+ {
+ fprintf(stderr, "SNDCTL_DSP_RESET fails\n");
+ }
+ }
+}
+
+#if 4 == kLn2SoundSampSz
+#define MyDesiredFormat AFMT_S16_NE
+#else
+#define MyDesiredFormat AFMT_U8
+#endif
+
+LOCALFUNC blnr MySound_Init(void)
+{
+ blnr IsOk = falseblnr;
+
+ audio_fd = open(AudioDevPath, O_WRONLY, 0);
+ if (audio_fd < 0) {
+ fprintf(stderr, "open /dev/dsp fails: %d\n", audio_fd);
+ } else {
+ int fragment_value = (16 /* 16 fragments */ << 16)
+#if 4 == kLn2SoundSampSz
+ | 10 /* of 1024 bytes */
+#else
+ | 9 /* of 512 bytes */
+#endif
+ ;
+ int channels_value = 1;
+ int fmt_value = MyDesiredFormat;
+ int speed_value = SOUND_SAMPLERATE;
+
+ /* fprintf(stderr, "open /dev/dsp works\n"); */
+
+ if (0 !=
+ ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_value))
+ {
+ fprintf(stderr, "SNDCTL_DSP_SETFRAGMENT fails\n");
+ } else if ((0 !=
+ ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels_value))
+ || (channels_value != 1))
+ {
+ fprintf(stderr, "SNDCTL_DSP_CHANNELS fails\n");
+ } else if ((0 !=
+ ioctl(audio_fd, SNDCTL_DSP_SETFMT, &fmt_value))
+ || (fmt_value != MyDesiredFormat))
+ {
+ fprintf(stderr, "SNDCTL_DSP_SETFMT fails\n");
+ } else if ((0 !=
+ ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed_value))
+ || (speed_value != SOUND_SAMPLERATE))
+ {
+ fprintf(stderr, "SNDCTL_DSP_SPEED fails\n");
+ } else
+ {
+ IsOk = trueblnr;
+ }
+
+ if (! IsOk) {
+ (void) close(audio_fd);
+ audio_fd = -1;
+ }
+ }
+
+ return trueblnr; /* keep going, even if no sound */
+}
+
+LOCALPROC MySound_UnInit(void)
+{
+ if (audio_fd >= 0) {
+ if (close(audio_fd) != 0) {
+ fprintf(stderr, "close /dev/dsp fails\n");
+ }
+ audio_fd = -1;
+ }
+}
+
+GLOBALOSGLUPROC MySound_EndWrite(ui4r actL)
+{
+ if (MySound_EndWrite0(actL)) {
+ ConvertSoundBlockToNative(TheSoundBuffer
+ + ((TheFillOffset - kOneBuffLen) & kAllBuffMask));
+ if (audio_fd >= 0) {
+ MySound_WriteOut();
+ }
+ }
+}
+
+LOCALPROC MySound_SecondNotify(void)
+{
+ if (audio_fd >= 0) {
+ MySound_SecondNotify0();
+ }
+}
--- /dev/null
+++ b/src/SNDEMDEV.c
@@ -1,0 +1,223 @@
+/*
+ SNDEMDEV.c
+
+ Copyright (C) 2003 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ SouND EMulated DEVice
+
+ Emulation of Sound in the Mac Plus could go here.
+
+ This code adapted from "Sound.c" in vMac by Philip Cummins.
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+
+#include "MYOSGLUE.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#include "MINEM68K.h"
+#endif
+
+#include "SNDEMDEV.h"
+
+
+#if MySoundEnabled
+
+#define kSnd_Main_Offset 0x0300
+#define kSnd_Alt_Offset 0x5F00
+
+#define kSnd_Main_Buffer (kRAM_Size - kSnd_Main_Offset)
+#define kSnd_Alt_Buffer (kRAM_Size - kSnd_Alt_Offset)
+
+/*
+ approximate volume levels of vMac, so:
+
+ x * vol_mult[SoundVolume] >> 16
+ + vol_offset[SoundVolume]
+ = {approx} (x - kCenterSound) / (8 - SoundVolume) + kCenterSound;
+*/
+
+LOCALVAR const ui4b vol_mult[] = {
+ 8192, 9362, 10922, 13107, 16384, 21845, 32768
+};
+
+LOCALVAR const trSoundSamp vol_offset[] = {
+#if 3 == kLn2SoundSampSz
+ 112, 110, 107, 103, 96, 86, 64, 0
+#elif 4 == kLn2SoundSampSz
+ 28672, 28087, 27307, 26215, 24576, 21846, 16384, 0
+#else
+#error "unsupported kLn2SoundSampSz"
+#endif
+};
+
+LOCALVAR const ui4b SubTick_offset[kNumSubTicks] = {
+ 0, 25, 50, 90, 102, 115, 138, 161,
+ 185, 208, 231, 254, 277, 300, 323, 346
+};
+
+LOCALVAR const ui3r SubTick_n[kNumSubTicks] = {
+ 25, 25, 40, 12, 13, 23, 23, 24,
+ 23, 23, 23, 23, 23, 23, 23, 24
+};
+
+/*
+ One version of free form sound driver
+ spends around 18000 cycles writing
+ offsets 50 to 370, then around another 3000
+ cycles writing 0 to 50. So be done
+ with 0 to 50 at end of second sixtieth.
+*/
+
+/*
+ Different in system 6.0.4:
+ spends around 23500 cycles writing
+ offsets 90 to 370, then around another 7500
+ cycles writing 0 to 90. This is nastier,
+ because gets to be a very small gap
+ between where is being read and
+ where written. So read a bit in
+ advance for third subtick.
+*/
+
+/*
+ startup sound spends around 19500 cycles
+ writing offsets 0 to 370. presumably
+ writing offset 0 before it is read.
+*/
+
+LOCALVAR ui5b SoundInvertPhase = 0;
+LOCALVAR ui4b SoundInvertState = 0;
+
+IMPORTFUNC ui4b GetSoundInvertTime(void);
+
+GLOBALPROC MacSound_SubTick(int SubTick)
+{
+ ui4r actL;
+ tpSoundSamp p;
+ ui4r i;
+ ui5b StartOffset = SubTick_offset[SubTick];
+ ui4r n = SubTick_n[SubTick];
+ unsigned long addy =
+#ifdef SoundBuffer
+ (SoundBuffer == 0) ? kSnd_Alt_Buffer :
+#endif
+ kSnd_Main_Buffer;
+#ifndef ln2mtb
+ ui3p addr = addy + (2 * StartOffset) + RAM;
+#else
+ CPTR addr = addy + (2 * StartOffset);
+#endif
+ ui4b SoundInvertTime = GetSoundInvertTime();
+ ui3b SoundVolume = SoundVolb0
+ | (SoundVolb1 << 1)
+ | (SoundVolb2 << 2);
+
+#if dbglog_HAVE && 0
+ dbglog_StartLine();
+ dbglog_writeCStr("reading sound buffer ");
+ dbglog_writeHex(StartOffset);
+ dbglog_writeCStr(" to ");
+ dbglog_writeHex(StartOffset + n);
+ dbglog_writeReturn();
+#endif
+
+label_retry:
+ p = MySound_BeginWrite(n, &actL);
+ if (actL > 0) {
+ if (SoundDisable && (SoundInvertTime == 0)) {
+ for (i = 0; i < actL; i++) {
+#if 0
+ *p++ = 0x00; /* this is believed more accurate */
+#else
+ /* But this avoids more clicks. */
+ *p++ = kCenterSound;
+#endif
+ }
+ } else {
+ for (i = 0; i < actL; i++) {
+ /* Copy sound data, high byte of each word */
+ *p++ =
+#ifndef ln2mtb
+ *addr
+#else
+ get_vm_byte(addr)
+#endif
+#if 4 == kLn2SoundSampSz
+ << 8
+#endif
+ ;
+
+ /* Move the address on */
+ addr += 2;
+ }
+
+ if (SoundInvertTime != 0) {
+ ui5b PhaseIncr = (ui5b)SoundInvertTime * (ui5b)20;
+ p -= actL;
+
+ for (i = 0; i < actL; i++) {
+ if (SoundInvertPhase < 704) {
+ ui5b OnPortion = 0;
+ ui5b LastPhase = 0;
+ do {
+ if (! SoundInvertState) {
+ OnPortion +=
+ (SoundInvertPhase - LastPhase);
+ }
+ SoundInvertState = ! SoundInvertState;
+ LastPhase = SoundInvertPhase;
+ SoundInvertPhase += PhaseIncr;
+ } while (SoundInvertPhase < 704);
+ if (! SoundInvertState) {
+ OnPortion += 704 - LastPhase;
+ }
+ *p = (*p * OnPortion) / 704;
+ } else {
+ if (SoundInvertState) {
+ *p = 0;
+ }
+ }
+ SoundInvertPhase -= 704;
+ p++;
+ }
+ }
+ }
+
+ if (SoundVolume < 7) {
+ /*
+ Usually have volume at 7, so this
+ is just for completeness.
+ */
+ ui5b mult = (ui5b)vol_mult[SoundVolume];
+ trSoundSamp offset = vol_offset[SoundVolume];
+
+ p -= actL;
+ for (i = 0; i < actL; i++) {
+ *p = (trSoundSamp)((ui5b)(*p) * mult >> 16) + offset;
+ ++p;
+ }
+ }
+
+ MySound_EndWrite(actL);
+ n -= actL;
+ if (n > 0) {
+ goto label_retry;
+ }
+ }
+}
+
+#endif
--- /dev/null
+++ b/src/SNDEMDEV.h
@@ -1,0 +1,25 @@
+/*
+ SNDEMDEV.h
+
+ Copyright (C) 2003 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef SNDEMDEV_H
+#error "header already included"
+#else
+#define SNDEMDEV_H
+#endif
+
+#if MySoundEnabled
+EXPORTPROC MacSound_SubTick(int SubTick);
+#endif
--- /dev/null
+++ b/src/SONYEMDV.c
@@ -1,0 +1,1644 @@
+/*
+ SONYEMDV.c
+
+ Copyright (C) 2009 Philip Cummins, Jesus A. Alvarez, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ SONY floppy disk EMulated DeVice
+
+ The Sony hardware is not actually emulated. Instead the
+ ROM is patched to replace the Sony disk driver with
+ code that calls Mini vMac extensions implemented in
+ the file.
+
+ Information neeeded to better support the Disk Copy 4.2
+ format was found in libdc42.c of the Lisa Emulator Project
+ by Ray A. Arachelian, and adapted to Mini vMac
+ by Jesus A. Alvarez.
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+#include "MYOSGLUE.h"
+#include "ENDIANAC.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#include "MINEM68K.h"
+#endif
+
+#include "SONYEMDV.h"
+
+/*
+ ReportAbnormalID unused 0x090B - 0x09FF
+*/
+
+
+LOCALVAR ui5b vSonyMountedMask = 0;
+
+#define vSonyIsLocked(Drive_No) \
+ ((vSonyWritableMask & ((ui5b)1 << (Drive_No))) == 0)
+#define vSonyIsMounted(Drive_No) \
+ ((vSonyMountedMask & ((ui5b)1 << (Drive_No))) != 0)
+
+LOCALFUNC blnr vSonyNextPendingInsert0(tDrive *Drive_No)
+{
+ /* find next drive to Mount */
+ ui5b MountPending = vSonyInsertedMask & (~ vSonyMountedMask);
+ if (MountPending != 0) {
+ tDrive i;
+ for (i = 0; i < NumDrives; ++i) {
+ if ((MountPending & ((ui5b)1 << i)) != 0) {
+ *Drive_No = i;
+ return trueblnr; /* only one disk at a time */
+ }
+ }
+ }
+
+ return falseblnr;
+}
+
+LOCALFUNC tMacErr CheckReadableDrive(tDrive Drive_No)
+{
+ tMacErr result;
+
+ if (Drive_No >= NumDrives) {
+ result = mnvm_nsDrvErr;
+ } else if (! vSonyIsMounted(Drive_No)) {
+ result = mnvm_offLinErr;
+ } else {
+ result = mnvm_noErr;
+ }
+
+ return result;
+}
+
+LOCALFUNC tMacErr vSonyTransferVM(blnr IsWrite,
+ CPTR Buffera, tDrive Drive_No,
+ ui5r Sony_Start, ui5r Sony_Count, ui5r *Sony_ActCount)
+{
+ /*
+ Transfer data between emulated disk and emulated memory. Taking
+ into account that the emulated memory may not be contiguous in
+ real memory. (Though it generally is for macintosh emulation.)
+ */
+ tMacErr result;
+ ui5b contig;
+ ui5r actual;
+ ui3p Buffer;
+ ui5r offset = Sony_Start;
+ ui5r n = Sony_Count;
+
+label_1:
+ if (0 == n) {
+ result = mnvm_noErr;
+ } else {
+ Buffer = get_real_address0(n, ! IsWrite, Buffera, &contig);
+ if (0 == contig) {
+ result = mnvm_miscErr;
+ } else {
+ result = vSonyTransfer(IsWrite, Buffer, Drive_No,
+ offset, contig, &actual);
+ offset += actual;
+ Buffera += actual;
+ n -= actual;
+ if (mnvm_noErr == result) {
+ goto label_1;
+ }
+ }
+ }
+
+ if (nullpr != Sony_ActCount) {
+ *Sony_ActCount = Sony_Count - n;
+ }
+ return result;
+}
+
+LOCALPROC MyMoveBytesVM(CPTR srcPtr, CPTR dstPtr, si5b byteCount)
+{
+ ui3p src;
+ ui3p dst;
+ ui5b contigSrc;
+ ui5b contigDst;
+ ui5r contig;
+
+label_1:
+ if (0 != byteCount) {
+ src = get_real_address0(byteCount, falseblnr, srcPtr,
+ &contigSrc);
+ dst = get_real_address0(byteCount, trueblnr, dstPtr,
+ &contigDst);
+ if ((0 == contigSrc) || (0 == contigDst)) {
+ ReportAbnormalID(0x0901, "MyMoveBytesVM fails");
+ } else {
+ contig = (contigSrc < contigDst) ? contigSrc : contigDst;
+ MyMoveBytes(src, dst, contig);
+ srcPtr += contig;
+ dstPtr += contig;
+ byteCount -= contig;
+ goto label_1;
+ }
+ }
+}
+
+LOCALVAR ui5r ImageDataOffset[NumDrives];
+ /* size of any header in disk image file */
+LOCALVAR ui5r ImageDataSize[NumDrives];
+ /* size of disk image file contents */
+
+#if Sony_SupportTags
+LOCALVAR ui5r ImageTagOffset[NumDrives];
+ /* offset to disk image file tags */
+#endif
+
+#if Sony_SupportDC42
+#define kDC42offset_diskName 0
+#define kDC42offset_dataSize 64
+#define kDC42offset_tagSize 68
+#define kDC42offset_dataChecksum 72
+#define kDC42offset_tagChecksum 76
+#define kDC42offset_diskFormat 80
+#define kDC42offset_formatByte 81
+#define kDC42offset_private 82
+#define kDC42offset_userData 84
+#endif
+
+#define ChecksumBlockSize 1024
+
+#if Sony_SupportDC42 && Sony_WantChecksumsUpdated
+LOCALFUNC tMacErr DC42BlockChecksum(tDrive Drive_No,
+ ui5r Sony_Start, ui5r Sony_Count, ui5r *r)
+{
+ tMacErr result;
+ ui5r n;
+ ui3b Buffer[ChecksumBlockSize];
+ ui3b *p;
+ ui5b sum = 0;
+ ui5r offset = Sony_Start;
+ ui5r remaining = Sony_Count;
+
+ while (0 != remaining) {
+ /* read a block */
+ if (remaining > ChecksumBlockSize) {
+ n = ChecksumBlockSize;
+ } else {
+ n = remaining;
+ }
+
+ result = vSonyTransfer(falseblnr, Buffer, Drive_No, offset,
+ n, nullpr);
+ if (mnvm_noErr != result) {
+ return result;
+ }
+
+ offset += n;
+ remaining -= n;
+
+ /* add to Checksum */
+ p = Buffer;
+ n >>= 1; /* n = number of words */
+ while (0 != n) {
+ --n;
+ /* ROR.l sum+word */
+ sum += do_get_mem_word(p);
+ p += 2;
+ sum = (sum >> 1) | ((sum & 1) << 31);
+ }
+ }
+
+ *r = sum;
+ return mnvm_noErr;
+}
+#endif
+
+#if Sony_SupportDC42 && Sony_WantChecksumsUpdated
+#if Sony_SupportTags
+#define SizeCheckSumsToUpdate 8
+#else
+#define SizeCheckSumsToUpdate 4
+#endif
+#endif
+
+#if Sony_WantChecksumsUpdated
+LOCALPROC Drive_UpdateChecksums(tDrive Drive_No)
+{
+ if (! vSonyIsLocked(Drive_No)) {
+ ui5r DataOffset = ImageDataOffset[Drive_No];
+#if Sony_SupportDC42
+ if (kDC42offset_userData == DataOffset) {
+ /* a disk copy 4.2 image */
+ tMacErr result;
+ ui5r dataChecksum;
+ ui3b Buffer[SizeCheckSumsToUpdate];
+ ui5r Sony_Count = SizeCheckSumsToUpdate;
+ ui5r DataSize = ImageDataSize[Drive_No];
+
+ /* Checksum image data */
+ result = DC42BlockChecksum(Drive_No,
+ DataOffset, DataSize, &dataChecksum);
+ if (mnvm_noErr != result) {
+ ReportAbnormalID(0x0902, "Failed to find dataChecksum");
+ dataChecksum = 0;
+ }
+ do_put_mem_long(Buffer, dataChecksum);
+#if Sony_SupportTags
+ {
+ ui5r tagChecksum;
+ ui5r TagOffset = ImageTagOffset[Drive_No];
+ ui5r TagSize =
+ (0 == TagOffset) ? 0 : ((DataSize >> 9) * 12);
+ if (TagSize < 12) {
+ tagChecksum = 0;
+ } else {
+ /*
+ Checksum of tags doesn't include first block.
+ presumably because of bug in original disk
+ copy program.
+ */
+ result = DC42BlockChecksum(Drive_No,
+ TagOffset + 12, TagSize - 12, &tagChecksum);
+ if (mnvm_noErr != result) {
+ ReportAbnormalID(0x0903,
+ "Failed to find tagChecksum");
+ tagChecksum = 0;
+ }
+ }
+ do_put_mem_long(Buffer + 4, tagChecksum);
+ }
+#endif
+
+ /* write Checksums */
+ vSonyTransfer(trueblnr, Buffer, Drive_No,
+ kDC42offset_dataChecksum, Sony_Count, nullpr);
+ }
+#endif
+ }
+}
+#endif
+
+#define checkheaderoffset 0
+#define checkheadersize 128
+
+#define Sony_SupportOtherFormats Sony_SupportDC42
+
+LOCALFUNC tMacErr vSonyNextPendingInsert(tDrive *Drive_No)
+{
+ tDrive i;
+ tMacErr result;
+ ui5r L;
+
+ if (! vSonyNextPendingInsert0(&i)) {
+ result = mnvm_nsDrvErr;
+ } else {
+ result = vSonyGetSize(i, &L);
+ if (mnvm_noErr == result) {
+ /* first, set up for default format */
+ ui5r DataOffset = 0;
+ ui5r DataSize = L;
+#if Sony_SupportTags
+ ui5r TagOffset = 0;
+#endif
+
+#if Sony_SupportOtherFormats
+#if IncludeSonyRawMode
+ if (! vSonyRawMode)
+#endif
+ {
+ ui5r DataOffset0;
+ ui5r DataSize0;
+ ui5r TagOffset0;
+ ui5r TagSize0;
+ ui3b Temp[checkheadersize];
+ ui5r Sony_Count = checkheadersize;
+ blnr gotFormat = falseblnr;
+
+ result = vSonyTransfer(falseblnr, Temp, i,
+ checkheaderoffset, Sony_Count, nullpr);
+ if (mnvm_noErr == result) {
+#if Sony_SupportDC42
+ /* Detect Disk Copy 4.2 image */
+ if (0x0100 == do_get_mem_word(
+ &Temp[kDC42offset_private]))
+ {
+ /* DC42 signature found, check sizes */
+ DataSize0 = do_get_mem_long(
+ &Temp[kDC42offset_dataSize]);
+ TagSize0 = do_get_mem_long(
+ &Temp[kDC42offset_tagSize]);
+ DataOffset0 = kDC42offset_userData;
+ TagOffset0 = DataOffset0 + DataSize0;
+ if (L >= (TagOffset0 + TagSize0))
+ if (0 == (DataSize0 & 0x01FF))
+ if ((DataSize0 >> 9) >= 4)
+ if (Temp[kDC42offset_diskName] < 64)
+ /* length of pascal string */
+ {
+ if (0 == TagSize0) {
+ /* no tags */
+ gotFormat = trueblnr;
+ } else if ((DataSize0 >> 9) * 12
+ == TagSize0)
+ {
+ /* 12 byte tags */
+ gotFormat = trueblnr;
+ }
+ if (gotFormat) {
+#if Sony_VerifyChecksums /* mostly useful to check the Checksum code */
+ ui5r dataChecksum;
+ ui5r tagChecksum;
+ ui5r dataChecksum0 = do_get_mem_long(
+ &Temp[kDC42offset_dataChecksum]);
+ ui5r tagChecksum0 = do_get_mem_long(
+ &Temp[kDC42offset_tagChecksum]);
+ result = DC42BlockChecksum(i,
+ DataOffset0, DataSize0,
+ &dataChecksum);
+ if (TagSize0 >= 12) {
+ result = DC42BlockChecksum(i,
+ TagOffset0 + 12, TagSize0 - 12,
+ &tagChecksum);
+ } else {
+ tagChecksum = 0;
+ }
+ if (dataChecksum != dataChecksum0) {
+ ReportAbnormalID(0x0904,
+ "bad dataChecksum");
+ }
+ if (tagChecksum != tagChecksum0) {
+ ReportAbnormalID(0x0905,
+ "bad tagChecksum");
+ }
+#endif
+ DataOffset = DataOffset0;
+ DataSize = DataSize0;
+#if Sony_SupportTags
+ TagOffset =
+ (0 == TagSize0) ? 0 : TagOffset0;
+#endif
+
+#if (! Sony_SupportTags) || (! Sony_WantChecksumsUpdated)
+ if (! vSonyIsLocked(i)) {
+#if ! Sony_WantChecksumsUpdated
+ /* unconditionally revoke */
+#else
+ if (0 != TagSize0)
+#endif
+ {
+ DiskRevokeWritable(i);
+ }
+ }
+#endif
+ }
+ }
+ }
+#endif /* Sony_SupportDC42 */
+ }
+ }
+ if (mnvm_noErr == result)
+#endif /* Sony_SupportOtherFormats */
+ {
+ vSonyMountedMask |= ((ui5b)1 << i);
+
+ ImageDataOffset[i] = DataOffset;
+ ImageDataSize[i] = DataSize;
+#if Sony_SupportTags
+ ImageTagOffset[i] = TagOffset;
+#endif
+
+ *Drive_No = i;
+ }
+ }
+
+ if (mnvm_noErr != result) {
+ (void) vSonyEject(i);
+ }
+ }
+
+ return result;
+}
+
+#define MinTicksBetweenInsert 240
+ /*
+ if call PostEvent too frequently, insert events seem to get lost
+ */
+
+LOCALVAR ui4r DelayUntilNextInsert;
+
+LOCALVAR CPTR MountCallBack = 0;
+
+/* This checks to see if a disk (image) has been inserted */
+GLOBALPROC Sony_Update (void)
+{
+ if (DelayUntilNextInsert != 0) {
+ --DelayUntilNextInsert;
+ } else {
+ if (MountCallBack != 0) {
+ tDrive i;
+
+ if (mnvm_noErr == vSonyNextPendingInsert(&i)) {
+ ui5b data = i;
+
+ if (vSonyIsLocked(i)) {
+ data |= ((ui5b)0x00FF) << 16;
+ }
+
+ DiskInsertedPsuedoException(MountCallBack, data);
+
+#if IncludeSonyRawMode
+ if (! vSonyRawMode)
+#endif
+ {
+ DelayUntilNextInsert = MinTicksBetweenInsert;
+ /*
+ but usually will reach kDriveStatus first,
+ where shorten delay.
+ */
+ }
+ }
+ }
+ }
+}
+
+LOCALFUNC tMacErr Drive_Transfer(blnr IsWrite, CPTR Buffera,
+ tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
+ ui5r *Sony_ActCount)
+{
+ tMacErr result;
+
+ QuietEnds();
+
+ if (nullpr != Sony_ActCount) {
+ *Sony_ActCount = 0;
+ }
+
+ result = CheckReadableDrive(Drive_No);
+ if (mnvm_noErr == result) {
+ if (IsWrite && vSonyIsLocked(Drive_No)) {
+ result = mnvm_vLckdErr;
+ } else {
+ ui5r DataSize = ImageDataSize[Drive_No];
+ if (Sony_Start > DataSize) {
+ result = mnvm_eofErr;
+ } else {
+ blnr hit_eof = falseblnr;
+ ui5r L = DataSize - Sony_Start;
+ if (L >= Sony_Count) {
+ L = Sony_Count;
+ } else {
+ hit_eof = trueblnr;
+ }
+ result = vSonyTransferVM(IsWrite, Buffera, Drive_No,
+ ImageDataOffset[Drive_No] + Sony_Start, L,
+ Sony_ActCount);
+ if ((mnvm_noErr == result) && hit_eof) {
+ result = mnvm_eofErr;
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+LOCALVAR blnr QuitOnEject = falseblnr;
+
+GLOBALPROC Sony_SetQuitOnEject(void)
+{
+ QuitOnEject = trueblnr;
+}
+
+LOCALFUNC tMacErr Drive_Eject(tDrive Drive_No)
+{
+ tMacErr result;
+
+ result = CheckReadableDrive(Drive_No);
+ if (mnvm_noErr == result) {
+ vSonyMountedMask &= ~ ((ui5b)1 << Drive_No);
+#if Sony_WantChecksumsUpdated
+ Drive_UpdateChecksums(Drive_No);
+#endif
+ result = vSonyEject(Drive_No);
+ if (QuitOnEject != 0) {
+ if (! AnyDiskInserted()) {
+ ForceMacOff = trueblnr;
+ }
+ }
+ }
+
+ return result;
+}
+
+#if IncludeSonyNew
+LOCALFUNC tMacErr Drive_EjectDelete(tDrive Drive_No)
+{
+ tMacErr result;
+
+ result = CheckReadableDrive(Drive_No);
+ if (mnvm_noErr == result) {
+ if (vSonyIsLocked(Drive_No)) {
+ result = mnvm_vLckdErr;
+ } else {
+ vSonyMountedMask &= ~ ((ui5b)1 << Drive_No);
+ result = vSonyEjectDelete(Drive_No);
+ }
+ }
+
+ return result;
+}
+#endif
+
+GLOBALPROC Sony_EjectAllDisks(void)
+{
+ tDrive i;
+
+ vSonyMountedMask = 0;
+ for (i = 0; i < NumDrives; ++i) {
+ if (vSonyIsInserted(i)) {
+#if Sony_WantChecksumsUpdated
+ Drive_UpdateChecksums(i);
+#endif
+ (void) vSonyEject(i);
+ }
+ }
+}
+
+GLOBALPROC Sony_Reset(void)
+{
+ DelayUntilNextInsert = 0;
+ QuitOnEject = falseblnr;
+ MountCallBack = 0;
+}
+
+/*
+ Mini vMac extension for low level access to disk operations.
+*/
+
+#define kCmndDiskNDrives 1
+#define kCmndDiskRead 2
+#define kCmndDiskWrite 3
+#define kCmndDiskEject 4
+#define kCmndDiskGetSize 5
+#define kCmndDiskGetCallBack 6
+#define kCmndDiskSetCallBack 7
+#define kCmndDiskQuitOnEject 8
+#define kCmndDiskFeatures 9
+#define kCmndDiskNextPendingInsert 10
+#if IncludeSonyRawMode
+#define kCmndDiskGetRawMode 11
+#define kCmndDiskSetRawMode 12
+#endif
+#if IncludeSonyNew
+#define kCmndDiskNew 13
+#define kCmndDiskGetNewWanted 14
+#define kCmndDiskEjectDelete 15
+#endif
+#if IncludeSonyGetName
+#define kCmndDiskGetName 16
+#endif
+
+#define kFeatureCmndDisk_RawMode 0
+#define kFeatureCmndDisk_New 1
+#define kFeatureCmndDisk_NewName 2
+#define kFeatureCmndDisk_GetName 3
+
+#define kParamDiskNumDrives 8
+#define kParamDiskStart 8
+#define kParamDiskCount 12
+#define kParamDiskBuffer 16
+#define kParamDiskDrive_No 20
+
+GLOBALPROC ExtnDisk_Access(CPTR p)
+{
+ tMacErr result = mnvm_controlErr;
+
+ switch (get_vm_word(p + ExtnDat_commnd)) {
+ case kCmndVersion:
+ put_vm_word(p + ExtnDat_version, 2);
+ result = mnvm_noErr;
+ break;
+ case kCmndDiskNDrives: /* count drives */
+ put_vm_word(p + kParamDiskNumDrives, NumDrives);
+ result = mnvm_noErr;
+ break;
+ case kCmndDiskRead:
+ {
+ ui5r Sony_ActCount;
+ CPTR Buffera = get_vm_long(p + kParamDiskBuffer);
+ tDrive Drive_No = get_vm_word(p + kParamDiskDrive_No);
+ ui5r Sony_Start = get_vm_long(p + kParamDiskStart);
+ ui5r Sony_Count = get_vm_long(p + kParamDiskCount);
+
+ result = Drive_Transfer(falseblnr, Buffera, Drive_No,
+ Sony_Start, Sony_Count, &Sony_ActCount);
+
+ put_vm_long(p + kParamDiskCount, Sony_ActCount);
+ }
+ break;
+ case kCmndDiskWrite:
+ {
+ ui5r Sony_ActCount;
+ CPTR Buffera = get_vm_long(p + kParamDiskBuffer);
+ tDrive Drive_No = get_vm_word(p + kParamDiskDrive_No);
+ ui5r Sony_Start = get_vm_long(p + kParamDiskStart);
+ ui5r Sony_Count = get_vm_long(p + kParamDiskCount);
+
+ result = Drive_Transfer(trueblnr, Buffera, Drive_No,
+ Sony_Start, Sony_Count, &Sony_ActCount);
+
+ put_vm_long(p + kParamDiskCount, Sony_ActCount);
+ }
+ break;
+ case kCmndDiskEject:
+ {
+ tDrive Drive_No = get_vm_word(p + kParamDiskDrive_No);
+ result = Drive_Eject(Drive_No);
+ }
+ break;
+ case kCmndDiskGetSize:
+ {
+ tDrive Drive_No = get_vm_word(p + kParamDiskDrive_No);
+
+ result = CheckReadableDrive(Drive_No);
+ if (mnvm_noErr == result) {
+ put_vm_long(p + kParamDiskCount,
+ ImageDataSize[Drive_No]);
+ result = mnvm_noErr;
+ }
+ }
+ break;
+ case kCmndDiskGetCallBack:
+ put_vm_long(p + kParamDiskBuffer, MountCallBack);
+ result = mnvm_noErr;
+ break;
+ case kCmndDiskSetCallBack:
+ MountCallBack = get_vm_long(p + kParamDiskBuffer);
+ result = mnvm_noErr;
+ break;
+ case kCmndDiskQuitOnEject:
+ QuitOnEject = trueblnr;
+ result = mnvm_noErr;
+ break;
+ case kCmndDiskFeatures:
+ {
+ ui5r v = (0
+#if IncludeSonyRawMode
+ | ((ui5b)1 << kFeatureCmndDisk_RawMode)
+#endif
+#if IncludeSonyNew
+ | ((ui5b)1 << kFeatureCmndDisk_New)
+#endif
+#if IncludeSonyNameNew
+ | ((ui5b)1 << kFeatureCmndDisk_NewName)
+#endif
+#if IncludeSonyGetName
+ | ((ui5b)1 << kFeatureCmndDisk_GetName)
+#endif
+ );
+
+ put_vm_long(p + ExtnDat_params + 0, v);
+ result = mnvm_noErr;
+ }
+ break;
+ case kCmndDiskNextPendingInsert:
+ {
+ tDrive i;
+
+ result = vSonyNextPendingInsert(&i);
+ if (mnvm_noErr == result) {
+ put_vm_word(p + kParamDiskDrive_No, i);
+ }
+ }
+ break;
+#if IncludeSonyRawMode
+ case kCmndDiskGetRawMode:
+ put_vm_word(p + kParamDiskBuffer, vSonyRawMode);
+ result = mnvm_noErr;
+ break;
+ case kCmndDiskSetRawMode:
+ vSonyRawMode = get_vm_word(p + kParamDiskBuffer);
+ result = mnvm_noErr;
+ break;
+#endif
+#if IncludeSonyNew
+ case kCmndDiskNew:
+ {
+ ui5b count = get_vm_long(p + ExtnDat_params + 0);
+ tPbuf Pbuf_No = get_vm_word(p + ExtnDat_params + 4);
+ /* reserved word at offset 6, should be zero */
+
+ result = mnvm_noErr;
+
+#if IncludePbufs
+ if (Pbuf_No != NotAPbuf) {
+ result = CheckPbuf(Pbuf_No);
+ if (mnvm_noErr == result) {
+ vSonyNewDiskWanted = trueblnr;
+ vSonyNewDiskSize = count;
+#if IncludeSonyNameNew
+ if (vSonyNewDiskName != NotAPbuf) {
+ PbufDispose(vSonyNewDiskName);
+ }
+ vSonyNewDiskName = Pbuf_No;
+#else
+ PbufDispose(Pbuf_No);
+#endif
+ }
+ } else
+#endif
+ {
+ vSonyNewDiskWanted = trueblnr;
+ vSonyNewDiskSize = count;
+ }
+ }
+ break;
+ case kCmndDiskGetNewWanted:
+ put_vm_word(p + kParamDiskBuffer, vSonyNewDiskWanted);
+ result = mnvm_noErr;
+ break;
+ case kCmndDiskEjectDelete:
+ {
+ tDrive Drive_No = get_vm_word(p + kParamDiskDrive_No);
+ result = Drive_EjectDelete(Drive_No);
+ }
+ break;
+#endif
+#if IncludeSonyGetName
+ case kCmndDiskGetName:
+ {
+ tDrive Drive_No = get_vm_word(p + ExtnDat_params + 0);
+ /* reserved word at offset 2, should be zero */
+ result = CheckReadableDrive(Drive_No);
+ if (mnvm_noErr == result) {
+ tPbuf Pbuf_No;
+ result = vSonyGetName(Drive_No, &Pbuf_No);
+ put_vm_word(p + ExtnDat_params + 4, Pbuf_No);
+ }
+ }
+ break;
+#endif
+ }
+
+ put_vm_word(p + ExtnDat_result, result);
+}
+
+
+/*
+ Mini vMac extension that implements most of the logic
+ of the replacement disk driver patched into the emulated ROM.
+ (sony_driver in ROMEMDEV.c)
+
+ This logic used to be completely contained in the 68k code
+ of the replacement driver, using only the low level
+ disk access extension.
+*/
+
+/* Sony Variable Drive Setting Offsets */
+
+#define kTrack 0 /* Current Track */
+#define kWriteProt 2 /* FF if Write Protected, 00 if readable */
+#define kDiskInPlace 3
+ /*
+ 00 = No Disk, 01 = Disk In,
+ 2 = MacOS Read, FC-FF = Just Ejected
+ */
+#define kInstalled 4
+ /* 00 = Unknown, 01 = Installed, FF = Not Installed */
+#define kSides 5
+ /* 00 if Single Sided Drive, FF if Doubled Sided Drive */
+#define kQLink 6 /* Link to Next Drive */
+#define kQType 10 /* Drive Type (0 = Size Saved, 1 = Very Large) */
+#define kQDriveNo 12 /* Drive Number (1 = Internal, 2 = External) */
+#define kQRefNum 14
+ /* Driver Reference Number (-5 for .Sony, FFFB) */
+#define kQFSID 16 /* File System ID (0 = MacOS) */
+#define kQDrvSz 18 /* size, low-order word */
+#define kQDrvSz2 20 /* size, hi-order word */
+
+#define kTwoSideFmt 18
+ /* FF if double-sided format, 00 if single-sided format */
+#define kNewIntf 19
+ /* FF if new 800K interface or 00 if old 400K interface */
+#define kDriveErrs 20 /* Drive Soft Errors */
+
+/* Sony Driver Control Call csCodes */
+
+#define kKillIO 1
+#define kVerifyDisk 5
+#define kFormatDisk 6
+#define kEjectDisk 7
+#define kSetTagBuffer 8
+#define kTrackCacheControl 9
+#define kGetIconID 20
+#define kDriveIcon 21
+#define kMediaIcon 22
+#define kDriveInfo 23
+#define kFormatCopy 21315
+
+/* Sony Driver Status Call csCodes */
+
+#define kReturnFormatList 6
+#define kDriveStatus 8
+#define kMFMStatus 10
+#define kDuplicatorVersionSupport 17494
+
+/* Parameter Block Offsets */
+
+#define kqLink 0
+#define kqType 4
+#define kioTrap 6
+#define kioCmdAddr 8
+#define kioCompletion 12
+#define kioResult 16
+#define kioNamePtr 18
+#define kioVRefNum 22
+#define kioRefNum 24
+#define kcsCode 26
+#define kcsParam 28
+#define kioBuffer 32 /* Buffer to store data into */
+#define kioReqCount 36 /* Requested Number of Bytes */
+#define kioActCount 40 /* Actual Number of Bytes obtained */
+#define kioPosMode 44 /* Positioning Mode */
+#define kioPosOffset 46 /* Position Offset */
+
+/* Positioning Modes */
+
+#define kfsAtMark 0 /* At Mark (Ignore PosOffset) */
+#define kfsFromStart 1 /* At Start (PosOffset is absolute) */
+#define kfsFromLEOF 2 /* From Logical End of File - PosOffset */
+#define kfsFromMark 3 /* At Mark + PosOffset */
+
+/* Device Control Entry Offsets */
+
+#define kdCtlPosition 16
+
+#if 0
+struct MyDriverDat_R {
+ ui5b zeroes[4]; /* 0 */
+ ui5b checkval; /* 16 */
+ ui5b pokeaddr; /* 20 */
+ ui4b NumDrives; /* 24 */
+ ui4b DiskExtn; /* 26 */
+ TMTask NullTask; /* 28 */
+ /* total size must be <= FirstDriveVarsOffset */
+};
+
+typedef struct MyDriverDat_R MyDriverDat_R;
+#endif
+
+
+#if CurEmMd <= kEmMd_Twiggy
+
+#define SonyVarsPtr 0x0128 /* TwiggyVars, actually */
+
+#if CurEmMd <= kEmMd_Twig43
+#define MinSonVarsSize 0x000000FA
+#define FirstDriveVarsOffset 0x004A
+#define EachDriveVarsSize 0x0042
+#else
+#define MinSonVarsSize 0x000000E6
+#define FirstDriveVarsOffset 0x004C
+#define EachDriveVarsSize 0x002E
+#endif
+
+#else
+
+#define SonyVarsPtr 0x0134
+
+#define FirstDriveVarsOffset 0x004A
+#define EachDriveVarsSize 0x0042
+#if CurEmMd <= kEmMd_128K
+#define MinSonVarsSize 0x000000FA
+#else
+#define MinSonVarsSize 0x00000310
+#endif
+
+#endif
+
+#define kcom_checkval 0x841339E2
+
+#define Sony_dolog (dbglog_HAVE && 0)
+
+#if Sony_SupportTags
+LOCALVAR CPTR TheTagBuffer;
+#endif
+
+LOCALFUNC ui5b DriveVarsLocation(tDrive Drive_No)
+{
+ CPTR SonyVars = get_vm_long(SonyVarsPtr);
+
+ if (Drive_No < NumDrives) {
+ return SonyVars + FirstDriveVarsOffset
+ + EachDriveVarsSize * Drive_No;
+ } else {
+ return 0;
+ }
+}
+
+LOCALFUNC tMacErr Sony_Mount(CPTR p)
+{
+ ui5b data = get_vm_long(p + ExtnDat_params + 0);
+ tMacErr result = mnvm_miscErr;
+ tDrive i = data & 0x0000FFFF;
+ CPTR dvl = DriveVarsLocation(i);
+
+ if (0 == dvl) {
+#if Sony_dolog
+ dbglog_WriteNote("Sony : Mount : no dvl");
+#endif
+
+ result = mnvm_nsDrvErr;
+ } else if (get_vm_byte(dvl + kDiskInPlace) == 0x00) {
+ ui5b L = ImageDataSize[i] >> 9; /* block count */
+
+#if Sony_dolog
+ dbglog_StartLine();
+ dbglog_writeCStr("Sony : Mount : Drive=");
+ dbglog_writeHex(i);
+ dbglog_writeCStr(", L=");
+ dbglog_writeHex(L);
+ dbglog_writeReturn();
+#endif
+
+#if CurEmMd <= kEmMd_Twiggy
+ if (L == 1702) {
+ put_vm_byte(dvl + kTwoSideFmt, 0xFF);
+ /* Drive i Single Format */
+ put_vm_byte(dvl + kNewIntf, 0x00);
+ /* Drive i doesn't use new interface */
+ put_vm_word(dvl + kQType, 0x00); /* Drive Type */
+ put_vm_word(dvl + kDriveErrs, 0x0000);
+ /* Drive i has no errors */
+ } else
+#else
+ if ((L == 800)
+#if CurEmMd > kEmMd_128K
+ || (L == 1600)
+#endif
+ )
+ {
+#if CurEmMd <= kEmMd_128K
+ put_vm_byte(dvl + kTwoSideFmt, 0x00);
+ /* Drive i Single Format */
+ put_vm_byte(dvl + kNewIntf, 0x00);
+ /* Drive i doesn't use new interface */
+#else
+ if (L == 800) {
+ put_vm_byte(dvl + kTwoSideFmt, 0x00);
+ /* Drive i Single Format */
+ } else {
+ put_vm_byte(dvl + kTwoSideFmt, 0xFF);
+ /* Drive Double Format */
+ }
+ put_vm_byte(dvl + kNewIntf, 0xFF);
+ /* Drive i uses new interface */
+#endif
+ put_vm_word(dvl + kQType, 0x00); /* Drive Type */
+ put_vm_word(dvl + kDriveErrs, 0x0000);
+ /* Drive i has no errors */
+ } else
+#endif
+ {
+ put_vm_word(dvl + kQRefNum, 0xFFFE); /* Driver */
+ put_vm_word(dvl + kQType, 0x01); /* Drive Type */
+ put_vm_word(dvl + kQDrvSz , L);
+ put_vm_word(dvl + kQDrvSz2, L >> 16);
+ }
+
+#if CurEmMd <= kEmMd_Twiggy
+ put_vm_word(dvl + kQFSID, 0x00); /* kQFSID must be 0 for 4.3T */
+#endif
+
+ put_vm_byte(dvl + kWriteProt, data >> 16);
+ put_vm_byte(dvl + kDiskInPlace, 0x01); /* Drive Disk Inserted */
+
+ put_vm_long(p + ExtnDat_params + 4, i + 1);
+ /* PostEvent Disk Inserted eventMsg */
+ result = mnvm_noErr;
+ } else {
+ /* disk already in place, a mistake has been made */
+#if Sony_dolog
+ dbglog_WriteNote("Sony : Mount : already in place");
+#endif
+ }
+
+ return result;
+}
+
+#if Sony_SupportTags
+LOCALFUNC tMacErr Sony_PrimeTags(tDrive Drive_No,
+ ui5r Sony_Start, ui5r Sony_Count, blnr IsWrite)
+{
+ tMacErr result = mnvm_noErr;
+ ui5r TagOffset = ImageTagOffset[Drive_No];
+
+ if ((0 != TagOffset) && (Sony_Count > 0)) {
+ ui5r block = Sony_Start >> 9;
+ ui5r n = Sony_Count >> 9; /* is >= 1 if get here */
+
+ TagOffset += block * 12;
+
+ if (0 != TheTagBuffer) {
+ ui5r count = 12 * n;
+ result = vSonyTransferVM(IsWrite, TheTagBuffer, Drive_No,
+ TagOffset, count, nullpr);
+ if (mnvm_noErr == result) {
+ MyMoveBytesVM(TheTagBuffer + count - 12, 0x02FC, 12);
+ }
+ } else {
+ if (! IsWrite) {
+ /* only need to read the last block tags */
+ ui5r count = 12;
+ TagOffset += 12 * (n - 1);
+ result = vSonyTransferVM(falseblnr, 0x02FC, Drive_No,
+ TagOffset, count, nullpr);
+ } else {
+ ui5r count = 12;
+ ui4r BufTgFBkNum = get_vm_word(0x0302);
+ do {
+ put_vm_word(0x0302, BufTgFBkNum);
+ result = vSonyTransferVM(trueblnr, 0x02FC, Drive_No,
+ TagOffset, count, nullpr);
+ if (mnvm_noErr != result) {
+ goto label_fail;
+ }
+ BufTgFBkNum += 1;
+ TagOffset += 12;
+ } while (--n != 0);
+ }
+ }
+ }
+
+label_fail:
+ return result;
+}
+#endif
+
+/* Handles I/O to disks */
+LOCALFUNC tMacErr Sony_Prime(CPTR p)
+{
+ tMacErr result;
+ ui5r Sony_Count;
+ ui5r Sony_Start;
+ ui5r Sony_ActCount = 0;
+ CPTR ParamBlk = get_vm_long(p + ExtnDat_params + 0);
+ CPTR DeviceCtl = get_vm_long(p + ExtnDat_params + 4);
+ tDrive Drive_No = get_vm_word(ParamBlk + kioVRefNum) - 1;
+ ui4r IOTrap = get_vm_word(ParamBlk + kioTrap);
+ CPTR dvl = DriveVarsLocation(Drive_No);
+
+ if (0 == dvl) {
+#if Sony_dolog
+ dbglog_WriteNote("Sony : Prime : no dvl");
+#endif
+
+ result = mnvm_nsDrvErr;
+ } else
+#if CurEmMd >= kEmMd_Twiggy
+ if (0xA002 != (IOTrap & 0xF0FE)) {
+#if Sony_dolog
+ dbglog_WriteNote("Sony : Prime : "
+ "not read (0xA002) or write (0xA003)");
+#endif
+
+ result = mnvm_controlErr;
+ } else
+#endif
+ {
+ blnr IsWrite = (0 != (IOTrap & 0x0001));
+ ui3b DiskInPlaceV = get_vm_byte(dvl + kDiskInPlace);
+
+ if (DiskInPlaceV != 0x02) {
+ if (DiskInPlaceV == 0x01) {
+ put_vm_byte(dvl + kDiskInPlace, 0x02); /* Clamp Drive */
+ } else {
+ result = mnvm_offLinErr;
+ goto label_fail;
+ /*
+ if don't check for this, will go right
+ ahead and boot off a disk that hasn't
+ been mounted yet by Sony_Update.
+ (disks other than the boot disk aren't
+ seen unless mounted by Sony_Update)
+ */
+ }
+ }
+
+#if 0
+ ui4r PosMode = get_vm_word(ParamBlk + kioPosMode);
+
+ if (0 != (PosMode & 64)) {
+#if ExtraAbnormalReports
+ /*
+ This is used when copy to floppy
+ disk with Finder. But not implemented
+ yet.
+ */
+ ReportAbnormalID(0x0906, "read verify mode requested");
+#endif
+ PosMode &= ~ 64;
+ }
+
+ /*
+ Don't use the following code, because
+ according to Apple's Technical Note FL24
+ the Device Manager takes care of this,
+ and puts the result in dCtlPosition.
+ (The RAMDisk example in Apple's sample
+ code serves to confirm this. Further
+ evidence found in Basilisk II emulator,
+ and disassembly of Mac Plus disk driver.)
+ */
+ ui5r PosOffset = get_vm_long(ParamBlk + kioPosOffset);
+ switch (PosMode) {
+ case kfsAtMark:
+ Sony_Start = get_vm_long(DeviceCtl + kdCtlPosition);
+ break;
+ case kfsFromStart:
+ Sony_Start = PosOffset;
+ break;
+#if 0
+ /*
+ not valid for device driver.
+ actually only kfsFromStart seems to be used.
+ */
+ case kfsFromLEOF:
+ Sony_Start = ImageDataSize[Drive_No]
+ + PosOffset;
+ break;
+#endif
+ case kfsFromMark:
+ Sony_Start = PosOffset
+ + get_vm_long(DeviceCtl + kdCtlPosition);
+ break;
+ default:
+ ReportAbnormalID(0x0907, "unknown PosMode");
+ result = mnvm_paramErr;
+ goto label_fail;
+ break;
+ }
+#endif
+ Sony_Start = get_vm_long(DeviceCtl + kdCtlPosition);
+
+ Sony_Count = get_vm_long(ParamBlk + kioReqCount);
+
+#if Sony_dolog
+ dbglog_StartLine();
+ dbglog_writeCStr("Sony : Prime : Drive=");
+ dbglog_writeHex(Drive_No);
+ dbglog_writeCStr(", IsWrite=");
+ dbglog_writeHex(IsWrite);
+ dbglog_writeCStr(", Start=");
+ dbglog_writeHex(Sony_Start);
+ dbglog_writeCStr(", Count=");
+ dbglog_writeHex(Sony_Count);
+ dbglog_writeReturn();
+#endif
+
+ if ((0 != (Sony_Start & 0x1FF))
+ || (0 != (Sony_Count & 0x1FF)))
+ {
+ /* only whole blocks allowed */
+#if ExtraAbnormalReports
+ ReportAbnormalID(0x0908, "not blockwise in Sony_Prime");
+#endif
+ result = mnvm_paramErr;
+ } else if (IsWrite && (get_vm_byte(dvl + kWriteProt) != 0)) {
+ result = mnvm_wPrErr;
+ } else {
+ CPTR Buffera = get_vm_long(ParamBlk + kioBuffer);
+ result = Drive_Transfer(IsWrite, Buffera, Drive_No,
+ Sony_Start, Sony_Count, &Sony_ActCount);
+#if Sony_SupportTags
+ if (mnvm_noErr == result) {
+ result = Sony_PrimeTags(Drive_No,
+ Sony_Start, Sony_Count, IsWrite);
+ }
+#endif
+ put_vm_long(DeviceCtl + kdCtlPosition,
+ Sony_Start + Sony_ActCount);
+ }
+ }
+
+label_fail:
+ put_vm_word(ParamBlk + kioResult, result);
+ put_vm_long(ParamBlk + kioActCount, Sony_ActCount);
+
+ if (mnvm_noErr != result) {
+ put_vm_word(0x0142 /* DskErr */, result);
+ }
+ return result;
+}
+
+/* Implements control csCodes for the Sony driver */
+LOCALFUNC tMacErr Sony_Control(CPTR p)
+{
+ tMacErr result;
+ CPTR ParamBlk = get_vm_long(p + ExtnDat_params + 0);
+ /* CPTR DeviceCtl = get_vm_long(p + ExtnDat_params + 4); */
+ ui4r OpCode = get_vm_word(ParamBlk + kcsCode);
+
+ if (kKillIO == OpCode) {
+#if Sony_dolog
+ dbglog_WriteNote("Sony : Control : kKillIO");
+#endif
+
+ result = mnvm_miscErr;
+ } else if (kSetTagBuffer == OpCode) {
+#if Sony_dolog
+ dbglog_WriteNote("Sony : Control : kSetTagBuffer");
+#endif
+
+#if Sony_SupportTags
+ TheTagBuffer = get_vm_long(ParamBlk + kcsParam);
+ result = mnvm_noErr;
+#else
+ result = mnvm_controlErr;
+#endif
+ } else if (kTrackCacheControl == OpCode) {
+#if Sony_dolog
+ dbglog_WriteNote("Sony : Control : kTrackCacheControl");
+#endif
+
+#if CurEmMd <= kEmMd_128K
+ result = mnvm_controlErr;
+#else
+#if 0
+ ui3r Arg1 = get_vm_byte(ParamBlk + kcsParam);
+ ui3r Arg2 = get_vm_byte(ParamBlk + kcsParam + 1);
+ if (0 == Arg1) {
+ /* disable track cache */
+ } else {
+ /* enable track cache */
+ }
+ if (Arg2 < 0) {
+ /* remove track cache */
+ } else if (Arg2 > 0) {
+ /* install track cache */
+ }
+#endif
+ result = mnvm_noErr;
+ /* not implemented, but pretend we did it */
+#endif
+ } else {
+ tDrive Drive_No = get_vm_word(ParamBlk + kioVRefNum) - 1;
+ CPTR dvl = DriveVarsLocation(Drive_No);
+
+ if (0 == dvl) {
+#if Sony_dolog
+ dbglog_WriteNote("Sony : Control : no dvl");
+#endif
+
+ result = mnvm_nsDrvErr;
+ } else if (get_vm_byte(dvl + kDiskInPlace) == 0) {
+#if Sony_dolog
+ dbglog_WriteNote("Sony : Control : not DiskInPlace");
+#endif
+
+ result = mnvm_offLinErr;
+ } else {
+ switch (OpCode) {
+ case kVerifyDisk :
+#if Sony_dolog
+ dbglog_WriteNote("Sony : Control : kVerifyDisk");
+#endif
+
+ result = mnvm_noErr;
+ break;
+ case kEjectDisk :
+#if Sony_dolog
+ dbglog_StartLine();
+ dbglog_writeCStr("Sony : Control : kEjectDisk : ");
+ dbglog_writeHex(Drive_No);
+ dbglog_writeReturn();
+#endif
+
+ put_vm_byte(dvl + kWriteProt, 0x00);
+ /* Drive Writeable */
+ put_vm_byte(dvl + kDiskInPlace, 0x00);
+ /* Drive No Disk */
+#if 0
+ put_vm_byte(dvl + kTwoSideFmt, 0x00);
+ /* Drive Single Format (Initially) */
+#endif
+ put_vm_word(dvl + kQRefNum, 0xFFFB);
+ /* Drive i uses .Sony */
+
+ result = Drive_Eject(Drive_No);
+ break;
+ case kFormatDisk :
+#if Sony_dolog
+ dbglog_StartLine();
+ dbglog_writeCStr("Sony : Control : kFormatDisk : ");
+ dbglog_writeHex(Drive_No);
+ dbglog_writeReturn();
+#endif
+
+ result = mnvm_noErr;
+ break;
+ case kDriveIcon :
+#if Sony_dolog
+ dbglog_StartLine();
+ dbglog_writeCStr("Sony : Control : kDriveIcon : ");
+ dbglog_writeHex(Drive_No);
+ dbglog_writeReturn();
+#endif
+
+ if (get_vm_word(dvl + kQType) != 0) {
+ put_vm_long(ParamBlk + kcsParam,
+ my_disk_icon_addr);
+ result = mnvm_noErr;
+ } else {
+ result = mnvm_controlErr;
+ /*
+ Driver can't respond to
+ this Control call (-17)
+ */
+ }
+ break;
+#if CurEmMd >= kEmMd_SE
+ case kDriveInfo :
+ {
+ ui5b v;
+
+#if Sony_dolog
+ dbglog_StartLine();
+ dbglog_writeCStr(
+ "Sony : Control : kDriveInfo : ");
+ dbglog_writeHex(kDriveIcon);
+ dbglog_writeReturn();
+#endif
+
+ if (get_vm_word(dvl + kQType) != 0) {
+ v = 0x00000001; /* unspecified drive */
+ } else {
+#if CurEmMd <= kEmMd_128K
+ v = 0x00000002; /* 400K Drive */
+#else
+ v = 0x00000003; /* 800K Drive */
+#endif
+ }
+ if (Drive_No != 0) {
+ v += 0x00000900;
+ /* Secondary External Drive */
+ }
+ put_vm_long(ParamBlk + kcsParam, v);
+ result = mnvm_noErr; /* No error (0) */
+ }
+ break;
+#endif
+ default :
+#if Sony_dolog
+ dbglog_StartLine();
+ dbglog_writeCStr("Sony : Control : OpCode : ");
+ dbglog_writeHex(OpCode);
+ dbglog_writeReturn();
+#endif
+#if ExtraAbnormalReports
+ if ((kGetIconID != OpCode)
+ && (kMediaIcon != OpCode)
+ && (kDriveInfo != OpCode))
+ {
+ ReportAbnormalID(0x0909,
+ "unexpected OpCode in Sony_Control");
+ }
+#endif
+ result = mnvm_controlErr;
+ /*
+ Driver can't respond to
+ this Control call (-17)
+ */
+ break;
+ }
+ }
+ }
+
+ if (mnvm_noErr != result) {
+ put_vm_word(0x0142 /* DskErr */, result);
+ }
+ return result;
+}
+
+/* Handles the DriveStatus call */
+LOCALFUNC tMacErr Sony_Status(CPTR p)
+{
+ tMacErr result;
+ CPTR ParamBlk = get_vm_long(p + ExtnDat_params + 0);
+ /* CPTR DeviceCtl = get_vm_long(p + ExtnDat_params + 4); */
+ ui4r OpCode = get_vm_word(ParamBlk + kcsCode);
+
+#if Sony_dolog
+ dbglog_StartLine();
+ dbglog_writeCStr("Sony : Sony_Status OpCode = ");
+ dbglog_writeHex(OpCode);
+ dbglog_writeReturn();
+#endif
+
+ if (kDriveStatus == OpCode) {
+ tDrive Drive_No = get_vm_word(ParamBlk + kioVRefNum) - 1;
+ CPTR Src = DriveVarsLocation(Drive_No);
+ if (Src == 0) {
+ result = mnvm_nsDrvErr;
+ } else {
+ if (DelayUntilNextInsert > 4) {
+ DelayUntilNextInsert = 4;
+ }
+ MyMoveBytesVM(Src, ParamBlk + kcsParam, 22);
+ result = mnvm_noErr;
+ }
+ } else {
+#if ExtraAbnormalReports
+ if ((kReturnFormatList != OpCode)
+ && (kDuplicatorVersionSupport != OpCode))
+ {
+ ReportAbnormalID(0x090A,
+ "unexpected OpCode in Sony_Control");
+ }
+#endif
+ result = mnvm_statusErr;
+ }
+
+ if (mnvm_noErr != result) {
+ put_vm_word(0x0142 /* DskErr */, result);
+ }
+ return result;
+}
+
+LOCALFUNC tMacErr Sony_Close(CPTR p)
+{
+#if 0
+ CPTR ParamBlk = get_vm_long(p + ExtnDat_params + 0);
+ CPTR DeviceCtl = get_vm_long(p + ExtnDat_params + 4);
+#endif
+ UnusedParam(p);
+ return mnvm_closErr; /* Can't Close Driver */
+}
+
+LOCALFUNC tMacErr Sony_OpenA(CPTR p)
+{
+#if Sony_dolog
+ dbglog_WriteNote("Sony : OpenA");
+#endif
+
+ if (MountCallBack != 0) {
+ return mnvm_opWrErr; /* driver already open */
+ } else {
+ ui5b L = FirstDriveVarsOffset + EachDriveVarsSize * NumDrives;
+
+ if (L < MinSonVarsSize) {
+ L = MinSonVarsSize;
+ }
+
+ put_vm_long(p + ExtnDat_params + 0, L);
+
+ return mnvm_noErr;
+ }
+}
+
+LOCALFUNC tMacErr Sony_OpenB(CPTR p)
+{
+ si4b i;
+ CPTR dvl;
+
+#if Sony_dolog
+ dbglog_WriteNote("Sony : OpenB");
+#endif
+
+ CPTR SonyVars = get_vm_long(p + ExtnDat_params + 4);
+ /* CPTR ParamBlk = get_vm_long(p + ExtnDat_params + 24); (unused) */
+#if CurEmMd > kEmMd_128K
+ CPTR DeviceCtl = get_vm_long(p + ExtnDat_params + 28);
+#endif
+
+ put_vm_long(SonyVars + 16 /* checkval */, kcom_checkval);
+ put_vm_long(SonyVars + 20 /* pokeaddr */, kExtn_Block_Base);
+ put_vm_word(SonyVars + 24 /* NumDrives */, NumDrives);
+ put_vm_word(SonyVars + 26 /* DiskExtn */, kExtnDisk);
+
+ put_vm_long(SonyVarsPtr, SonyVars);
+
+ for (i = 0; (dvl = DriveVarsLocation(i)) != 0; ++i) {
+ put_vm_byte(dvl + kDiskInPlace, 0x00); /* Drive i No Disk */
+ put_vm_byte(dvl + kInstalled, 0x01); /* Drive i Installed */
+#if CurEmMd <= kEmMd_128K
+ put_vm_byte(dvl + kSides, 0x00);
+ /* Drive i Single Sided */
+#else
+ put_vm_byte(dvl + kSides, 0xFF);
+ /* Drive i Double Sided */
+#endif
+ put_vm_word(dvl + kQDriveNo, i + 1); /* Drive i is Drive 1 */
+ put_vm_word(dvl + kQRefNum, 0xFFFB); /* Drive i uses .Sony */
+ }
+
+ {
+ CPTR UTableBase = get_vm_long(0x011C);
+
+ put_vm_long(UTableBase + 4 * 1,
+ get_vm_long(UTableBase + 4 * 4));
+ /* use same drive for hard disk as used for sony floppies */
+ }
+
+#if CurEmMd > kEmMd_128K
+ /* driver version in driver i/o queue header */
+ put_vm_byte(DeviceCtl + 7, 1);
+#endif
+
+#if CurEmMd <= kEmMd_128K
+ /* init Drive Queue */
+ put_vm_word(0x308, 0);
+ put_vm_long(0x308 + 2, 0);
+ put_vm_long(0x308 + 6, 0);
+#endif
+
+ put_vm_long(p + ExtnDat_params + 8,
+ SonyVars + FirstDriveVarsOffset + kQLink);
+ put_vm_word(p + ExtnDat_params + 12, EachDriveVarsSize);
+ put_vm_word(p + ExtnDat_params + 14, NumDrives);
+ put_vm_word(p + ExtnDat_params + 16, 1);
+ put_vm_word(p + ExtnDat_params + 18, 0xFFFB);
+#if CurEmMd <= kEmMd_128K
+ put_vm_long(p + ExtnDat_params + 20, 0);
+#else
+ put_vm_long(p + ExtnDat_params + 20, SonyVars + 28 /* NullTask */);
+#endif
+
+#if Sony_SupportTags
+ TheTagBuffer = 0;
+#endif
+
+ return mnvm_noErr;
+}
+
+LOCALFUNC tMacErr Sony_OpenC(CPTR p)
+{
+#if Sony_dolog
+ dbglog_WriteNote("Sony : OpenC");
+#endif
+
+ MountCallBack = get_vm_long(p + ExtnDat_params + 0)
+#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
+ | 0x40000000
+#endif
+ ;
+ return mnvm_noErr;
+}
+
+#define kCmndSonyPrime 1
+#define kCmndSonyControl 2
+#define kCmndSonyStatus 3
+#define kCmndSonyClose 4
+#define kCmndSonyOpenA 5
+#define kCmndSonyOpenB 6
+#define kCmndSonyOpenC 7
+#define kCmndSonyMount 8
+
+GLOBALPROC ExtnSony_Access(CPTR p)
+{
+ tMacErr result;
+
+ switch (get_vm_word(p + ExtnDat_commnd)) {
+ case kCmndVersion:
+ put_vm_word(p + ExtnDat_version, 0);
+ result = mnvm_noErr;
+ break;
+ case kCmndSonyPrime:
+ result = Sony_Prime(p);
+ break;
+ case kCmndSonyControl:
+ result = Sony_Control(p);
+ break;
+ case kCmndSonyStatus:
+ result = Sony_Status(p);
+ break;
+ case kCmndSonyClose:
+ result = Sony_Close(p);
+ break;
+ case kCmndSonyOpenA:
+ result = Sony_OpenA(p);
+ break;
+ case kCmndSonyOpenB:
+ result = Sony_OpenB(p);
+ break;
+ case kCmndSonyOpenC:
+ result = Sony_OpenC(p);
+ break;
+ case kCmndSonyMount:
+ result = Sony_Mount(p);
+ break;
+ default:
+ result = mnvm_controlErr;
+ break;
+ }
+
+ put_vm_word(p + ExtnDat_result, result);
+}
--- /dev/null
+++ b/src/SONYEMDV.h
@@ -1,0 +1,31 @@
+/*
+ SONYEMDV.h
+
+ Copyright (C) 2004 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef SONYEMDV_H
+#error "header already included"
+#else
+#define SONYEMDV_H
+#endif
+
+EXPORTPROC ExtnDisk_Access(CPTR p);
+EXPORTPROC ExtnSony_Access(CPTR p);
+
+EXPORTPROC Sony_SetQuitOnEject(void);
+
+EXPORTPROC Sony_EjectAllDisks(void);
+EXPORTPROC Sony_Reset(void);
+
+EXPORTPROC Sony_Update(void);
--- /dev/null
+++ b/src/STRCNCAT.h
@@ -1,0 +1,167 @@
+/*
+ STRCNCAT.h
+
+ Copyright (C) 2017 ArduinoXino, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file;ls see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY;ls without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ STRing CoNstants for CATalan
+
+ These strings were translated by ArduinoXino.
+*/
+
+#define kStrAboutTitle "Sobre"
+#define kStrAboutMessage "Per mostrar informaci;eo sobre aquest programa, utilitzeu el comandament ;]A;} del ^p Mode Control. Per coneixer m;ees sobre el Mode Control, vegi ;[M;ees Comandaments;ll;{ en el menu ;[Especial;{ ."
+
+#define kStrMoreCommandsTitle "M;ees comandaments est;`an disponibles en el mode de control de ^p ."
+#define kStrMoreCommandsMessage "Per entrar en el mode de control, mantingueu premut la tecla ;]^c;} . Seguir;`a en el mode control fins que deixeu anar la tecla ;]^c;} . Polsi ;]H;} en el mode control per llistar els comandaments disponibles."
+
+#define kStrTooManyImagesTitle "Massa imatges de disc"
+#define kStrTooManyImagesMessage "No es poden muntar tantes imatges de disc. Proveu treure alguna."
+
+#define kStrImageInUseTitle "Imatge de disc en ;eus"
+#define kStrImageInUseMessage "No es pot muntar la imatge disc perqu;`e ja est;`a en ;eus per una altra aplicaci;eo, o ja est;`a oberta a ^p."
+
+#define kStrOutOfMemTitle "Mem;`oria insuficient"
+#define kStrOutOfMemMessage "No hi ha prou mem;`oria disponible per a llan;car ^p."
+
+#define kStrNoROMTitle "Impossible localitzar la imatge ROM"
+#define kStrNoROMMessage "No es troba la imatge del fitxer ROM ;[^r;{. Per a m;ees informaci;eo, veure: ;[^w;{."
+
+#define kStrCorruptedROMTitle "El control checksum de la ROM ha fracassat"
+#define kStrCorruptedROMMessage "El fitxer d;laimatge ROM ;[^r;{ pot estar corromput."
+
+#define kStrUnsupportedROMTitle "ROM no suportada"
+#define kStrUnsupportedROMMessage "Fitxer d;laimatge ROM ;[^r;{ carregat amb ;`exit, per;`o aquesta versi;eo no est;`a suportada."
+
+#define kStrQuitWarningTitle "Si us plau, apagueu l;laordinador emulat abans de sortir."
+#define kStrQuitWarningMessage "Per for;car ^p sortir, amb risc de corrupci;eo en les imatges de discos muntades, utilitzeu la ordre ;]Q;} del ^p Mode Control. Per coneixer m;ees sobre el Mode Control, vegi ;[M;ees Comandaments;ll;{ al menu ;[Especial;{ ."
+
+#define kStrReportAbnormalTitle "Situaci;eo anormal"
+#define kStrReportAbnormalMessage "L;laordinador emulat intenta fer una operaci;eo no esperada en un ;eus normal."
+
+#define kStrBadArgTitle "Argument desconegut"
+#define kStrBadArgMessage "No es va comprendre algun dels arguments de la l;einia d;laordres, i es va ignorar."
+
+#define kStrOpenFailTitle "Obertura fracassada"
+#define kStrOpenFailMessage "No s;laha pogut obrir la imatge disc."
+
+#define kStrNoReadROMTitle "No es pot obrir la imatge ROM"
+#define kStrNoReadROMMessage "Es va trobar el fitxer d;laimatge ROM ;[^r;{, per;`o no es va poder llegir."
+
+#define kStrShortROMTitle "Imatge ROM massa curta"
+#define kStrShortROMMessage "El fitxer d;laimatge ROM ;[^r;{ ;ees m;ees curt del que hauria de ser."
+
+/* state of a boolean option */
+#define kStrOn "activat"
+#define kStrOff "desactivat"
+
+/* state of a key */
+#define kStrPressed "polsada"
+#define kStrReleased "deixada anar"
+
+/* state of Stopped */
+#define kStrStoppedOn kStrOn
+#define kStrStoppedOff kStrOff
+
+/* About Screen */
+#define kStrProgramInfo "^v"
+#define kStrSponsorIs "^v. Aquesta variaci;eo est;`a patrocinada per:"
+#define kStrWorkOfMany "Copyright ^y. ^p cont;ee el treball de moltes persones. Aquesta versi;eo ;ees mantinguda per:"
+#define kStrForMoreInfo "Per m;ees informaci;eo, vegeu:"
+#define kStrLicense "^p es distribueix sota els termes de la llic;`encia p;eublica GNU, versi;eo 2."
+#define kStrDisclaimer " ^p es distribueix amb l;laesperan;ca de ser ;eutil, per;`o SENSE CAP GARANTIA;ls fins i tot sense la garantia impl;eicita de MERCANTIBILITAT O ADECUACI;eO PER A UN ;eUS PARTICULAR."
+
+/* Help Screen */
+#define kStrHowToLeaveControl "Per sortir del Mode Control, deixeu anar la tecla ;]^c;} ."
+#define kStrHowToPickACommand "Sin;eo, polsi una lletra. Els comandaments disponibles s;eon:"
+#define kStrCmdAbout "Sobre (informaci;eo sobre versi;eo)"
+#define kStrCmdOpenDiskImage "Obrir imatge de disc..."
+#define kStrCmdQuit "Sortir"
+#define kStrCmdSpeedControl "Control de velocitat;ll (^s)"
+#define kStrCmdMagnifyToggle "Magnificaci;eo (^g)"
+#define kStrCmdFullScrnToggle "Pantalla completa (^f)"
+#define kStrCmdCtrlKeyToggle "Toggle emulaci;eo tecla ;]^m;} (^k)"
+#define kStrCmdReset "Restablir"
+#define kStrCmdInterrupt "Interrompre"
+#define kStrCmdHelp "Ajuda (mostra aquesta p;`agina)"
+
+/* Speed Control Screen */
+#define kStrCurrentSpeed "Velocitat actual: ^s"
+#define kStrSpeedAllOut "M;`axima velocitat"
+#define kStrSpeedStopped "Aturar (^h)"
+#define kStrSpeedBackToggle "Executar en segon pla (^b)"
+#define kStrSpeedAutoSlowToggle "AutoSlow (^l)"
+#define kStrSpeedExit "Sortir del control de velocitat"
+
+#define kStrNewSpeed "Velocitat: ^s"
+#define kStrSpeedValueAllOut kStrSpeedAllOut
+
+#define kStrNewStopped "Aturar est;ea ^h."
+#define kStrNewRunInBack "Executar en segon pla est;`a ^b."
+#define kStrNewAutoSlow "AutoSlow est;`a ^l."
+
+#define kStrNewMagnify "Magnificaci;eo est;`a ^g."
+
+#define kStrNewFullScreen "Pantalla completa est;`a ^f."
+
+#define kStrNewCntrlKey "Emulat tecla ;]^m;} ^k."
+
+#define kStrCmdCancel "cancel;l.lar"
+
+#define kStrConfirmReset "Est;`a segur de voler reiniciar l;laordinador emulat? Els canvis no salvats es perdran, i hi ha risc de corrupci;eo en les imatges de discos muntades. Premeu una tecla:"
+#define kStrResetDo "restablir"
+#define kStrResetNo kStrCmdCancel
+
+#define kStrHaveReset "S;laha reiniciat l;laordinador emulat"
+
+#define kStrCancelledReset "Reset cancel;l.lat"
+
+#define kStrConfirmInterrupt "Est;`a segur de voler interrompre l;laordinador emulat? Aix;`o invocar;`a qualsevol debugger instal;l.lat. Premeu una tecla:"
+#define kStrInterruptDo "interrompre"
+#define kStrInterruptNo kStrCmdCancel
+
+#define kStrHaveInterrupted "S;laha interromput l;laordinador emulat"
+
+#define kStrCancelledInterrupt "Interrupci;eo cancel;l.lada"
+
+#define kStrConfirmQuit "Est;`a segur de desitjar sortir de ^p? Hauria apagar l;laordinador emulat abans de sortir, per evitar corrupcions en les imatges de discos muntades. Premeu una tecla:"
+#define kStrQuitDo "sortir"
+#define kStrQuitNo kStrCmdCancel
+
+#define kStrCancelledQuit "Sortida cancel;l.lada"
+
+#define kStrModeConfirmReset "Mode Control : Confirma reset"
+#define kStrModeConfirmInterrupt "Mode Control : Confirma Interrupci;eo"
+#define kStrModeConfirmQuit "Mode Control : Confirma sortida"
+#define kStrModeSpeedControl "Mode Control : Control de velocitat"
+#define kStrModeControlBase "Mode Control (Premi ;laH;la per a l;laajuda)"
+#define kStrModeControlHelp "Mode Control"
+#define kStrModeMessage "Missatge (Premi ;]C;} per continuar)"
+
+#define kStrMenuFile "Fitxer"
+#define kStrMenuSpecial "Especial"
+#define kStrMenuHelp "Ajuda"
+
+#define kStrMenuItemAbout "Sobre ^p"
+#define kStrMenuItemOpen "Obrir imatge de disc"
+#define kStrMenuItemQuit "Sortir"
+#define kStrMenuItemMore "M;eess comandaments"
+
+#define kStrAppMenuItemHide "Ocultar ^p"
+#define kStrAppMenuItemHideOthers "Ocultar la resta"
+#define kStrAppMenuItemShowAll "Mostrar-ho tot"
+#define kStrAppMenuItemQuit "Sortir de ^p"
+
+#define kStrCmdCopyOptions "Copiar variation options"
+#define kStrHaveCopiedOptions "Variation options copiat"
--- /dev/null
+++ b/src/STRCNCZE.h
@@ -1,0 +1,167 @@
+/*
+ STRCNCZE.h
+
+ Copyright (C) 2017 Anonymous, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file;ls see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY;ls without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ STRing CoNstants for CZEch
+
+ These strings were translated by Anonymous.
+*/
+
+#define kStrAboutTitle "O programu"
+#define kStrAboutMessage "Pro zobrazen;ei informac;ei o programu, pou;vzijte p;vr;eikaz ;]A;} v ovl;eadac;eim m;eodu ^p. Pro informace o ovl;eadac;eim m;eodu, pod;eivejte se do ;[V;eice p;vr;eikaz;ru;ll;{ v menu ;[Dal;vs;ei mo;vznosti;{."
+
+#define kStrMoreCommandsTitle "V kontroln;eim m;eodu ^p jsou dostupn;ee dal;vs;ei p;vr;eikazy."
+#define kStrMoreCommandsMessage "pro pou;vzit;ei ovl;eadac;eiho m;eodu stiskn;vete a dr;vzte ;]^c;}. V ovl;eadac;eim m;eodu z;rustanete, dokud nepust;eite ;]^c;}. stiskn;vete ;]H;} v ovl;eadac;eim m;eodu pro zobrazen;ei dostupn;eych p;vr;eikaz;ru."
+
+#define kStrTooManyImagesTitle "P;vr;eili;vs mnoho obraz;ru disk;ru"
+#define kStrTooManyImagesMessage "Tolik obraz;ru disk;ru p;vripojit nezvl;eadnu. zkuste jeden odpojit."
+
+#define kStrImageInUseTitle "Obraz disku je pou;vz;eiv;ean"
+#define kStrImageInUseMessage "Nemohu p;vripojit obraz disku, proto;vze je pou;vz;eiv;ean jinou aplikac;ei nebo otev;vren v ^p."
+
+#define kStrOutOfMemTitle "Nedostatek pam;veti"
+#define kStrOutOfMemMessage "Pro su;vst;ven;ei ^p nen;ei dostatek pam;veti."
+
+#define kStrNoROMTitle "ROM nenalezen"
+#define kStrNoROMMessage "Nemohu naj;eit soubor ROM ;[^r;{. Pro v;eice informac;ei se pod;eivejte na: ;[^w;{."
+
+#define kStrCorruptedROMTitle "Kontroln;ei sou;vcet ROMu selhal"
+#define kStrCorruptedROMMessage "ROM ;[^r;{ m;ru;vze b;eyt po;vskozen."
+
+#define kStrUnsupportedROMTitle "Nepodporovan;ey ROM"
+#define kStrUnsupportedROMMessage "ROM ;[^r;{ se ;eusp;ve;vsn;ve na;vcetl, ale s touto verz;ei ROMu neum;eim pracovat."
+
+#define kStrQuitWarningTitle "Pros;eim vypn;vete emulovan;ey po;vc;eita;vc p;vred zav;vren;eim."
+#define kStrQuitWarningMessage "Pro vynucen;ei zav;vren;ei ^p (riskujete po;vskozen;ei p;vripojen;eych disk;ru),pou;vzijte p;vr;eikaz ;]Q;} ovl;eadac;eiho m;eodu ^p. Pro informace o ovl;eadac;eim m;eodu, pod;eivejte se do ;[V;eice p;vr;eikaz;ru;ll;{ v menu ;[Dal;vs;ei mo;vznosti;{."
+
+#define kStrReportAbnormalTitle "Abnorm;ealn;ei situace"
+#define kStrReportAbnormalMessage "Emulovan;ey po;vc;eite;vc se pokou;vs;ei o operaci, kter;ea nebyla o;vcek;eav;eana p;vri b;ve;vzn;eem pou;vz;eiv;ean;ei."
+
+#define kStrBadArgTitle "Nezn;eam;ey argument"
+#define kStrBadArgMessage "Nerozum;eim jednomu z p;vr;eikazov;eych argument;ru, budu ho ignorovat."
+
+#define kStrOpenFailTitle "Otev;vren;ei selhalo"
+#define kStrOpenFailMessage "Neopda;vrilo se mi otev;vr;eit obraz disku."
+
+#define kStrNoReadROMTitle "Ne;vciteln;ey ROM"
+#define kStrNoReadROMMessage "Na;vsel jsem ROM ;[^r;{, ale nemohu ho p;vre;vc;eist."
+
+#define kStrShortROMTitle "P;vr;eili;vs kr;eatk;ey ROM"
+#define kStrShortROMMessage "ROM ;[^r;{ je krat;vs;ei ne;vz obvykle."
+
+/* state of a boolean option */
+#define kStrOn "on"
+#define kStrOff "off"
+
+/* state of a key */
+#define kStrPressed "stisknuto"
+#define kStrReleased "pu;vst;veno"
+
+/* state of Stopped */
+#define kStrStoppedOn kStrOn
+#define kStrStoppedOff kStrOff
+
+/* About Screen */
+#define kStrProgramInfo "^v"
+#define kStrSponsorIs "^v. Tuto variaci sponzoruje:"
+#define kStrWorkOfMany "Copyright ^y. ^p Obsahuje pr;eaci mnoha lid;ei. Tuto verzi udr;vzuje:"
+#define kStrForMoreInfo "Pro v;eice informac;ei jd;vete na:"
+#define kStrLicense "^p je distribuov;ean poj licenc;ei GNU GPL, verze 2."
+#define kStrDisclaimer " ^p je distribuov;ean s nad;vej;ei, ;vze ude pou;vz;eiv;ean, ale BEZ JAK;eEKOLIV Z;eARUKY;ls t;ee;vz bez implikovan;ee z;earuky OBCHODOVATELNOSTI nebo VHODNOSTI PRO UR;vCIT;eY ;eU;vCEL."
+
+/* Help Screen */
+#define kStrHowToLeaveControl "Pro opu;vst;ven;ei ovl;ead;eac;eiho m;eodu pus;vtte ;]^c;}."
+#define kStrHowToPickACommand "jinak stiskn;vete p;eismeno. Dostupn;ee p;vr;eikazy jsou:"
+#define kStrCmdAbout "O programu (informace o verzi)"
+#define kStrCmdOpenDiskImage "Otev;vr;eit obraz disku"
+#define kStrCmdQuit "Zav;vr;eit"
+#define kStrCmdSpeedControl "Ovl;ead;ean;ei rychlosti;ll (^s)"
+#define kStrCmdMagnifyToggle "P;vribl;ei;vzen;ei (^g)"
+#define kStrCmdFullScrnToggle "Cel;ea obrazovka (^f)"
+#define kStrCmdCtrlKeyToggle "P;vrep;ein;ean;ei emulovan;eeho ;]^m;} (^k)"
+#define kStrCmdReset "Reset"
+#define kStrCmdInterrupt "Vyru;vsit"
+#define kStrCmdHelp "Pomoc (uk;eaz;eat tuto str;eanku)"
+
+/* Speed Control Screen */
+#define kStrCurrentSpeed "Sou;vcasn;ea rychlost: ^s"
+#define kStrSpeedAllOut "Maximum"
+#define kStrSpeedStopped "zastavit (^h)"
+#define kStrSpeedBackToggle "b;ve;vz;vet v pozad;ei (^b)"
+#define kStrSpeedAutoSlowToggle "automatick;ee zpomalen;ei (^l)"
+#define kStrSpeedExit "Zav;vr;eit ovl;ead;ean;ei rychlosti"
+
+#define kStrNewSpeed "Rychlost: ^s"
+#define kStrSpeedValueAllOut kStrSpeedAllOut
+
+#define kStrNewStopped "Je zastaven: ^h."
+#define kStrNewRunInBack "B;ve;vz;ei na pozad;ei: ^b."
+#define kStrNewAutoSlow "Je automaticky zpomalen: ^l."
+
+#define kStrNewMagnify "P;vribl;ei;vzen;ei: ^g."
+
+#define kStrNewFullScreen "Na celou obrazovku: ^f."
+
+#define kStrNewCntrlKey "Emulovan;ey ;]^m;}: ^k."
+
+#define kStrCmdCancel "Storno"
+
+#define kStrConfirmReset "Opravdu chcete resetovat emulovan;ey po;vc;eita;vc? Ztrat;eite neulo;vzen;ee zm;veny a riskujete po;vskozen;ei p;vripojen;eych obraz;ru disk;ru. Stiskn;vete p;eismeno:"
+#define kStrResetDo "resetovat"
+#define kStrResetNo kStrCmdCancel
+
+#define kStrHaveReset "Resetoval jsem emulovan;ey po;vc;eita;vc"
+
+#define kStrCancelledReset "Resetov;ean;ei zru;vseno"
+
+#define kStrConfirmInterrupt "Opravdu chcete vyru;vsit emulovan;ey po;vc;eita;vc? Spust;ei se nainstalovan;ey debugger. Stiskn;vete p;eismeno:"
+#define kStrInterruptDo "vyru;vsit"
+#define kStrInterruptNo kStrCmdCancel
+
+#define kStrHaveInterrupted "Vyru;vsil jsem emulovan;ey po;vc;eita;vc"
+
+#define kStrCancelledInterrupt "Vyru;vsen;ei zru;vseno"
+
+#define kStrConfirmQuit "Opravdu chcete zav;vr;eit ^p? M;veli byste vypnout emulovan;ey po;vc;eita;vc p;vred vypnut;eim pro zabr;ean;ven;ei po;vskozen;ei p;vripojen;eych obraz;ru disk;ru. Stiskn;vete p;eismeno:"
+#define kStrQuitDo "odej;eit"
+#define kStrQuitNo kStrCmdCancel
+
+#define kStrCancelledQuit "Zav;vren;ei zru;vseno"
+
+#define kStrModeConfirmReset " : Confirm Reset"
+#define kStrModeConfirmInterrupt "ovl;ead;eac;ei m;eod : Potvrdit vyru;vsen;ei"
+#define kStrModeConfirmQuit "ovl;ead;eac;ei m;eod : Potvrdit zav;vren;ei"
+#define kStrModeSpeedControl "ovl;ead;eac;ei m;eod : Ovl;ead;ean;ei rychlosti"
+#define kStrModeControlBase "ovl;ead;eac;ei m;eod (stiskn;vete ;]H;} pro pomoc) "
+#define kStrModeControlHelp "ovl;ead;eac;ei m;eod"
+#define kStrModeMessage "Zpr;eava (Stiskn;vete ;]C;} pro pokra;vcov;ean;ei)"
+
+#define kStrMenuFile "Soubor"
+#define kStrMenuSpecial "Dal;vs;ei mo;vznosti"
+#define kStrMenuHelp "Pomoc"
+
+#define kStrMenuItemAbout "O ^p"
+#define kStrMenuItemOpen "Otev;vr;eit obraz disku"
+#define kStrMenuItemQuit "Odej;eit"
+#define kStrMenuItemMore "V;eice p;vr;eikaz;ru"
+
+#define kStrAppMenuItemHide "Skr;eyt ^p"
+#define kStrAppMenuItemHideOthers "Skr;eyt ostatn;ei"
+#define kStrAppMenuItemShowAll "Zobrazit v;vse"
+#define kStrAppMenuItemQuit "Ukon;vcit ^p"
+
+#define kStrCmdCopyOptions "Kop;eirovat variation options"
+#define kStrHaveCopiedOptions "Variation options zkop;eirov;eany"
--- /dev/null
+++ b/src/STRCNDUT.h
@@ -1,0 +1,167 @@
+/*
+ STRCNDUT.h
+
+ Copyright (C) 2006 Luc Pauwels, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ STRing CoNstants for DUTch
+
+ These strings were translated by Luc Pauwels.
+*/
+
+#define kStrAboutTitle "Over ^p"
+#define kStrAboutMessage "Gebruik het ;]A;}-commando van de ^p controlemodus om meer informatie over deze applicatie te tonen. Om meer te weten te komen over de controlemodus, zie ;[Meer Commando;}s;ll;{ in het ;[Speciaal;{ menu."
+
+#define kStrMoreCommandsTitle "Meer commando;}s zijn beschikbaar in de ^p controlemodus."
+#define kStrMoreCommandsMessage "Om naar de controlemodus te gaan, hou de ;]^c;} toets ingedrukt. Je blijft in de controlemodus zolang je de ;]^c;} toets ingedrukt houdt. Type ;]H;} in de controlemodus om een lijst van beschikbare commando;}s te zien."
+
+#define kStrTooManyImagesTitle "Teveel schijfkopiebestanden"
+#define kStrTooManyImagesMessage "Het maximaal aantal schijfkopiebestanden is in gebruik. Probeer er ;ee;een te verwijderen."
+
+#define kStrImageInUseTitle "Schijfkopiebestand in gebruik"
+#define kStrImageInUseMessage "Ik kan het schijfkopiebestand niet openen omdat het al in gebruik is door een andere applicatie of omdat het al geopend is in ^p."
+
+#define kStrOutOfMemTitle "Niet genoeg geheugen"
+#define kStrOutOfMemMessage "Er is niet genoeg geheugen beschikbaar om ^p te openen."
+
+#define kStrNoROMTitle "ROM bestand niet gevonden"
+#define kStrNoROMMessage "Ik kan het ROM bestand ;[^r;{ niet vinden. Voor meer informatie, zie ;[^w;{."
+
+#define kStrCorruptedROMTitle "ROM controlegetal verkeerd"
+#define kStrCorruptedROMMessage "Het ROM bestand ;[^r;{ is mogelijk beschadigd."
+
+#define kStrUnsupportedROMTitle "Niet ondersteunde ROM"
+#define kStrUnsupportedROMMessage "Het ROM bestand ;[^r;{ werd succesvol ingeladen, maar ik ondersteun deze ROM versie niet."
+
+#define kStrQuitWarningTitle "Zet de ge;uemuleerde computer uit vooraleer de applicatie te stoppen."
+#define kStrQuitWarningMessage "Om ^p geforceerd te stoppen, met het risico dat het gebruikte schijfkopiebestand beschadigd geraakt, gebruik het ;]Q;} commando van de ^p controlemodus. Om meer te weten te komen over de controlemodus, zie ;[Meer Commando;}s;{ in het ;[Speciaal;{ menu."
+
+#define kStrReportAbnormalTitle "Abnormale situatie"
+#define kStrReportAbnormalMessage "De ge;uemuleerde computer probeert een operatie uit te voeren die onder normale omstandigheden niet kan voorkomen."
+
+#define kStrBadArgTitle "Onbekend argument"
+#define kStrBadArgMessage "Ik herkende ;ee;een van de commandolijn-argumenten niet en heb het genegeerd."
+
+#define kStrOpenFailTitle "Open operatie gefaald"
+#define kStrOpenFailMessage "Ik kon het schijfkopiebestand niet openen."
+
+#define kStrNoReadROMTitle "Het ROM bestand kan niet gelezen worden"
+#define kStrNoReadROMMessage "Ik kon het ROM bestand ;[^r;{vinden, maar ik kon het niet lezen."
+
+#define kStrShortROMTitle "ROM bestand te kort"
+#define kStrShortROMMessage "Het ROM bestand ;[^r;{ is korter dan verwacht."
+
+/* state of a boolean option */
+#define kStrOn "aan"
+#define kStrOff "uit"
+
+/* state of a key */
+#define kStrPressed "ingedrukt"
+#define kStrReleased "losgelaten"
+
+/* state of Stopped */
+#define kStrStoppedOn kStrOn
+#define kStrStoppedOff kStrOff
+
+/* About Screen */
+#define kStrProgramInfo "^v"
+#define kStrSponsorIs "^v. This variation is made for:"
+#define kStrWorkOfMany "Copyright ^y. ^p is het werk van velen. Deze versie wordt onderhouden door:"
+#define kStrForMoreInfo "Voor meer informatie, zie:"
+#define kStrLicense "^p wordt verspreid onder de voorwaarden van de GNU Public License, versie 2."
+#define kStrDisclaimer " ^p wordt verspreid in de hoop dat het bruikbaar is, maar ZONDER ENIGE GARANTIE, zelfs zonder impliciete garanties van VERKOOPBAARHEID noch BRUIKBAARHEID VOOR EEN BEPAALD DOELEINDE."
+
+/* Help Screen */
+#define kStrHowToLeaveControl "Laat de ;]^c;} toets los om de controlemodus te verlaten."
+#define kStrHowToPickACommand "Zoniet, typ een letter. De beschikbare commando;}s zijn:"
+#define kStrCmdAbout "Over ^p (informatie over deze versie)"
+#define kStrCmdOpenDiskImage "Open schijfkopiebstand;ll"
+#define kStrCmdQuit "Stop"
+#define kStrCmdSpeedControl "Snelheidscontrole;ll (^s)"
+#define kStrCmdMagnifyToggle "Schermvergroting (^g)"
+#define kStrCmdFullScrnToggle "Gebruik het volledig scherm (^f)"
+#define kStrCmdCtrlKeyToggle "Ge;uemuleerde ;]^m;} toets (^k)"
+#define kStrCmdReset "Herstart"
+#define kStrCmdInterrupt "Onderbreek"
+#define kStrCmdHelp "Hulp (toon deze pagina)"
+
+/* Speed Control Screen */
+#define kStrCurrentSpeed "Huidige snelheid: ^s"
+#define kStrSpeedAllOut "Zo snel mogelijk"
+#define kStrSpeedStopped "Stopschakelaar (^h)"
+#define kStrSpeedBackToggle "Schakelaar om in de achtergrond te draaien (^b)"
+#define kStrSpeedAutoSlowToggle "AutoSlow (^l)"
+#define kStrSpeedExit "Verlaat Snelheidscontrole"
+
+#define kStrNewSpeed "Snelheid: ^s"
+#define kStrSpeedValueAllOut kStrSpeedAllOut
+
+#define kStrNewStopped "Stopschakelaar is ^h."
+#define kStrNewRunInBack "In de achtergrond draaien is ^b."
+#define kStrNewAutoSlow "AutoSlow is ^l."
+
+#define kStrNewMagnify "Schermvergroting is ^g."
+
+#define kStrNewFullScreen "Volledig scherm gebruiken is ^f."
+
+#define kStrNewCntrlKey "Ge;uemuleerde ;]^m;} toets ^k."
+
+#define kStrCmdCancel "annuleer"
+
+#define kStrConfirmReset "Bent u er zeker van dat u de ge;uemuleerde computer wilt herstarten? Werk dat niet bewaard werd zal verloren gaan, en er bestaat een kans dat het gebruikte schijfkopiebestand beschadigd geraakt. Typ een letter:"
+#define kStrResetDo "herstart"
+#define kStrResetNo kStrCmdCancel
+
+#define kStrHaveReset "De ge;uemuleerde computer werd herstart"
+
+#define kStrCancelledReset "Herstart werd geannuleerd"
+
+#define kStrConfirmInterrupt "Bent u er zeker van dat u de ge;uemuleerde computer wilt onderbreken? Dit zal de eventueel ge;uinstalleerde debugger activeren. Typ een letter:"
+#define kStrInterruptDo "onderbreken"
+#define kStrInterruptNo kStrCmdCancel
+
+#define kStrHaveInterrupted "De ge;uemuleerde computer werd onderbroken"
+
+#define kStrCancelledInterrupt "Onderbreking geannuleerd"
+
+#define kStrConfirmQuit "Bent u er zeker van dat u wilt ^p wilt stoppen? U zou eerst de ge;uemuleerde computer moeten uitzetten alvorens te stoppen om beschadiging van het gebruikte schijfkopiebestand te vermijden. Typ een letter:"
+#define kStrQuitDo "stop"
+#define kStrQuitNo kStrCmdCancel
+
+#define kStrCancelledQuit "Stoppen geannuleerd"
+
+#define kStrModeConfirmReset "Controlemodus : Bevesting herstarten"
+#define kStrModeConfirmInterrupt "Controlemodus : Bevesting onderbreking"
+#define kStrModeConfirmQuit "Controlemodus : Bevesting stoppen"
+#define kStrModeSpeedControl "Controlemodus : Snelheidscontrole"
+#define kStrModeControlBase "Controlemodus (Typ ;]H;} voor meer hulp)"
+#define kStrModeControlHelp "Controlemodus"
+#define kStrModeMessage "Boodschap (Typ ;]C;} om verder te gaan)"
+
+#define kStrMenuFile "Archief"
+#define kStrMenuSpecial "Speciaal"
+#define kStrMenuHelp "Hulp"
+
+#define kStrMenuItemAbout "Over ^p"
+#define kStrMenuItemOpen "Open schijfkopiebestand"
+#define kStrMenuItemQuit "Stop"
+#define kStrMenuItemMore "Meer Commando;}s"
+
+#define kStrAppMenuItemHide "Verberg ^p"
+#define kStrAppMenuItemHideOthers "Verberg andere"
+#define kStrAppMenuItemShowAll "Toon alles"
+#define kStrAppMenuItemQuit "Stop ^p"
+
+#define kStrCmdCopyOptions "Kopieer variation options"
+#define kStrHaveCopiedOptions "Variation options gekopieerd"
--- /dev/null
+++ b/src/STRCNENG.h
@@ -1,0 +1,167 @@
+/*
+ STRCNENG.h
+
+ Copyright (C) 2006 Paul C. Pratt, Pierre Lemieux
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ STRing CoNstants for ENGlish
+
+ Pierre Lemieux provided some corrections and suggestions.
+*/
+
+#define kStrAboutTitle "About"
+#define kStrAboutMessage "To display information about this program, use the ;]A;} command of the ^p Control Mode. To learn about the Control Mode, see the ;[More Commands;ll;{ item in the ;[Special;{ menu."
+
+#define kStrMoreCommandsTitle "More commands are available in the ^p Control Mode."
+#define kStrMoreCommandsMessage "To enter the Control Mode, press and hold down the ;]^c;} key. You will remain in the Control Mode until you release the ;]^c;} key. Type ;]H;} in the Control Mode to list available commands."
+
+#define kStrTooManyImagesTitle "Too many Disk Images"
+#define kStrTooManyImagesMessage "I can not mount that many Disk Images. Try ejecting one."
+
+#define kStrImageInUseTitle "Disk Image in use"
+#define kStrImageInUseMessage "I can not mount the Disk Image because it is already in use by another application or already open in ^p."
+
+#define kStrOutOfMemTitle "Not enough Memory"
+#define kStrOutOfMemMessage "There is not enough memory available to launch ^p."
+
+#define kStrNoROMTitle "Unable to locate ROM image"
+#define kStrNoROMMessage "I can not find the ROM image file ;[^r;{. For more information, see: ;[^w;{."
+
+#define kStrCorruptedROMTitle "ROM checksum failed"
+#define kStrCorruptedROMMessage "The ROM image file ;[^r;{ may be corrupted."
+
+#define kStrUnsupportedROMTitle "Unsupported ROM"
+#define kStrUnsupportedROMMessage "The ROM image file ;[^r;{ loaded successfully, but I don;}t support this ROM version."
+
+#define kStrQuitWarningTitle "Please shut down the emulated computer before quitting."
+#define kStrQuitWarningMessage "To force ^p to quit, at the risk of corrupting the mounted disk image files, use the ;]Q;} command of the ^p Control Mode. To learn about the Control Mode, see the ;[More Commands;ll;{ item in the ;[Special;{ menu."
+
+#define kStrReportAbnormalTitle "Abnormal Situation"
+#define kStrReportAbnormalMessage "The emulated computer is attempting an operation that wasn;}t expected to happen in normal use."
+
+#define kStrBadArgTitle "Unknown argument"
+#define kStrBadArgMessage "I did not understand one of the command line arguments, and ignored it."
+
+#define kStrOpenFailTitle "Open failed"
+#define kStrOpenFailMessage "I could not open the disk image."
+
+#define kStrNoReadROMTitle "Unable to read ROM image"
+#define kStrNoReadROMMessage "I found the ROM image file ;[^r;{, but I can not read it."
+
+#define kStrShortROMTitle "ROM image too short"
+#define kStrShortROMMessage "The ROM image file ;[^r;{ is shorter than it should be."
+
+/* state of a boolean option */
+#define kStrOn "on"
+#define kStrOff "off"
+
+/* state of a key */
+#define kStrPressed "pressed"
+#define kStrReleased "released"
+
+/* state of Stopped */
+#define kStrStoppedOn kStrOn
+#define kStrStoppedOff kStrOff
+
+/* About Screen */
+#define kStrProgramInfo "^v"
+#define kStrSponsorIs "^v. This variation is made for:"
+#define kStrWorkOfMany "Copyright ^y. ^p contains the work of many people. This version is maintained by:"
+#define kStrForMoreInfo "For more information, see:"
+#define kStrLicense "^p is distributed under the terms of the GNU Public License, version 2."
+#define kStrDisclaimer " ^p is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;ls without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+/* Help Screen */
+#define kStrHowToLeaveControl "To leave the Control Mode, release the ;]^c;} key."
+#define kStrHowToPickACommand "Otherwise, type a letter. Available commands are:"
+#define kStrCmdAbout "About (version information)"
+#define kStrCmdOpenDiskImage "Open disk image;ll"
+#define kStrCmdQuit "Quit"
+#define kStrCmdSpeedControl "Speed control;ll (^s)"
+#define kStrCmdMagnifyToggle "Magnify toggle (^g)"
+#define kStrCmdFullScrnToggle "Full screen toggle (^f)"
+#define kStrCmdCtrlKeyToggle "emulated ;]^m;} Key toggle (^k)"
+#define kStrCmdReset "Reset"
+#define kStrCmdInterrupt "Interrupt"
+#define kStrCmdHelp "Help (show this page)"
+
+/* Speed Control Screen */
+#define kStrCurrentSpeed "Current speed: ^s"
+#define kStrSpeedAllOut "All out"
+#define kStrSpeedStopped "stopped toggle (^h)"
+#define kStrSpeedBackToggle "run in Background toggle (^b)"
+#define kStrSpeedAutoSlowToggle "autosloW toggle (^l)"
+#define kStrSpeedExit "Exit speed control"
+
+#define kStrNewSpeed "Speed: ^s"
+#define kStrSpeedValueAllOut kStrSpeedAllOut
+
+#define kStrNewStopped "Stopped is ^h."
+#define kStrNewRunInBack "Run in background is ^b."
+#define kStrNewAutoSlow "AutoSlow is ^l."
+
+#define kStrNewMagnify "Magnify is ^g."
+
+#define kStrNewFullScreen "Full Screen is ^f."
+
+#define kStrNewCntrlKey "Emulated ;]^m;} key ^k."
+
+#define kStrCmdCancel "cancel"
+
+#define kStrConfirmReset "Are you sure you want to reset the emulated computer? Unsaved changes will be lost, and there is a risk of corrupting the mounted disk image files. Type a letter:"
+#define kStrResetDo "reset"
+#define kStrResetNo kStrCmdCancel
+
+#define kStrHaveReset "Have reset the emulated computer"
+
+#define kStrCancelledReset "Reset cancelled"
+
+#define kStrConfirmInterrupt "Are you sure you want to interrupt the emulated computer? This will invoke any installed debugger. Type a letter:"
+#define kStrInterruptDo "interrupt"
+#define kStrInterruptNo kStrCmdCancel
+
+#define kStrHaveInterrupted "Have interrupted the emulated computer"
+
+#define kStrCancelledInterrupt "Interrupt cancelled"
+
+#define kStrConfirmQuit "Are you sure you want to quit ^p? You should shut down the emulated computer before quitting to prevent corrupting the mounted disk image files. Type a letter:"
+#define kStrQuitDo "quit"
+#define kStrQuitNo kStrCmdCancel
+
+#define kStrCancelledQuit "Quit cancelled"
+
+#define kStrModeConfirmReset "Control Mode : Confirm Reset"
+#define kStrModeConfirmInterrupt "Control Mode : Confirm Interrupt"
+#define kStrModeConfirmQuit "Control Mode : Confirm Quit"
+#define kStrModeSpeedControl "Control Mode : Speed Control"
+#define kStrModeControlBase "Control Mode (Type ;]H;} for help)"
+#define kStrModeControlHelp "Control Mode"
+#define kStrModeMessage "Message (Type ;]C;} to continue)"
+
+#define kStrMenuFile "File"
+#define kStrMenuSpecial "Special"
+#define kStrMenuHelp "Help"
+
+#define kStrMenuItemAbout "About ^p"
+#define kStrMenuItemOpen "Open Disk Image"
+#define kStrMenuItemQuit "Quit"
+#define kStrMenuItemMore "More Commands"
+
+#define kStrAppMenuItemHide "Hide ^p"
+#define kStrAppMenuItemHideOthers "Hide Others"
+#define kStrAppMenuItemShowAll "Show All"
+#define kStrAppMenuItemQuit "Quit ^p"
+
+#define kStrCmdCopyOptions "copy variation options"
+#define kStrHaveCopiedOptions "Variation options copied"
--- /dev/null
+++ b/src/STRCNFRE.h
@@ -1,0 +1,169 @@
+/*
+ STRCNFRE.h
+
+ Copyright (C) 2006 Pierre Lemieux, Ga;uel Coup;ee, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ STRing CoNstants for FREnch
+
+ These strings were translated by Pierre Lemieux, and an earlier
+ version of them was proofread by Ga;uel Coup;ee.
+*/
+
+#define kStrAboutTitle ";`A propos"
+#define kStrAboutMessage "Pour afficher des informations sur ce programme, utilisez la commande A du mode commande de ^p. Pour en savoir plus sur le mode commande, s;eelectionnez l;}article Autres commandes;ll du menu Sp;eecial."
+
+#define kStrMoreCommandsTitle "D;}autres commandes sont disponibles dans le mode commande de ^p."
+#define kStrMoreCommandsMessage "Pour acc;eeder au mode commande, maintenez la touche ^c enfonc;eee. Vous allez demeurer en mode commande jusqu;};`a ce que vous rel;iachiez la touche ^c. Tapez H en mode commande pour afficher la liste des commandes disponibles."
+
+#define kStrTooManyImagesTitle "Images disques trop nombreuses."
+#define kStrTooManyImagesMessage "Je ne peux pas ouvrir un aussi grand nombre d;}images disques. Veuillez en ;eejecter une."
+
+#define kStrImageInUseTitle "Image disque d;eej;`a utilis;eee."
+#define kStrImageInUseMessage "Je ne peux pas ouvrir l;}image disque, car elle est d;eej;`a utilis;eee par une autre application ou d;eej;`a ouverte dans ^p."
+
+#define kStrOutOfMemTitle "M;eemoire insuffisante."
+#define kStrOutOfMemMessage "Il n;}y a plus assez de m;eemoire disponible pour lancer ^p"
+
+#define kStrNoROMTitle "ROM introuvable."
+#define kStrNoROMMessage "Je n;}arrive pas ;`a trouver le fichier image de la ROM intitul;ee ;[^r;{. Pour plus d;}information, voir : ;[^w;{."
+
+#define kStrCorruptedROMTitle "Somme de contr;iole incorrecte."
+#define kStrCorruptedROMMessage "Le fichier image de la ROM intitul;ee ;[^r;{ est peut-;ietre endommag;ee."
+
+#define kStrUnsupportedROMTitle "ROM non support;eee."
+#define kStrUnsupportedROMMessage "Le chargement du fichier image de la ROM intitul;ee ;[^r;{ a r;eeussi, mais je ne supporte pas cette version de la ROM."
+
+#define kStrQuitWarningTitle "Veuillez ;eeteindre l;}ordinateur virtuel avant de quitter."
+#define kStrQuitWarningMessage "Pour forcer ^p ;`a quitter, au risque d;}endommager les images disques ouvertes, tapez Q en mode commande. Pour en savoir plus sur le mode commande de ^p, s;eelectionnez l;}article Autres commandes;ll du menu Sp;eecial."
+
+#define kStrReportAbnormalTitle "Situation anormale."
+#define kStrReportAbnormalMessage "L;}ordinateur virtuel tente d;}effectuer une op;eeration qui n;};eetait pas pr;eevue dans le cadre d;}un usage normal."
+
+#define kStrBadArgTitle "Argument inconnu."
+#define kStrBadArgMessage "J;}ai ignor;ee l;}un des arguments de la ligne de commande, que je ne comprenais pas."
+
+#define kStrOpenFailTitle "Tentative d;}ouverture infructueuse."
+#define kStrOpenFailMessage "Je n;}ai pas r;eeussi ;`a ouvrir l;}image disque."
+
+#define kStrNoReadROMTitle "ROM illisible."
+#define kStrNoReadROMMessage "J;}ai bien trouv;ee le fichier image de la ROM intitul;ee ;[^r;{, mais je n;}arrive pas ;`a le lire."
+
+#define kStrShortROMTitle "ROM trop courte."
+#define kStrShortROMMessage "Le fichier image de la ROM intitul;ee ;[^r;{ est plus court qu;}il ne le devrait."
+
+/* state of a boolean option */
+#define kStrOn "activ;ee"
+#define kStrOff "d;eesactiv;ee"
+
+/* state of a key */
+#define kStrPressed "enfonc;eee"
+#define kStrReleased "rel;iach;eee"
+
+/* state of Stopped */
+#define kStrStoppedOn "activ;eee"
+#define kStrStoppedOff "d;eesactiv;eee"
+
+/* About Screen */
+#define kStrProgramInfo "^v"
+#define kStrSponsorIs "^v. This variation is made for:"
+#define kStrWorkOfMany "copyright ^y. ^p est le fruit du travail de nombreuses personnes. La maintenance de cette version est assur;eee par :"
+#define kStrForMoreInfo "Pour de plus amples informations, voir :"
+#define kStrLicense "^p est distribu;ee au titre des clauses de la Licence publique g;een;eerale GNU, version 2."
+#define kStrDisclaimer " ^p est distribu;ee dans l;}espoir qu;}il sera utile, mais SANS AUCUNE GARANTIE, sans m;ieme une garantie implicite de COMMERCIABILIT;eE ou DE CONFORMIT;eE ;`A UNE UTILISATION PARTICULI;`ERE."
+
+/* Help Screen */
+#define kStrHowToLeaveControl "Pour quitter le mode commande, rel;iachez la touche ^c."
+#define kStrHowToPickACommand "Sinon, choisissez l;}une des commandes ci-dessous en tapant la lettre correspondante :"
+#define kStrCmdAbout ";`A propos (de cette version du logiciel)"
+#define kStrCmdOpenDiskImage "Ouvrir une image disque;ll"
+#define kStrCmdQuit "Quitter"
+#define kStrCmdSpeedControl "R;eeglage de la vitesse;ll (^s)"
+#define kStrCmdMagnifyToggle "Agrandissement (^g)"
+#define kStrCmdFullScrnToggle "Plein ;eecran (^f)"
+#define kStrCmdCtrlKeyToggle "Touche ^m virtuelle (^k)"
+#define kStrCmdReset "R;eeinitialisation"
+#define kStrCmdInterrupt "Interruption"
+#define kStrCmdHelp "Aide (affiche cette page)"
+
+/* Speed Control Screen */
+#define kStrCurrentSpeed "Vitesse courante : ^s"
+#define kStrSpeedAllOut "Vitesse maximale"
+#define kStrSpeedStopped "Pause (^h)"
+#define kStrSpeedBackToggle "Fonctionnement en arri;`ere-plan (^b)"
+#define kStrSpeedAutoSlowToggle "AutoSlow (^l)"
+#define kStrSpeedExit "Quitter cette page"
+
+#define kStrNewSpeed "Vitesse : ^s"
+#define kStrSpeedValueAllOut "maximale"
+
+#define kStrNewStopped "Pause ^h."
+#define kStrNewRunInBack "Fonctionnement en arri;`ere-plan ^b."
+#define kStrNewAutoSlow "AutoSlow ^l."
+
+#define kStrNewMagnify "Agrandissement ^g."
+
+#define kStrNewFullScreen "Mode plein ;eecran ^f."
+
+#define kStrNewCntrlKey "Touche ^m virtuelle ^k."
+
+#define kStrCmdCancel "Annuler"
+
+#define kStrConfirmReset "Souhaitez-vous vraiment r;eeinitialiser l;}ordinateur virtuel ? Vous allez perdre les modifications non enregistr;eees et vous risquez d;}endommager les images disques ouvertes."
+#define kStrResetDo "R;eeinitialiser"
+#define kStrResetNo kStrCmdCancel
+
+#define kStrHaveReset "Vous avez r;eeinitialis;ee l;}ordinateur virtuel."
+
+#define kStrCancelledReset "R;eeinitialisation annul;eee."
+
+#define kStrConfirmInterrupt "Souhaitez-vous vraiment interrompre l;}ordinateur virtuel ? Cela va d;eeclencher le d;eebogueur (s;}il y en a un d;}install;ee)."
+#define kStrInterruptDo "Interrompre"
+#define kStrInterruptNo kStrCmdCancel
+
+#define kStrHaveInterrupted "Vous avez interrompu l;}ordinateur virtuel."
+
+#define kStrCancelledInterrupt "Interruption annul;eee."
+
+#define kStrConfirmQuit "Souhaitez-vous vraiment quitter ^p ? Vous devriez ;eeteindre l;}ordinateur virtuel avant de quitter, pour ;eeviter d;}endommager les images disques ouvertes."
+#define kStrQuitDo kStrCmdQuit
+#define kStrQuitNo kStrCmdCancel
+
+#define kStrCancelledQuit "Commande Quitter annul;eee."
+
+#define kStrModeConfirmReset "Mode commande : confirmation de la r;eeinitialisation"
+#define kStrModeConfirmInterrupt "Mode commande : confirmation de l;}interruption"
+#define kStrModeConfirmQuit "Mode commande : confirmation de la commande Quitter"
+#define kStrModeSpeedControl "Mode commande : r;eeglage de la vitesse"
+#define kStrModeControlBase "Mode commande (Tapez H pour afficher l;}aide.)"
+#define kStrModeControlHelp "Mode commande"
+#define kStrModeMessage "Message (Tapez C pour continuer.)"
+
+#define kStrMenuFile "Fichier"
+#define kStrMenuSpecial "Sp;eecial"
+#define kStrMenuHelp "Aide"
+
+#define kStrMenuItemAbout ";`A propos de ^p"
+#define kStrMenuItemOpen "Ouvrir une image disque"
+#define kStrMenuItemQuit "Quitter"
+#define kStrMenuItemMore "Autres commandes"
+
+#define kStrAppMenuItemHide "Masquer ^p"
+#define kStrAppMenuItemHideOthers "Masquer les autres"
+#define kStrAppMenuItemShowAll "Tout afficher"
+#define kStrAppMenuItemQuit "Quitter ^p"
+
+#define kStrCntrlKyName "Contr;iole"
+#define kStrCmdCopyOptions "Copier variation options"
+#define kStrHaveCopiedOptions "Variation options copi;eees"
--- /dev/null
+++ b/src/STRCNGER.h
@@ -1,0 +1,169 @@
+/*
+ STRCNGER.h
+
+ Copyright (C) 2006 Paul C. Pratt, Detlef Kahner
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ STRing CoNstants for GERman
+
+ Translated by Detlef Kahner
+*/
+
+#define kStrAboutTitle ";uUber ^p"
+#define kStrAboutMessage "Mehr Informationen zu ^p erhalten Sie ;uuber die Taste ;]A;} im Kontrollmodus. Informationen zum Kontrollmodus erhalten Sie ;uuber den Men;uubefehl ;[Mehr Befehle;ll;{ im Spezialmen;uu."
+
+#define kStrMoreCommandsTitle "Mehr Befehle sind im Kontrollmodus abrufbar."
+#define kStrMoreCommandsMessage "Um den Kontrollmodus von ^p aufzurufen, dr;uucken Sie die ;]^c;}-Taste und lassen diese gedr;uuckt. Sie verbleiben im Kontrollmodus, solange Sie diese Taste gedr;uuckt halten. Eine Liste verf;uugbarer Befehle erhalten Sie w;uahrenddessen durch Dr;uucken der Taste ;]H;}."
+
+#define kStrTooManyImagesTitle "Zuviele Disketten-Images."
+#define kStrTooManyImagesMessage "Soviele Images k;uonnen nicht gemountet sein. Bitte werfen Sie einige aus."
+
+#define kStrImageInUseTitle "Disketten-Image bereits in Gebrauch."
+#define kStrImageInUseMessage "Disketten-Image kann nicht gemountet werden, weil es entweder bereits in ^p gemountet ist oder von einem anderen Programm (z. B. dem Finder) verwendet wird."
+
+#define kStrOutOfMemTitle "Zuwenig Arbeitsspeicher."
+#define kStrOutOfMemMessage "Es ist nicht gen;uugend Arbeitsspeicher vorhanden, um ^p zu starten."
+
+#define kStrNoROMTitle "ROM nicht gefunden."
+#define kStrNoROMMessage "Das ROM namens ;[^r;{ kann nicht gefunden werden. Mehr Informationen hier: ;[^w;{"
+
+#define kStrCorruptedROMTitle "ROM-Pr;uufsumme fehlgeschlagen."
+#define kStrCorruptedROMMessage "Das ROM ;[^r;{ ist m;uoglicherweise besch;uadigt."
+
+#define kStrUnsupportedROMTitle "ROM wird nicht unterst;uutzt."
+#define kStrUnsupportedROMMessage "Das ROM ;[^r;{ wurde erfolgreich geladen, aber diese Version von ^p unterst;uutzt es nicht."
+
+#define kStrQuitWarningTitle "Bitte fahren Sie das emulierte MacOS herunter, bevor Sie ^p beenden."
+#define kStrQuitWarningMessage "Um ^p sofort zu beenden, aber Besch;uadigungen an den gemounteten Disketten-Images in Kauf zu nehmen, dr;uucken Sie die Taste ;]Q;} innerhalb des Kontrollmodus. Zugriff zum Kontrollmodus von ^p erhalten Sie, indem Sie die ;]^c;}-Taste gedr;uuckt halten."
+
+#define kStrReportAbnormalTitle "Unerwartete Situation"
+#define kStrReportAbnormalMessage "Der emulierte Rechner hat versucht, eine Operation durchzuf;uuhren, die im Rahmen eines normalen Gebrauches nicht vorgesehen war."
+
+#define kStrBadArgTitle "Unbekannter Befehl."
+#define kStrBadArgMessage "Befehlseingabe nicht verstanden und deshalb ignoriert."
+
+#define kStrOpenFailTitle ";uOffnen fehlgeschlagen."
+#define kStrOpenFailMessage "Das Disk-Image konnte nicht ge;uoffnet werden."
+
+#define kStrNoReadROMTitle "ROM nicht lesbar."
+#define kStrNoReadROMMessage "Das ROM namens ;[^r;{ wurde gefunden, kann aber von dieser Version von ^p nicht verwendet werden."
+
+#define kStrShortROMTitle "ROM-Image zu klein."
+#define kStrShortROMMessage "Das ROM ;[^r;{ ist kleiner als erwartet."
+
+/* state of a boolean option */
+#define kStrOn "an"
+#define kStrOff "aus"
+
+/* state of a key */
+#define kStrPressed "gedr;uuckt"
+#define kStrReleased "losgelassen"
+
+/* state of Stopped */
+#define kStrStoppedOn kStrOn
+#define kStrStoppedOff kStrOff
+
+/* About Screen */
+#define kStrProgramInfo "^v"
+#define kStrSponsorIs "^v. This variation is made for:"
+#define kStrWorkOfMany "Copyright ^y. ^p enth;ualt die Arbeit mehrerer Personen. Diese Version wird gepflegt von:"
+#define kStrForMoreInfo "Mehr Informationen:"
+#define kStrLicense "^p wird unter den Bestimmungen der GNU Public License, Version 2, verbreitet."
+#define kStrDisclaimer " ^p wird angeboten in der Hoffnung, brauchbar zu sein, aber OHNE JEDE GARANTIE;ls gleichfalls ohne garantierte EIGNUNG ZU EINEM BESTIMMTEN ZWECK."
+
+/* Help Screen */
+#define kStrHowToLeaveControl "Um den Kontrollmodus zu verlassen, lassen Sie ;]^c;} los."
+#define kStrHowToPickACommand "Anderenfalls dr;uucken Sie einen dieser Buchstaben:"
+#define kStrCmdAbout "Informationen zu dieser Version"
+#define kStrCmdOpenDiskImage "Disketten-Image ;uoffnen;ll"
+#define kStrCmdQuit "Beenden"
+#define kStrCmdSpeedControl "Geschwindigkeitskontrolle;ll (^s)"
+#define kStrCmdMagnifyToggle "Vergr;uosserung (^g)"
+#define kStrCmdFullScrnToggle "Vollbild (^f)"
+#define kStrCmdCtrlKeyToggle "Emulierte ;]^m;}-Taste (^k)"
+#define kStrCmdReset "Neustarten (Reset durchf;uuhren)"
+#define kStrCmdInterrupt "Interrupt"
+#define kStrCmdHelp "Hilfe (zeigt diese Befehlsliste)"
+
+/* Speed Control Screen */
+#define kStrCurrentSpeed "Momentane Geschwindigkeit: ^s"
+#define kStrSpeedAllOut "H;uochstgeschwindigkeit"
+#define kStrSpeedStopped "^p jetzt anhalten (^h)"
+#define kStrSpeedBackToggle "^p im Hintergrund anhalten (^b)"
+#define kStrSpeedAutoSlowToggle "AutoSlow (^l)"
+#define kStrSpeedExit "Geschwindigkeits-Einstellungen verlassen"
+
+#define kStrNewSpeed "Neue Geschwindigkeit: ^s"
+#define kStrSpeedValueAllOut kStrSpeedAllOut
+
+#define kStrNewStopped "^p ist jetzt angehalten (^h)"
+#define kStrNewRunInBack "^p anhalten, wenn nicht aktiv (^b)"
+#define kStrNewAutoSlow "AutoSlow (^l)"
+
+#define kStrNewMagnify "Vergr;uo;serung ist ^g"
+
+#define kStrNewFullScreen "Vollbildmodus ist ^f"
+
+#define kStrNewCntrlKey "Emulierte ;]^m;}-Taste ^k"
+
+#define kStrCmdCancel "Abbrechen"
+
+#define kStrConfirmReset "Wollen Sie den emulierten Rechner wirklich neustarten? Ungesicherte ;uAnderungen werden verlorengehen und gemountete Disketten-Images k;uonnen besch;uadigt werden. Dr;uucken Sie einen dieser Buchstaben:"
+#define kStrResetDo "^p neustarten"
+#define kStrResetNo "Nicht neustarten"
+
+#define kStrHaveReset "Emulierter Rechner wurde zur;uuckgesetzt."
+
+#define kStrCancelledReset "Neustart wird nicht durchgef;uuhrt"
+
+#define kStrConfirmInterrupt "Interrupt f;uur diesen emulierten Rechner ausf;uuhren? Dies ruft alle implementierten Debugger auf. Dr;uucken Sie einen dieser Buchstaben:"
+#define kStrInterruptDo "Interrupt ausf;uuhren"
+#define kStrInterruptNo "Interrupt nicht ausf;uuhren"
+
+#define kStrHaveInterrupted "Interrupt wurde durchgef;uuhrt"
+
+#define kStrCancelledInterrupt "Interrupt wird nicht ausgef;uuhrt"
+
+#define kStrConfirmQuit "Wollen Sie ^p wirklich beenden? Sie sollten zuvor den emulierten Rechner herunterfahren, um Besch;uadigungen an gemounteten Disketten-Images zu vermeiden. Dr;uucken Sie einen dieser Buchstaben:"
+#define kStrQuitDo kStrCmdQuit
+#define kStrQuitNo "Nicht beenden"
+
+#define kStrCancelledQuit "^p wird nicht beendet"
+
+#define kStrModeConfirmReset "Kontrollmodus : Neustarten von ^p best;uatigen"
+#define kStrModeConfirmInterrupt "Kontrollmodus : Interrupt best;uatigen"
+#define kStrModeConfirmQuit "Kontrollmodus : Beenden von ^p best;uatigen"
+#define kStrModeSpeedControl "Kontrollmodus : Geschwindigkeitskontrolle"
+#define kStrModeControlBase "Kontrollmodus (Tippen Sie ;]H;}, um Hilfe zu erhalten)"
+#define kStrModeControlHelp "Kontrollmodus"
+#define kStrModeMessage "Mitteilung (Tippen Sie ;]C;}, um fortzusetzen)"
+
+#define kStrMenuFile "Ablage"
+#define kStrMenuFile_win "Datei"
+#define kStrMenuSpecial "Spezial"
+#define kStrMenuHelp "Hilfe"
+
+#define kStrMenuItemAbout ";uUber ^p"
+#define kStrMenuItemOpen "Disketten-Image ;uoffnen"
+#define kStrMenuItemQuit "Beenden"
+#define kStrMenuItemMore "Mehr Befehle"
+
+#define kStrAppMenuItemHide "^p ausblenden"
+#define kStrAppMenuItemHideOthers "Andere ausblenden"
+#define kStrAppMenuItemShowAll "Alle einblenden"
+#define kStrAppMenuItemQuit "^p beenden"
+
+#define kStrCntrlKyName "Control"
+#define kStrCmdCopyOptions "Variation options kopieren"
+#define kStrHaveCopiedOptions "Variation options kopiert"
--- /dev/null
+++ b/src/STRCNITA.h
@@ -1,0 +1,170 @@
+/*
+ STRCNITA.h
+
+ Copyright (C) 2006 Paul C. Pratt, Fabio Concas, Gianluca Abbiati
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ STRing CoNstants for ITAlian
+
+ These strings were originally translated by Fabio Concas, who
+ hasn't been heard from lately, and modifications were
+ needed for version 2.8.1. Gianluca Abbiati agreed to look
+ at it, and made numerous changes for version 2.8.2.
+*/
+
+#define kStrAboutTitle "Informazioni"
+#define kStrAboutMessage "Per visualizzare le informazioni su questo programma usa il comando ;]A;} dalla Modalit;`a Controllo di ^p. Per informazioni sulla Modalit;`a Controllo, vedi ;[Ulteriori Comandi;ll;{ nel men;`u ;[Speciale;{."
+
+#define kStrMoreCommandsTitle "Ulteriori comandi sono disponibili nella Modalit;`a Controllo di ^p."
+#define kStrMoreCommandsMessage "Per entrare nella Modalit;`a Controllo, premi e tieni premuto il tasto ;]^c;}. La Modalit;`a Controllo rester;`a attiva fino a che il tasto ;]^c;} non verr;`a rilasciato. Digita ;]H;} nella Modalit;`a Controllo per avere la lista dei comandi disponibili."
+
+#define kStrTooManyImagesTitle "Troppe Immagini Disco."
+#define kStrTooManyImagesMessage "Non posso montare altre Immagini Disco. Prova ad espellerne una."
+
+#define kStrImageInUseTitle "Immagine Disco in uso."
+#define kStrImageInUseMessage "Non posso montare l;}Immagine Disco perch;ee ;`e utilizzata da un;}altra applicazione."
+
+#define kStrOutOfMemTitle "Memoria insufficiente."
+#define kStrOutOfMemMessage "Non c;};`e abbastanza memoria per avviare ^p."
+
+#define kStrNoROMTitle "Impossibile trovare l;}immagine della ROM."
+#define kStrNoROMMessage "Non trovo il file immagine della ROM ;[^r;{. Per maggiori informazioni, vedi: ;[^w;{"
+
+#define kStrCorruptedROMTitle "Checksum della ROM fallita."
+#define kStrCorruptedROMMessage "L;}immagine della ROM ;[^r;{ potrebbe essere danneggiata."
+
+#define kStrUnsupportedROMTitle "ROM non supportata."
+#define kStrUnsupportedROMMessage "Il file immagine della ROM ;[^r;{ ;`e stato caricato, ma ^p non supporta ancora questa ROM."
+
+#define kStrQuitWarningTitle "Dovresti spegnere la macchina emulata prima di uscire."
+#define kStrQuitWarningMessage "Per forzare l;}uscita da ^p (col rischio di danneggiare le immagini disco montate), usa il comando ;]Q;} dalla Modalit;`a Controllo di ^p. Per informazioni sulla Modalit;`a Controllo, vedi ;[Ulteriori Comandi;ll;{ nel men;`u ;[Speciale;{."
+
+#define kStrReportAbnormalTitle "Situazione Anomala"
+#define kStrReportAbnormalMessage "La macchina emulata sta tentando un;}operazione inaspettata nell;}uso normale."
+
+#define kStrBadArgTitle "Argomento sconosciuto."
+#define kStrBadArgMessage "Non comprendo uno dei parametri della riga di comando, lo ignoro."
+
+#define kStrOpenFailTitle "Apertura fallita."
+#define kStrOpenFailMessage "Non posso aprire l;}immagine disco."
+
+#define kStrNoReadROMTitle "Non posso leggere l;}immagine della ROM."
+#define kStrNoReadROMMessage "Ho trovato l;}immagine della ROM ;[^r;{, ma non posso leggerla."
+
+#define kStrShortROMTitle "L;}immagine della ROM ;`e troppo piccola."
+#define kStrShortROMMessage "Il file immagine della ROM ;[^r;{ ;`e pi;`u piccolo di quanto dovrebbe essere."
+
+/* state of a boolean option */
+#define kStrOn "attivo"
+#define kStrOff "inattivo"
+
+/* state of a key */
+#define kStrPressed "premuto"
+#define kStrReleased "rilasciato"
+
+/* state of Stopped */
+#define kStrStoppedOn kStrOn
+#define kStrStoppedOff kStrOff
+
+/* About Screen */
+#define kStrProgramInfo "^v"
+#define kStrSponsorIs "^v. This variation is made for:"
+#define kStrWorkOfMany "Copyright ^y. ^p contiene il lavoro di molte persone. Questa versione ;`e mantenuta da:"
+#define kStrForMoreInfo "Per maggiori informazioni, vedi:"
+#define kStrLicense "^p ;`e distribuito secondo i termini della Licenza Pubblica GNU, versione 2."
+#define kStrDisclaimer " ^p ;`e distribuito con la speranza che sia utile, ma SENZA ALCUNA GARANZIA;ls compresa la garanzia implicita di COMMERCIABILIT;`A o IDONEIT;`A PER UN QUALSIASI SCOPO."
+
+/* Help Screen */
+#define kStrHowToLeaveControl "Per uscire dalla Modalit;`a Controllo, rilascia il tasto ;]^c;}."
+#define kStrHowToPickACommand "Altrimenti premi una lettera. I comandi disponibili sono:"
+#define kStrCmdAbout "Informazioni (informazioni sulla versione)"
+#define kStrCmdOpenDiskImage "Apri immagine disco;ll"
+#define kStrCmdQuit "Esci"
+#define kStrCmdSpeedControl "Controllo velocit;`a;ll (^s)"
+#define kStrCmdMagnifyToggle "Ingrandimento (^g)"
+#define kStrCmdFullScrnToggle "Schermo intero (^f)"
+#define kStrCmdCtrlKeyToggle "Tasto ;]^m;} emulato (^k)"
+#define kStrCmdReset "Reset"
+#define kStrCmdInterrupt "Interrupt"
+#define kStrCmdHelp "Aiuto (mostra questo messaggio)"
+
+/* Speed Control Screen */
+#define kStrCurrentSpeed "Velocit;`a attuale: ^s"
+#define kStrSpeedAllOut "Massima velocit;`a"
+#define kStrSpeedStopped "Stop (^h)"
+#define kStrSpeedBackToggle "Funzionamento in background (^b)"
+#define kStrSpeedAutoSlowToggle "AutoSlow (^l)"
+#define kStrSpeedExit "Esci da Controllo Velocit;`a"
+
+#define kStrNewSpeed "Velocit;`a: ^s"
+#define kStrSpeedValueAllOut "Massima"
+
+#define kStrNewStopped "Lo stop ;`e ^h"
+#define kStrNewRunInBack "Il funzionamento in background ;`e ^b"
+#define kStrNewAutoSlow "AutoSlow ;`e ^l."
+
+#define kStrNewMagnify "L;laingrandimento ;`e ^g"
+
+#define kStrNewFullScreen "Lo schermo intero ;`e ^f"
+
+#define kStrNewCntrlKey "Il tasto ;]^m;} emulato ;`e ^k"
+
+#define kStrCmdCancel "Annulla"
+
+#define kStrConfirmReset "Sei sicuro di voler resettare la macchina emulata? Le modifiche non salvate andranno perse e le immagini disco montate potrebbero venire danneggiate. Premi una lettera:"
+#define kStrResetDo kStrCmdReset
+#define kStrResetNo kStrCmdCancel
+
+#define kStrHaveReset "La macchina emulata ;`e stata resettata"
+
+#define kStrCancelledReset "Reset annullato"
+
+#define kStrConfirmInterrupt "Sei sicuro di voler eseguire l;laInterrupt della macchina emulata? Questo avvier;`a il debugger installato nel tuo sistema. Premi una lettera:"
+#define kStrInterruptDo kStrCmdInterrupt
+#define kStrInterruptNo kStrCmdCancel
+
+#define kStrHaveInterrupted "Interrupt della macchina emulata eseguito"
+
+#define kStrCancelledInterrupt "Interrupt annullato"
+
+#define kStrConfirmQuit "Sei sicuro di voler uscire? Dovresti spegnere la macchina emulata prima di uscire da ^p per prevenire potenziali danni alle immagini disco montate. Premi una lettera:"
+#define kStrQuitDo kStrCmdQuit
+#define kStrQuitNo kStrCmdCancel
+
+#define kStrCancelledQuit "Uscita annullata"
+
+#define kStrModeConfirmReset "Modalit;`a Controllo : Conferma Riavviare"
+#define kStrModeConfirmInterrupt "Modalit;`a Controllo : Conferma l;}Interrupt"
+#define kStrModeConfirmQuit "Modalit;`a Controllo : Conferma Uscire"
+#define kStrModeSpeedControl "Modalit;`a Controllo : Controllo Velocit;`a"
+#define kStrModeControlBase "Modalit;`a Controllo (Digita ;]H;} per l;}aiuto)"
+#define kStrModeControlHelp "Modalit;`a Controllo"
+#define kStrModeMessage "Messaggio (Digita ;]C;} per continuare)"
+
+#define kStrMenuFile "Archivio"
+#define kStrMenuSpecial "Speciale"
+#define kStrMenuHelp "Aiuto"
+
+#define kStrMenuItemAbout "Informazioni su ^p"
+#define kStrMenuItemOpen "Apri Immagine Disco"
+#define kStrMenuItemQuit "Esci"
+#define kStrMenuItemMore "Altri Comandi"
+
+#define kStrAppMenuItemHide "Nascondi ^p"
+#define kStrAppMenuItemHideOthers "Nascondi altre"
+#define kStrAppMenuItemShowAll "Mostra tutte"
+#define kStrAppMenuItemQuit "Esci da ^p"
+
+#define kStrCmdCopyOptions "Copia variation options"
+#define kStrHaveCopiedOptions "Variation options copiate"
--- /dev/null
+++ b/src/STRCNPOL.h
@@ -1,0 +1,168 @@
+/*
+ STRCNPOL.h
+
+ Copyright (C) 2012 Przemys;dlaw Buczkowski, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ STRing CoNstants for POLish
+
+ These strings were translated by Przemys;dlaw Buczkowski.
+*/
+
+#define kStrAboutTitle "O programie;ll"
+#define kStrAboutMessage "Aby obejrze;ec informacje o tym programie u;dzyj komendy ;]A;} w ^p Trybie Kontroli. Aby dowiedzie;ec si;de wi;decej o tym trybie kliknij przycisk ;[Wi;decej komend;ll;{ w menu ;[Specjalne;{."
+
+#define kStrMoreCommandsTitle "Wi;decej komend jest dost;depnych w ^p Trybie Kontroli."
+#define kStrMoreCommandsMessage "Aby wej;es;ec w Tryb Kontroli przytrzymaj przycisk ^c. Pozostaniesz w Trybie Kontroli dop;eoki nie pu;escisz tego klawisza. Kliknij H aby wy;eswietli;ec Pomoc."
+
+#define kStrTooManyImagesTitle "Za du;dzo obraz;eow dysk;eow"
+#define kStrTooManyImagesMessage "Nie mog;de zamontowa;ec tylu dysk;eow. Odmontowywanie jednego."
+
+#define kStrImageInUseTitle "Obraz w u;dzyciu"
+#define kStrImageInUseMessage "Nie mog;de zamontowa;ec tego dysku poniewa;dz jest on u;dzywany przez inn;da aplikacj;de lub uruchomiony w ^p."
+
+#define kStrOutOfMemTitle "Za ma;dlo pami;deci"
+#define kStrOutOfMemMessage "Mam za ma;dlo pami;deci aby uruchomi;ec ^p."
+
+#define kStrNoROMTitle "Nie uda;dlo si;de zlokalizowa;ec ROMu"
+#define kStrNoROMMessage "Nie mog;de znale;ez;ec ROMu ;[^r;{. Aby dowiedzie;ec si;de wi;decej, zobacz: ;[^w;{."
+
+#define kStrCorruptedROMTitle "ROM uszkodzony"
+#define kStrCorruptedROMMessage "Plik ROMu ;[^r;{ mo;dze by;ec uszkodzony."
+
+#define kStrUnsupportedROMTitle "Niewspierany ROM"
+#define kStrUnsupportedROMMessage "ROM ;[^r;{ zosta;dl za;dladowany, ale nie obs;dluguj;de tej wersji."
+
+#define kStrQuitWarningTitle "Prosz;de wy;dl;daczy;ec emulowany komputer przed wyj;esciem."
+#define kStrQuitWarningMessage "Aby wymusi;ec wyj;escie ryzykuj;dac uszkodzenie obraz;eow dysk;eow u;dzyj komendy ;]Q;} w Trybie Kontroli. Aby dowiedzie;ec si;de wi;decej o tym trybie kliknij przycisk ;[Wi;decej komend;ll;{ w menu ;[Specjalne;{."
+
+#define kStrReportAbnormalTitle "Nienormalne polecenie"
+#define kStrReportAbnormalMessage "Emulowany komputer pr;eobowa;dl zrobi;ec co;es, co nie powinno si;de zdarzy;ec."
+
+#define kStrBadArgTitle "Z;dly argument"
+#define kStrBadArgMessage "Nie zrozumia;dlem podanego argumentu."
+
+#define kStrOpenFailTitle "B;dl;dad otwierania"
+#define kStrOpenFailMessage "Nie mog;de otworzy;ec obrazu dysku."
+
+#define kStrNoReadROMTitle "Nieudane otwarcie ROMu"
+#define kStrNoReadROMMessage "Znalaz;dlem plik ROMu ;[^r;{, ale nie mog;de go otworzy;ec."
+
+#define kStrShortROMTitle "Za ma;dly ROM"
+#define kStrShortROMMessage "Plik ROMu ;[^r;{ jest mniejszy ni;dz powinien by;ec."
+
+/* state of a boolean option */
+#define kStrOn "w;dl;daczone"
+#define kStrOff "wy;dl;daczone"
+
+/* state of a key */
+#define kStrPressed "wci;esni;dety"
+#define kStrReleased "puszczony"
+
+/* state of Stopped */
+#define kStrStoppedOn kStrOn
+#define kStrStoppedOff kStrOff
+
+/* About Screen */
+#define kStrProgramInfo "^v"
+#define kStrSponsorIs "^v. This variation is made for:"
+#define kStrWorkOfMany "Copyright ^y. ^p jest wynikiem pracy wielu os;eob. Ta wersja jest zarz;dadzana przez:"
+#define kStrForMoreInfo "Po wi;decej informacji zobacz:"
+#define kStrLicense "^p jest dystrybuowany na licencji GNU General Public License 2."
+#define kStrDisclaimer " ^p is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;ls without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+/* Help Screen */
+#define kStrHowToLeaveControl "Aby opu;esci;ec Tryb Kontroli pu;es;ec klawisz ^c."
+#define kStrHowToPickACommand "Naci;esnij liter;de. Dost;depne komendy to:"
+#define kStrCmdAbout "O programie (szczeg;eo;dly wersji);ll"
+#define kStrCmdOpenDiskImage "Otw;eorz obraz dysku;ll"
+#define kStrCmdQuit "Wyjd;ez"
+#define kStrCmdSpeedControl "Kontrola szybko;esci;ll (^s)"
+#define kStrCmdMagnifyToggle "Skalowanie (^g)"
+#define kStrCmdFullScrnToggle "Pe;dlny ekran (^f)"
+#define kStrCmdCtrlKeyToggle "Emulowany klawisz ^m (^k)"
+#define kStrCmdReset "Reset"
+#define kStrCmdInterrupt "Przerwanie"
+#define kStrCmdHelp "Pomoc (ta strona)"
+
+/* Speed Control Screen */
+#define kStrCurrentSpeed "Obecna pr;dedko;es;ec: ^s"
+#define kStrSpeedAllOut "Ca;dla naprz;eod!"
+#define kStrSpeedStopped "Zatrzymanie (^h)"
+#define kStrSpeedBackToggle "Uruchamianie w tle (^b)"
+#define kStrSpeedAutoSlowToggle "AutoSlow (^l)"
+#define kStrSpeedExit "Wyj;escie z kontroli pr;dedko;esci"
+
+#define kStrNewSpeed "Pr;dedko;es;ec: ^s"
+#define kStrSpeedValueAllOut kStrSpeedAllOut
+
+#define kStrNewStopped "Zatrzymanie jest ^h."
+#define kStrNewRunInBack "Uruchomienie w tle ^b."
+#define kStrNewAutoSlow "AutoSlow jest ^g."
+
+#define kStrNewMagnify "Powi;dekszenie jest ^g."
+
+#define kStrNewFullScreen "Pe;dlny ekran jest ^f."
+
+#define kStrNewCntrlKey "Emulowany klawiszem ^m jest ^k."
+
+#define kStrCmdCancel "anuluj"
+
+#define kStrConfirmReset "Czy na pewno chcesz zresetowa;ec emulator? Zmiany nie zostan;da zapisane, istnieje ryzyko uszkodzenia obraz;eow dysk;eow. Podaj liter;de:"
+#define kStrResetDo "reset"
+#define kStrResetNo kStrCmdCancel
+
+#define kStrHaveReset "Zresetowano komputer."
+
+#define kStrCancelledReset "Reset anulowany."
+
+#define kStrConfirmInterrupt "Czy jeste;es pewny aby wywo;dla;ec przerwanie emulatora? Podaj liter;de:"
+#define kStrInterruptDo "przerwanie"
+#define kStrInterruptNo kStrCmdCancel
+
+#define kStrHaveInterrupted "Wywo;dlano przerwanie komputera."
+
+#define kStrCancelledInterrupt "Przerwanie anulowane."
+
+#define kStrConfirmQuit "Czy na pewno chcesz wy;dl;daczy;ec komputer ^p? Zmiany nie zostan;da zapisane, istnieje ryzyko uszkodzenia obraz;eow dysk;eow. Podaj liter;de:"
+#define kStrQuitDo "wyjd;ez"
+#define kStrQuitNo kStrCmdCancel
+
+#define kStrCancelledQuit "Wyj;escie anulowane"
+
+#define kStrModeConfirmReset "Tryb Kontroli : Potwierd;ez reset"
+#define kStrModeConfirmInterrupt "Tryb Kontroli : Potwierd;ez przerwanie"
+#define kStrModeConfirmQuit "Tryb Kontroli : Potwierd;ez wyj;escie"
+#define kStrModeSpeedControl "Tryb Kontroli : Kontrola pr;dedko;esci"
+#define kStrModeControlBase "Tryb Kontroli (wci;esnij ;]H;} po pomoc)"
+#define kStrModeControlHelp "Tryb Kontroli"
+#define kStrModeMessage "Wiadomo;es;ec (kliknij ;]C;} aby kontynuowa;ec)"
+
+#define kStrMenuFile "Plik"
+#define kStrMenuSpecial "Specjalne"
+#define kStrMenuHelp "Pomoc"
+
+#define kStrMenuItemAbout "O;ll ^p"
+#define kStrMenuItemOpen "Otw;eorz obraz dysku"
+#define kStrMenuItemQuit "Pomoc"
+#define kStrMenuItemMore "Wi;decej komend"
+
+#define kStrAppMenuItemHide "Ukryj ^p"
+#define kStrAppMenuItemHideOthers "Ukryj pozosta;dle"
+#define kStrAppMenuItemShowAll "Poka;dz wszystkie"
+#define kStrAppMenuItemQuit "Zako;encz ^p"
+
+#define kStrCntrlKyName "Control"
+#define kStrCmdCopyOptions "Kopiuj variation options"
+#define kStrHaveCopiedOptions "Variation options kopiowane"
--- /dev/null
+++ b/src/STRCNPTB.h
@@ -1,0 +1,211 @@
+/*
+ STRCNPTB.h
+
+ Copyright (C) 2017 Mauricio, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ STRing CoNstants for PorTuguese-Brazilian
+
+ These strings were translated by Mauricio.
+*/
+
+#define kStrAboutTitle "Sobre"
+
+#define kStrAboutMessage "Para exibir informa;c;noes sobre este programa, use o comando ;]A;} do Modo de Controle ^p. Para saber mais sobre o Modo de Controle, consulte o item ;[Mais Comandos;ll;{ no menu ;[Especial;{."
+
+#define kStrMoreCommandsTitle "Mais comandos est;nao dispon;eiveis no Modo de Controle ^p."
+
+#define kStrMoreCommandsMessage "Para entrar no Modo de Controle, pressione e mantenha pressionada a tecla ;]^c;}, voc;ie permanecer;ea no Modo de Controle at;ee que voc;ie solte a tecla ;]^c;}. Digite 'H' no Modo de Controle para listar os comandos dispon;eiveis."
+
+#define kStrTooManyImagesTitle "Imagens de Disco excedidas"
+
+#define kStrTooManyImagesMessage "N;nao consigo montar tantas Imagens de Disco. Tente ejetar alguma."
+
+#define kStrImageInUseTitle "Imagem de Disco em uso"
+
+#define kStrImageInUseMessage "N;nao consigo montar a imagem de disco porque ela j;ea est;ea em uso por outro aplicativo ou j;ea est;ea aberta em ^p."
+
+#define kStrOutOfMemTitle "Mem;eoria insuficiente"
+
+#define kStrOutOfMemMessage "N;nao h;ea mem;eoria suficiente dispon;eivel para iniciar ^p."
+
+#define kStrNoROMTitle "N;nao ;ee poss;eivel localizar a imagem ROM"
+
+#define kStrNoROMMessage "N;nao consigo encontrar o arquivo de imagem ROM ;[^r;{. Para obter mais informa;c;noes, consulte: ;[^w;{."
+
+#define kStrCorruptedROMTitle "Falha no checksum da ROM"
+
+#define kStrCorruptedROMMessage "O arquivo de imagem ROM ;[^r;{ pode estar corrompido."
+
+#define kStrUnsupportedROMTitle "ROM n;nao suportada"
+
+#define kStrUnsupportedROMMessage "O arquivo de imagem ROM ;[^r;{ foi carregado com ;iexito, mas n;nao suportamos esta vers;nao ROM."
+
+#define kStrQuitWarningTitle "Por favor, desligue o computador emulado antes de fechar."
+
+#define kStrQuitWarningMessage "To force ^p to quit, at the risk of corrupting the mounted disk image files, use the ;]Q;} command of the ^p Control Mode. To learn about the Control Mode, see the ;[More Commands;ll;{ item in the ;[Special;{ menu."
+
+#define kStrReportAbnormalTitle "Situa;c;nao Anormal"
+
+#define kStrReportAbnormalMessage "O computador emulado est;ea tentando uma opera;c;nao que n;nao era esperada para acontecer em uso normal."
+
+#define kStrBadArgTitle "Argumento desconhecido"
+
+#define kStrBadArgMessage "Eu n;nao entendi um dos argumentos da linha de comando e ignorei-o."
+
+#define kStrOpenFailTitle "Falha ao abrir"
+
+#define kStrOpenFailMessage "N;nao consegui abrir a imagem do disco."
+
+#define kStrNoReadROMTitle "N;nao ;ee poss;eivel ler a imagem ROM"
+
+#define kStrNoReadROMMessage "Eu encontrei o arquivo de imagem ROM ;[^r;{, mas n;nao consigo l;ie-lo."
+
+#define kStrShortROMTitle "Imagem da ROM muito pequena"
+
+#define kStrShortROMMessage "O arquivo de imagem ROM ;[^r;{ ;ee menor do que deveria ser."
+
+/* state of a boolean option */
+#define kStrOn "Ligado"
+#define kStrOff "Desligado"
+
+/* state of a key */
+#define kStrPressed "Ligada"
+#define kStrReleased "Desligada"
+
+/* state of Stopped */
+#define kStrStoppedOn kStrOn
+#define kStrStoppedOff kStrOff
+
+/* About Screen */
+#define kStrProgramInfo "^v"
+
+#define kStrSponsorIs "^v. Esta varia;c;nao ;ee patrocinada por:"
+
+#define kStrWorkOfMany "Copyright ^y. ^p cont;eem o trabalho de muitas pessoas. Esta vers;nao ;ee mantida por:"
+
+#define kStrForMoreInfo "Para obter mais informa;c;noes, consulte:"
+
+#define kStrLicense "^p ;ee distribu;eido sob os termos da Licen;ca P;eublica GNU, vers;nao 2."
+
+#define kStrDisclaimer " ^p ;ee distribu;eido com a esperan;ca de que ser;ea ;eutil, mas SEM NENHUMA GARANTIA, sem sequer a garantia impl;eicita de COMERCIALIZA;C;nAO ou ADEQUA;C;nAO A UM DETERMINADO PROP;eOSITO."
+
+/* Help Screen */
+#define kStrHowToLeaveControl "Para sair do modo de controle, solte a tecla ;]^c;}."
+
+#define kStrHowToPickACommand "Caso contr;eario, digite uma letra. Comandos dispon;eiveis:"
+
+#define kStrCmdAbout "Sobre (informa;c;noes sobre a vers;nao)"
+
+#define kStrCmdOpenDiskImage "Abrir imagem de disco;ll"
+
+#define kStrCmdQuit "Sair"
+
+#define kStrCmdSpeedControl "Controle de velocidade;ll (^s)"
+
+#define kStrCmdMagnifyToggle "Zoom (^g)"
+
+#define kStrCmdFullScrnToggle "Tela Cheia (^f)"
+
+#define kStrCmdCtrlKeyToggle "Alternar Tecla ;]^m;} emulada (^k)"
+
+#define kStrCmdReset "Reiniciar"
+
+#define kStrCmdInterrupt "Interromper"
+
+#define kStrCmdHelp "Ajuda (mostrar esta p;eagina)"
+
+/* Speed Control Screen */
+#define kStrCurrentSpeed "Velocidade atual: ^s"
+
+#define kStrSpeedAllOut "Toda a velocidade"
+
+#define kStrSpeedStopped "parado (^h)"
+
+#define kStrSpeedBackToggle "Rodar em Segundo Plano (^b)"
+
+#define kStrSpeedAutoSlowToggle "Lentid;nao Autom;eatica (^l)"
+
+#define kStrSpeedExit "Sair do controle de velocidade"
+
+#define kStrNewSpeed "Velocidade: ^s"
+
+#define kStrSpeedValueAllOut kStrSpeedAllOut
+
+#define kStrNewStopped "Parado est;ea ^h."
+
+#define kStrNewRunInBack "Rodar em segundo plano est;ea ^b."
+
+#define kStrNewAutoSlow "Lentid;nao Autom;eatica est;ea ^l."
+
+#define kStrNewMagnify "Zoom est;ea ^g."
+
+#define kStrNewFullScreen "Tela Cheia est;ea ^f."
+
+#define kStrNewCntrlKey "Emula;c;nao da tecla ;]^m;} ^k."
+
+#define kStrCmdCancel "cancelar"
+
+#define kStrConfirmReset "Tem certeza de que deseja reiniciar o computador emulado? As altera;c;noes n;nao salvas ser;nao perdidas e h;ea o risco de corromper os arquivos de imagem de disco montados. Digite uma letra:"
+
+#define kStrResetDo "reiniciar"
+
+#define kStrResetNo kStrCmdCancel
+
+#define kStrHaveReset "Reiniciar o computador emulado"
+
+#define kStrCancelledReset "Reinicializa;c;nao cancelada"
+
+#define kStrConfirmInterrupt "Tem certeza de que deseja interromper o computador emulado? Isso invocar;ea qualquer depurador instalado. Digite uma letra:"
+
+#define kStrInterruptDo "Interromper"
+
+#define kStrInterruptNo kStrCmdCancel
+
+#define kStrHaveInterrupted "Interrompeu o computador emulado"
+
+#define kStrCancelledInterrupt "Interrup;c;nao cancelada"
+
+#define kStrConfirmQuit "Tem certeza de que deseja sair ^p? Voc;ie deve desligar o computador emulado antes de sair para evitar corromper os arquivos de imagem de disco montados. Digite uma letra:"
+
+#define kStrQuitDo "sair"
+
+#define kStrQuitNo kStrCmdCancel
+
+#define kStrCancelledQuit "Opera;c;nao cancelada"
+
+#define kStrModeConfirmReset "Modo de Controle : Confirmar Reinicializa;c;nao"
+#define kStrModeConfirmInterrupt "Modo de Controle : Confirmar Interrup;c;nao"
+#define kStrModeConfirmQuit "Modo de Controle : Confirmar Sair"
+#define kStrModeSpeedControl "Modo de Controle : Controle de Velocidade"
+#define kStrModeControlBase "Modo de Controle (Digite ;]H;} para obter ajuda)"
+#define kStrModeControlHelp "Modo de Controle"
+#define kStrModeMessage "Message (Digite ;]C;} para continuar)"
+
+#define kStrMenuFile "Arquivo"
+#define kStrMenuSpecial "Especial"
+#define kStrMenuHelp "Ajuda"
+
+#define kStrMenuItemAbout "Sobre ^p"
+#define kStrMenuItemOpen "Open Disk Image"
+#define kStrMenuItemQuit "Sair"
+#define kStrMenuItemMore "Mais Comandos"
+
+#define kStrAppMenuItemHide "Esconder ^p"
+#define kStrAppMenuItemHideOthers "Esconder Outras"
+#define kStrAppMenuItemShowAll "Mostrar Todas"
+#define kStrAppMenuItemQuit "Sair ^p"
+
+#define kStrCmdCopyOptions "Copiar variation options"
+#define kStrHaveCopiedOptions "Variation options copiadas"
--- /dev/null
+++ b/src/STRCNSPA.h
@@ -1,0 +1,167 @@
+/*
+ STRCNSPA.h
+
+ Copyright (C) 2006 Chir, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ STRing CoNstants for SPAnish
+
+ These strings were translated by Chir.
+*/
+
+#define kStrAboutTitle "Acerca de"
+#define kStrAboutMessage "Para mostrar informaci;eon acerca de este programa, use el comando ;]A;} del ^p Modo Control. Para saber m;eas acerca del Modo Control, vea ;[Mas Comandos;ll;{ en el menu ;[Especial;{ ."
+
+#define kStrMoreCommandsTitle "M;eas comandos est;ean disponibles en el modo de control de ^p ."
+#define kStrMoreCommandsMessage "Para entrar en el modo de control, mantenga pulsada la tecla ;]^c;} . Seguir;ea en el modo control hasta que suelte la tecla ;]^c;} . Pulse ;]H;} en el modo control para listar los comandos disponibles."
+
+#define kStrTooManyImagesTitle "Demasiadas im;eagenes de disco"
+#define kStrTooManyImagesMessage "No se pueden montar tantas im;eagenes de disco. Intente sacar alguna."
+
+#define kStrImageInUseTitle "Imagen disco en uso"
+#define kStrImageInUseMessage "No se puede montar la imagen disco porque ya est;ea en uso por otra aplicaci;eon, o ya abierta en ^p."
+
+#define kStrOutOfMemTitle "Memoria insuficiente"
+#define kStrOutOfMemMessage "No hay suficiente memoria disponible para lanzar ^p."
+
+#define kStrNoROMTitle "Imposible localizar la imagen ROM"
+#define kStrNoROMMessage "No se encuentra la imagen del fichero ROM ;[^r;{. Para m;eas informaci;eon, ver: ;[^w;{."
+
+#define kStrCorruptedROMTitle "El control checksum de la ROM ha fracasado"
+#define kStrCorruptedROMMessage "El fichero de imagen ROM ;[^r;{ puede estar corrompido."
+
+#define kStrUnsupportedROMTitle "ROM no soportada"
+#define kStrUnsupportedROMMessage "Fichero de imagen ROM ;[^r;{ cargado con ;eexito, pero esa versi;eon no est;ea soportada."
+
+#define kStrQuitWarningTitle "Por favor, apague el ordenador emulado antes de salir."
+#define kStrQuitWarningMessage "Para forzar ^p salir, con riesgo de corrupci;eon en las im;eagenes de discos montadas, use el comando ;]Q;} del ^p Modo Control. Para saber m;eas acerca del Modo Control, vea ;[Mas Comandos;ll;{ en el menu ;[Especial;{ ."
+
+#define kStrReportAbnormalTitle "Situaci;eon anormal"
+#define kStrReportAbnormalMessage "El ordenador emulado intenta hacer una operaci;eon no esperada en un uso normal."
+
+#define kStrBadArgTitle "Argumento desconocido"
+#define kStrBadArgMessage "No se comprendi;eo alguno de los argumentos de la linea de comandos, y se ignor;eo."
+
+#define kStrOpenFailTitle "Apertura fracasada"
+#define kStrOpenFailMessage "No se pudo abrir la imagen disco."
+
+#define kStrNoReadROMTitle "No se puede abrir la imagen ROM"
+#define kStrNoReadROMMessage "Se encontr;eo el fichero de imagen ROM ;[^r;{, pero no se pudo leer."
+
+#define kStrShortROMTitle "Imagen ROM demasiado corta"
+#define kStrShortROMMessage "El fichero de imagen ROM ;[^r;{ es m;eas corto de lo que deber;eia."
+
+/* state of a boolean option */
+#define kStrOn "activado"
+#define kStrOff "desactivado"
+
+/* state of a key */
+#define kStrPressed "pulsada"
+#define kStrReleased "soltada"
+
+/* state of Stopped */
+#define kStrStoppedOn kStrOn
+#define kStrStoppedOff kStrOff
+
+/* About Screen */
+#define kStrProgramInfo "^v"
+#define kStrSponsorIs "^v. This variation is made for:"
+#define kStrWorkOfMany "Copyright ^y. ^p contiene el trabajo de muchas personas. Esta versi;eon es mantenida por:"
+#define kStrForMoreInfo "Para m;eas informaci;eon, vea:"
+#define kStrLicense "^p es distribuido bajo los t;eerminos de la licencia p;eublica GNU, versi;eon 2."
+#define kStrDisclaimer " ^p es distribuido con la esperanza de ser ;eutil, pero SIN NINGUNA GARANTIA;ls incluso sin la garant;eia impl;eicita de MERCANTIBILIDAD O ADECUACION PARA UN USO PARTICULAR."
+
+/* Help Screen */
+#define kStrHowToLeaveControl "Para salir del Modo Control, suelte la tecla ;]^c;} ."
+#define kStrHowToPickACommand "Sin;eo, pulse una letra. Los comandos disponibles son:"
+#define kStrCmdAbout "Acerca de (informaci;eon sobre versi;eon)"
+#define kStrCmdOpenDiskImage "Abrir imagen disco;ll"
+#define kStrCmdQuit "Salir"
+#define kStrCmdSpeedControl "Control de velocidad;ll (^s)"
+#define kStrCmdMagnifyToggle "Magnificaci;eon (^g)"
+#define kStrCmdFullScrnToggle "Pantalla completa (^f)"
+#define kStrCmdCtrlKeyToggle "Toggle emulaci;eon tecla ;]^m;} (^k)"
+#define kStrCmdReset "Reset"
+#define kStrCmdInterrupt "Interrumpir"
+#define kStrCmdHelp "Ayuda (mostrar esta p;eagina)"
+
+/* Speed Control Screen */
+#define kStrCurrentSpeed "Velocidad actual: ^s"
+#define kStrSpeedAllOut "M;eaxima velocidad"
+#define kStrSpeedStopped "Stop (^h)"
+#define kStrSpeedBackToggle "Ejecutar en segundo plano (^b)"
+#define kStrSpeedAutoSlowToggle "AutoSlow (^l)"
+#define kStrSpeedExit "Salir del control de velocidad"
+
+#define kStrNewSpeed "Velocidad: ^s"
+#define kStrSpeedValueAllOut kStrSpeedAllOut
+
+#define kStrNewStopped "Stop est;ea ^h."
+#define kStrNewRunInBack "Ejecutar en segundo plano est;ea ^b."
+#define kStrNewAutoSlow "AutoSlow est;ea ^l."
+
+#define kStrNewMagnify "Magnificaci;eon est;ea ^g."
+
+#define kStrNewFullScreen "Pantalla completa est;ea ^f."
+
+#define kStrNewCntrlKey "Emulado tecla ;]^m;} ^k."
+
+#define kStrCmdCancel "cancelar"
+
+#define kStrConfirmReset "Est;ea seguro de desear reiniciar el ordenador emulado? Los cambios no salvados se perderan, y existe riesgo de corrupci;eon en las im;eagenes de discos montadas. Pulse una tecla:"
+#define kStrResetDo "reset"
+#define kStrResetNo kStrCmdCancel
+
+#define kStrHaveReset "Se ha reiniciado el ordenador emulado"
+
+#define kStrCancelledReset "Reset cancelado"
+
+#define kStrConfirmInterrupt "Est;ea seguro de desear interrumpir el ordenador emulado? Esto invocar;ea cualquier debugger instalado. Pulse una tecla:"
+#define kStrInterruptDo "interrumpir"
+#define kStrInterruptNo kStrCmdCancel
+
+#define kStrHaveInterrupted "Se ha interrumpido el ordenador emulado"
+
+#define kStrCancelledInterrupt "Interrupci;eon cancelada"
+
+#define kStrConfirmQuit "Est;ea seguro de desear salir de ^p? Deber;eia apagar el ordenador emulado antes de salir, para evitar corrupciones en las im;eagenes de discos montadas. Pulse una tecla:"
+#define kStrQuitDo "salir"
+#define kStrQuitNo kStrCmdCancel
+
+#define kStrCancelledQuit "Salida cancelada"
+
+#define kStrModeConfirmReset "Modo Control : Confirmar reset"
+#define kStrModeConfirmInterrupt "Modo Control : Confirmar Interrupci;eon"
+#define kStrModeConfirmQuit "Modo Control : Confirmar salida"
+#define kStrModeSpeedControl "Modo Control : Control de velocidad"
+#define kStrModeControlBase "Modo Control (Pulse ;]H;} para la ayuda)"
+#define kStrModeControlHelp "Modo Control"
+#define kStrModeMessage "Mensaje (Pulse ;]C;} para continuar)"
+
+#define kStrMenuFile "Fichero"
+#define kStrMenuSpecial "Especial"
+#define kStrMenuHelp "Ayuda"
+
+#define kStrMenuItemAbout "Acerca de ^p"
+#define kStrMenuItemOpen "Abrir imagen disco"
+#define kStrMenuItemQuit "Salir"
+#define kStrMenuItemMore "M;eas comandos"
+
+#define kStrAppMenuItemHide "Ocultar ^p"
+#define kStrAppMenuItemHideOthers "Ocultar otros"
+#define kStrAppMenuItemShowAll "Mostrar todo"
+#define kStrAppMenuItemQuit "Salir de ^p"
+
+#define kStrCmdCopyOptions "Copiar variation options"
+#define kStrHaveCopiedOptions "Variation options copiadas"
--- /dev/null
+++ b/src/STRCNSRL.h
@@ -1,0 +1,184 @@
+/*
+ STRCNSRL.h
+
+ Copyright (C) 2018 SerbXenomorph, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file;ls see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY;ls without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ STRing CoNstants for SeRbian Latin
+
+ Converted from Serbian Cyrillic by 3 different online
+ converters, which all gave identical results.
+
+ comment from Serbian Cyrillic source follows:
+*/
+
+/*
+ STRing CoNstants for SeRbian Cyrillic
+ Translated by SerbXenomorph
+ - If no support Unicode/UTF-8, etc. support, online cyrillic to latin convertor will be enough.
+ - I have made some suggestions in the comments to avoid string repetition.
+*/
+
+#define kStrAboutTitle "O programu"
+#define kStrAboutMessage "Da bi se pokazale informacije o programu, koristite ;]A;} komandu moda kontrole ^p . Da saznate vi;vse o kontrolnom modu, vidite ;[Jo;vs komandi;ll;{ u ;[Special;{ meniju."
+
+#define kStrMoreCommandsTitle "Vi;vse komanda je dostupno u modu kontrole ^p."
+#define kStrMoreCommandsMessage "Da bi ste u;vsli u kontrolni mod, pretisnite taster ;]^c;}. osta;ecete u njemu dok ga ne pustite. Pretisnite ;]H;} da prika;vzete listu dostupnih komandi."
+
+#define kStrTooManyImagesTitle "Previ;vse diskovnih datoteka"
+#define kStrTooManyImagesMessage "Ne mogu montirati toliko diskovnih datoteka. Izbacite jednu."
+
+#define kStrImageInUseTitle "Diskovna datoteka se koristi"
+#define kStrImageInUseMessage "Ne mogu montirati diskovnu datoteku ^p kako se ve;ec koristi u drugom programu."
+
+#define kStrOutOfMemTitle "Nema dovoljno memorije"
+#define kStrOutOfMemMessage "Nema dovoljno memorije da bi se pokrenuo ^p."
+/*
+ This can possibly be defined as ("%s da bi se pokrenuo ^p.", kStrOutOfMemTitle) to avoid duplicated string, if used in a printf() like function.
+*/
+
+#define kStrNoROMTitle "Ne mogu na;eci ROM datoteku"
+#define kStrNoROMMessage "Ne mogu na;eci ROM datoteku ;[^r;{. Za vi;vse informacija, vidite: ;[^w;{."
+/*
+ Same for this
+*/
+
+#define kStrCorruptedROMTitle "ROM provera neuspe;vsna"
+#define kStrCorruptedROMMessage "ROM datoteka ;[^r;{ je mo;vzda o;vste;ecena."
+
+#define kStrUnsupportedROMTitle "Nepodr;vzani ROM"
+#define kStrUnsupportedROMMessage "ROM datoteka ;[^r;{ se u;vcitala uspe;vsno, ali ne podr;vzavam ROM verziju."
+
+#define kStrQuitWarningTitle "Molimo ugasite emulisani kompjuter pre nego ;vsto iza;ddete iz programa."
+#define kStrQuitWarningMessage "Da biste prisilili ^p da iza;dde, sa rizikom da se diskovni fajlovi o;vstete, koristi ;]Q;} komandu kontrolnog moda ^p. Da saznate vi;vse o kontrolnom modu, vidite ;[Jo;vs komandi;ll;{ u ;[Special;{ meniju."
+
+#define kStrReportAbnormalTitle "Abnormalna situacija"
+#define kStrReportAbnormalMessage "Emulisani ra;vcunar je poku;vsao operaciju koja ne bi trebalo de se izvr;vsi pri normalnom kori;vs;ecenju."
+
+#define kStrBadArgTitle "Nepoznati argument"
+#define kStrBadArgMessage "Nisam razumeo jedan od argumenata komandne linije, i ignorisao ga."
+
+#define kStrOpenFailTitle "Otvaranje neuspe;vsno"
+#define kStrOpenFailMessage "Nisam mogao otvoriti diskovnu datoteku."
+
+#define kStrNoReadROMTitle "ROM datoteka ne;vcitljiva"
+#define kStrNoReadROMMessage "Prona;vsao sam ROM datoteku ;[^r;{, ali je ne mogu pro;vcitati."
+
+#define kStrShortROMTitle "ROM datoteka prekratka"
+#define kStrShortROMMessage "ROM datoteka ;[^r;{ je kra;eca nego ;vsto bi trebala da bude."
+
+/* state of a boolean option */
+#define kStrOn "Vklju;vcen"
+#define kStrOff "Isklju;vcen"
+
+/* state of a key */
+#define kStrPressed "pritisnut"
+#define kStrReleased "pu;vsten"
+
+/* state of Stopped */
+#define kStrStoppedOn kStrOn
+#define kStrStoppedOff kStrOff
+
+/* About Screen */
+#define kStrProgramInfo "^v"
+#define kStrSponsorIs "^v. Ova varijacija je napravljena za:"
+#define kStrWorkOfMany "Za;vsti;eceno autorskim pravima ^y. ^p sadr;vzi rad mnogo ljudi. Ovu verziju odr;vzava:"
+#define kStrForMoreInfo "Za vi;vse informacija, vidite:"
+#define kStrLicense "^p je distribuiran pod nalozima GNU javne licence, verzije 2."
+#define kStrDisclaimer " ^p je distribuiran u nadi da ;ece biti koristan, ali BeZ GaRaNcIjE.;ls ;vcak i BeZ UtR;vzIvOsTi ili PrIkLaDnOsTi Za OdRe;dDeNu SvRhU."
+
+/* Help Screen */
+#define kStrHowToLeaveControl "da biste iza;vsli iz kontrolnog moda, pustite taster ;]^c;}."
+#define kStrHowToPickACommand "U drugom slu;vcaju, otkucajte slovo. Dostupne komande su:"
+#define kStrCmdAbout "O programu (informacije o verziji)"
+#define kStrCmdOpenDiskImage "Otvori diskovnu datoteku;ll"
+#define kStrCmdQuit "Iza;ddi"
+#define kStrCmdSpeedControl "Kontrola brzine;ll (^s)"
+#define kStrCmdMagnifyToggle "Prekida;vc lupe (^g)"
+#define kStrCmdFullScrnToggle "Prekida;vc re;vzima celog ekrana (^f)"
+#define kStrCmdCtrlKeyToggle "Prekida;vc emulisanog tastera ;]^m;} (^k)"
+#define kStrCmdReset "Resetuj"
+#define kStrCmdInterrupt "Prekid"
+#define kStrCmdHelp "Pomo;ec (poka;vzi ovu stranu)"
+
+/* Speed Control Screen */
+#define kStrCurrentSpeed "Trenutna brzina: ^s"
+#define kStrSpeedAllOut "Potpuna"
+#define kStrSpeedStopped "Prekida;vc zaustavljanja (^h)"
+#define kStrSpeedBackToggle "Prekida;vc rada u pozadini (^b)"
+#define kStrSpeedAutoSlowToggle "Prekida;vc automatskog usporavanja emulacije (^l)" /*Remove the "emulacije" if not enough space to display*/
+#define kStrSpeedExit "Iza;ddi iz kontrole brzine"
+
+#define kStrNewSpeed "Brzina: ^s"
+#define kStrSpeedValueAllOut kStrSpeedAllOut
+
+#define kStrNewStopped "Zaustavljeno jest ^h."
+#define kStrNewRunInBack "Pusti u pozadini jest ^b."
+#define kStrNewAutoSlow "automatsko usporavanje jest ^l."
+
+#define kStrNewMagnify "Pribli;vzi je ^g."
+
+#define kStrNewFullScreen "Ceo ekran je ^f."
+
+#define kStrNewCntrlKey "Emulisani taster ;]^m;} je ^k."
+
+#define kStrCmdCancel "odbij"
+
+#define kStrConfirmReset "Da li ste sigurni da ;vzelite resetovati emulirani kompjuter? nesa;vcuvane izmene ;ece biti izgubljene, i postoji rizik o;vste;ecivanja diskovnih datoteka. Otkucaj slovo:"
+#define kStrResetDo "resetuj"
+#define kStrResetNo kStrCmdCancel
+
+#define kStrHaveReset "Emulisani kompjuter resetovan"
+
+#define kStrCancelledReset "Resetovanje odbijeno"
+
+#define kStrConfirmInterrupt "Da li ste sigurni da ;vzelite prekinuti emulisani ra;vcunar? Ovo ;ece pokrenuti rad bilo kog instaliranog debagera. Otkucajte slovo:"
+#define kStrInterruptDo "prekini"
+#define kStrInterruptNo kStrCmdCancel
+
+#define kStrHaveInterrupted "Emulisani kompjuter prekinut"
+
+#define kStrCancelledInterrupt "Prekid odbijen"
+
+#define kStrConfirmQuit "Da li ste sigurni da ;vzelite iza;eci ^p? Trebali biste ugasiti emulisani ra;vcunar pre izlaska da biste preventisali korupciju montiranih diskovnih fajlova. Otkucajte slovo:"
+#define kStrQuitDo "iza;ddi"
+#define kStrQuitNo kStrCmdCancel
+
+#define kStrCancelledQuit "Izlazak odbijen"
+
+#define kStrModeConfirmReset "Kontrolni mod : Potvrdi resetovanje"
+#define kStrModeConfirmInterrupt "Kontrolni mod : Potvrdi prekid"
+#define kStrModeConfirmQuit "Kontrolni mod : Potvrdi izlazak"
+#define kStrModeSpeedControl "Kontrolni mod : Kontrola brzine"
+#define kStrModeControlBase "Kontrolni mod (Otkucaj ;]H;} za pomo;ec)"
+#define kStrModeControlHelp "Kontrolni mod"
+/* Same suggestion above for "Kontrolni mod". This may be used in other languages. */
+#define kStrModeMessage "Poruka (Otkucaj ;]C;} da nastavi;vs)"
+
+#define kStrMenuFile "Fajl"
+#define kStrMenuSpecial "Special"
+#define kStrMenuHelp "Pomo;ec"
+
+#define kStrMenuItemAbout "O ^p"
+#define kStrMenuItemOpen "Otvori diskovnu datoteku"
+#define kStrMenuItemQuit "Iza;ddi"
+#define kStrMenuItemMore "Vi;vse komandi"
+
+#define kStrAppMenuItemHide "Sakrij ^p"
+#define kStrAppMenuItemHideOthers "Sakrij ostale"
+#define kStrAppMenuItemShowAll "Prika;vzi sve"
+#define kStrAppMenuItemQuit "Iza;ddi ^p"
+
+#define kStrCmdCopyOptions "Kopiraj variation options"
+#define kStrHaveCopiedOptions "Variation options kopirane"
--- /dev/null
+++ b/src/SYSDEPNS.h
@@ -1,0 +1,152 @@
+/*
+ SYSDEPNS.h
+
+ Copyright (C) 2006 Bernd Schmidt, Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ SYStem DEPeNdencies.
+*/
+
+#ifdef SYSDEPNS_H
+#error "header already included"
+#else
+#define SYSDEPNS_H
+#endif
+
+#include "CNFGGLOB.h"
+
+
+typedef ui3b *ui3p;
+typedef ui4b *ui4p;
+typedef ui5b *ui5p;
+
+/*
+ Largest efficiently supported
+ representation types. uimr should be
+ large enough to hold number of elements
+ of any array we will deal with.
+*/
+typedef ui5r uimr;
+typedef si5r simr;
+
+#define blnr ui3r
+#define trueblnr 1
+#define falseblnr 0
+
+#define nullpr ((void *) 0)
+
+#define anyp ui3p
+
+/* pascal string, single byte characters */
+#define ps3p ui3p
+
+#ifndef MayInline
+#define MayInline
+#endif
+
+#ifndef MayNotInline
+#define MayNotInline
+#endif
+
+#ifndef my_reg_call
+#define my_reg_call
+#endif
+
+#ifndef my_osglu_call
+#define my_osglu_call
+#endif
+
+#define LOCALVAR static
+#ifdef AllFiles
+#define GLOBALVAR LOCALVAR
+#define EXPORTVAR(t, v)
+#else
+#define GLOBALVAR
+#define EXPORTVAR(t, v) extern t v;
+#endif
+
+#define LOCALFUNC static MayNotInline
+#define FORWARDFUNC LOCALFUNC
+#ifdef AllFiles
+#define GLOBALFUNC LOCALFUNC
+#define EXPORTFUNC LOCALFUNC
+#else
+#define GLOBALFUNC MayNotInline
+#define EXPORTFUNC extern
+#endif
+#define IMPORTFUNC EXPORTFUNC
+#define TYPEDEFFUNC typedef
+
+#define LOCALPROC LOCALFUNC void
+#define GLOBALPROC GLOBALFUNC void
+#define EXPORTPROC EXPORTFUNC void
+#define IMPORTPROC IMPORTFUNC void
+#define FORWARDPROC FORWARDFUNC void
+#define TYPEDEFPROC TYPEDEFFUNC void
+
+#define LOCALINLINEFUNC static MayInline
+#define LOCALINLINEPROC LOCALINLINEFUNC void
+
+#define LOCALFUNCUSEDONCE LOCALINLINEFUNC
+#define LOCALPROCUSEDONCE LOCALINLINEPROC
+
+#define GLOBALOSGLUFUNC GLOBALFUNC my_osglu_call
+#define EXPORTOSGLUFUNC EXPORTFUNC my_osglu_call
+#define GLOBALOSGLUPROC GLOBALFUNC my_osglu_call void
+#define EXPORTOSGLUPROC EXPORTFUNC my_osglu_call void
+ /*
+ For functions in operating system glue that
+ are called by rest of program.
+ */
+
+/*
+ best type for ui4r that is probably in register
+ (when compiler messes up otherwise)
+*/
+
+#ifndef BigEndianUnaligned
+#define BigEndianUnaligned 0
+#endif
+
+#ifndef LittleEndianUnaligned
+#define LittleEndianUnaligned 0
+#endif
+
+#ifndef ui3rr
+#define ui3rr ui3r
+#endif
+
+#ifndef ui4rr
+#define ui4rr ui4r
+#endif
+
+#ifndef si5rr
+#define si5rr si5r
+#endif
+
+#ifndef my_align_8
+#define my_align_8
+#endif
+
+#ifndef my_cond_rare
+#define my_cond_rare(x) (x)
+#endif
+
+#ifndef Have_ASR
+#define Have_ASR 0
+#endif
+
+#ifndef HaveMySwapUi5r
+#define HaveMySwapUi5r 0
+#endif
--- /dev/null
+++ b/src/VIA2EMDV.c
@@ -1,0 +1,1224 @@
+/*
+ VIA2EMDV.c
+
+ Copyright (C) 2008 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Versatile Interface Adapter EMulated DEVice
+
+ Emulates the VIA found in the Mac Plus.
+
+ This code adapted from vMac by Philip Cummins.
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+
+#include "MYOSGLUE.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#endif
+
+#include "VIA2EMDV.h"
+
+/*
+ ReportAbnormalID unused 0x0510 - 0x05FF
+*/
+
+#ifdef VIA2_iA0_ChangeNtfy
+IMPORTPROC VIA2_iA0_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iA1_ChangeNtfy
+IMPORTPROC VIA2_iA1_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iA2_ChangeNtfy
+IMPORTPROC VIA2_iA2_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iA3_ChangeNtfy
+IMPORTPROC VIA2_iA3_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iA4_ChangeNtfy
+IMPORTPROC VIA2_iA4_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iA5_ChangeNtfy
+IMPORTPROC VIA2_iA5_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iA6_ChangeNtfy
+IMPORTPROC VIA2_iA6_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iA7_ChangeNtfy
+IMPORTPROC VIA2_iA7_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iB0_ChangeNtfy
+IMPORTPROC VIA2_iB0_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iB1_ChangeNtfy
+IMPORTPROC VIA2_iB1_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iB2_ChangeNtfy
+IMPORTPROC VIA2_iB2_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iB3_ChangeNtfy
+IMPORTPROC VIA2_iB3_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iB4_ChangeNtfy
+IMPORTPROC VIA2_iB4_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iB5_ChangeNtfy
+IMPORTPROC VIA2_iB5_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iB6_ChangeNtfy
+IMPORTPROC VIA2_iB6_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iB7_ChangeNtfy
+IMPORTPROC VIA2_iB7_ChangeNtfy(void);
+#endif
+
+#ifdef VIA2_iCB2_ChangeNtfy
+IMPORTPROC VIA2_iCB2_ChangeNtfy(void);
+#endif
+
+#define Ui3rPowOf2(p) (1 << (p))
+#define Ui3rTestBit(i, p) (((i) & Ui3rPowOf2(p)) != 0)
+
+#define VIA2_ORA_CanInOrOut (VIA2_ORA_CanIn | VIA2_ORA_CanOut)
+
+#if ! Ui3rTestBit(VIA2_ORA_CanInOrOut, 7)
+#ifdef VIA2_iA7
+#error "VIA2_iA7 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORA_CanInOrOut, 6)
+#ifdef VIA2_iA6
+#error "VIA2_iA6 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORA_CanInOrOut, 5)
+#ifdef VIA2_iA5
+#error "VIA2_iA5 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORA_CanInOrOut, 4)
+#ifdef VIA2_iA4
+#error "VIA2_iA4 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORA_CanInOrOut, 3)
+#ifdef VIA2_iA3
+#error "VIA2_iA3 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORA_CanInOrOut, 2)
+#ifdef VIA2_iA2
+#error "VIA2_iA2 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORA_CanInOrOut, 1)
+#ifdef VIA2_iA1
+#error "VIA2_iA1 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORA_CanInOrOut, 0)
+#ifdef VIA2_iA0
+#error "VIA2_iA0 defined but not used"
+#endif
+#endif
+
+#define VIA2_ORB_CanInOrOut (VIA2_ORB_CanIn | VIA2_ORB_CanOut)
+
+#if ! Ui3rTestBit(VIA2_ORB_CanInOrOut, 7)
+#ifdef VIA2_iB7
+#error "VIA2_iB7 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORB_CanInOrOut, 6)
+#ifdef VIA2_iB6
+#error "VIA2_iB6 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORB_CanInOrOut, 5)
+#ifdef VIA2_iB5
+#error "VIA2_iB5 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORB_CanInOrOut, 4)
+#ifdef VIA2_iB4
+#error "VIA2_iB4 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORB_CanInOrOut, 3)
+#ifdef VIA2_iB3
+#error "VIA2_iB3 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORB_CanInOrOut, 2)
+#ifdef VIA2_iB2
+#error "VIA2_iB2 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORB_CanInOrOut, 1)
+#ifdef VIA2_iB1
+#error "VIA2_iB1 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA2_ORB_CanInOrOut, 0)
+#ifdef VIA2_iB0
+#error "VIA2_iB0 defined but not used"
+#endif
+#endif
+
+typedef struct {
+ ui5b T1C_F; /* Timer 1 Counter Fixed Point */
+ ui5b T2C_F; /* Timer 2 Counter Fixed Point */
+ ui3b ORB; /* Buffer B */
+ /* ui3b ORA_H; Buffer A with Handshake */
+ ui3b DDR_B; /* Data Direction Register B */
+ ui3b DDR_A; /* Data Direction Register A */
+ ui3b T1L_L; /* Timer 1 Latch Low */
+ ui3b T1L_H; /* Timer 1 Latch High */
+ ui3b T2L_L; /* Timer 2 Latch Low */
+ ui3b SR; /* Shift Register */
+ ui3b ACR; /* Auxiliary Control Register */
+ ui3b PCR; /* Peripheral Control Register */
+ ui3b IFR; /* Interrupt Flag Register */
+ ui3b IER; /* Interrupt Enable Register */
+ ui3b ORA; /* Buffer A */
+} VIA2_Ty;
+
+LOCALVAR VIA2_Ty VIA2_D;
+
+#define kIntCA2 0 /* One_Second */
+#define kIntCA1 1 /* Vertical_Blanking */
+#define kIntSR 2 /* Keyboard_Data_Ready */
+#define kIntCB2 3 /* Keyboard_Data */
+#define kIntCB1 4 /* Keyboard_Clock */
+#define kIntT2 5 /* Timer_2 */
+#define kIntT1 6 /* Timer_1 */
+
+#define VIA2_dolog (dbglog_HAVE && 0)
+
+/* VIA2_Get_ORA : VIA Get Port A Data */
+/*
+ This function queries VIA Port A interfaced hardware
+ about their status
+*/
+
+LOCALFUNC ui3b VIA2_Get_ORA(ui3b Selection)
+{
+ ui3b Value = (~ VIA2_ORA_CanIn) & Selection & VIA2_ORA_FloatVal;
+
+#if Ui3rTestBit(VIA2_ORA_CanIn, 7)
+ if (Ui3rTestBit(Selection, 7)) {
+ Value |= (VIA2_iA7 << 7);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanIn, 6)
+ if (Ui3rTestBit(Selection, 6)) {
+ Value |= (VIA2_iA6 << 6);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanIn, 5)
+ if (Ui3rTestBit(Selection, 5)) {
+ Value |= (VIA2_iA5 << 5);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanIn, 4)
+ if (Ui3rTestBit(Selection, 4)) {
+ Value |= (VIA2_iA4 << 4);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanIn, 3)
+ if (Ui3rTestBit(Selection, 3)) {
+ Value |= (VIA2_iA3 << 3);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanIn, 2)
+ if (Ui3rTestBit(Selection, 2)) {
+ Value |= (VIA2_iA2 << 2);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanIn, 1)
+ if (Ui3rTestBit(Selection, 1)) {
+ Value |= (VIA2_iA1 << 1);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanIn, 0)
+ if (Ui3rTestBit(Selection, 0)) {
+ Value |= (VIA2_iA0 << 0);
+ }
+#endif
+
+ return Value;
+}
+
+/* VIA2_Get_ORB : VIA Get Port B Data */
+/*
+ This function queries VIA Port B interfaced hardware
+ about their status
+*/
+
+LOCALFUNC ui3b VIA2_Get_ORB(ui3b Selection)
+{
+ ui3b Value = (~ VIA2_ORB_CanIn) & Selection & VIA2_ORB_FloatVal;
+
+#if Ui3rTestBit(VIA2_ORB_CanIn, 7)
+ if (Ui3rTestBit(Selection, 7)) {
+ Value |= (VIA2_iB7 << 7);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanIn, 6)
+ if (Ui3rTestBit(Selection, 6)) {
+ Value |= (VIA2_iB6 << 6);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanIn, 5)
+ if (Ui3rTestBit(Selection, 5)) {
+ Value |= (VIA2_iB5 << 5);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanIn, 4)
+ if (Ui3rTestBit(Selection, 4)) {
+ Value |= (VIA2_iB4 << 4);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanIn, 3)
+ if (Ui3rTestBit(Selection, 3)) {
+ Value |= (VIA2_iB3 << 3);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanIn, 2)
+ if (Ui3rTestBit(Selection, 2)) {
+ Value |= (VIA2_iB2 << 2);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanIn, 1)
+ if (Ui3rTestBit(Selection, 1)) {
+ Value |= (VIA2_iB1 << 1);
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanIn, 0)
+ if (Ui3rTestBit(Selection, 0)) {
+ Value |= (VIA2_iB0 << 0);
+ }
+#endif
+
+ return Value;
+}
+
+#define ViaORcheckBit(p, x) \
+ (Ui3rTestBit(Selection, p) && \
+ ((v = (Data >> p) & 1) != x))
+
+LOCALPROC VIA2_Put_ORA(ui3b Selection, ui3b Data)
+{
+#if 0 != VIA2_ORA_CanOut
+ ui3b v;
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanOut, 7)
+ if (ViaORcheckBit(7, VIA2_iA7)) {
+ VIA2_iA7 = v;
+#ifdef VIA2_iA7_ChangeNtfy
+ VIA2_iA7_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanOut, 6)
+ if (ViaORcheckBit(6, VIA2_iA6)) {
+ VIA2_iA6 = v;
+#ifdef VIA2_iA6_ChangeNtfy
+ VIA2_iA6_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanOut, 5)
+ if (ViaORcheckBit(5, VIA2_iA5)) {
+ VIA2_iA5 = v;
+#ifdef VIA2_iA5_ChangeNtfy
+ VIA2_iA5_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanOut, 4)
+ if (ViaORcheckBit(4, VIA2_iA4)) {
+ VIA2_iA4 = v;
+#ifdef VIA2_iA4_ChangeNtfy
+ VIA2_iA4_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanOut, 3)
+ if (ViaORcheckBit(3, VIA2_iA3)) {
+ VIA2_iA3 = v;
+#ifdef VIA2_iA3_ChangeNtfy
+ VIA2_iA3_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanOut, 2)
+ if (ViaORcheckBit(2, VIA2_iA2)) {
+ VIA2_iA2 = v;
+#ifdef VIA2_iA2_ChangeNtfy
+ VIA2_iA2_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanOut, 1)
+ if (ViaORcheckBit(1, VIA2_iA1)) {
+ VIA2_iA1 = v;
+#ifdef VIA2_iA1_ChangeNtfy
+ VIA2_iA1_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORA_CanOut, 0)
+ if (ViaORcheckBit(0, VIA2_iA0)) {
+ VIA2_iA0 = v;
+#ifdef VIA2_iA0_ChangeNtfy
+ VIA2_iA0_ChangeNtfy();
+#endif
+ }
+#endif
+}
+
+LOCALPROC VIA2_Put_ORB(ui3b Selection, ui3b Data)
+{
+#if 0 != VIA2_ORB_CanOut
+ ui3b v;
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanOut, 7)
+ if (ViaORcheckBit(7, VIA2_iB7)) {
+ VIA2_iB7 = v;
+#ifdef VIA2_iB7_ChangeNtfy
+ VIA2_iB7_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanOut, 6)
+ if (ViaORcheckBit(6, VIA2_iB6)) {
+ VIA2_iB6 = v;
+#ifdef VIA2_iB6_ChangeNtfy
+ VIA2_iB6_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanOut, 5)
+ if (ViaORcheckBit(5, VIA2_iB5)) {
+ VIA2_iB5 = v;
+#ifdef VIA2_iB5_ChangeNtfy
+ VIA2_iB5_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanOut, 4)
+ if (ViaORcheckBit(4, VIA2_iB4)) {
+ VIA2_iB4 = v;
+#ifdef VIA2_iB4_ChangeNtfy
+ VIA2_iB4_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanOut, 3)
+ if (ViaORcheckBit(3, VIA2_iB3)) {
+ VIA2_iB3 = v;
+#ifdef VIA2_iB3_ChangeNtfy
+ VIA2_iB3_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanOut, 2)
+ if (ViaORcheckBit(2, VIA2_iB2)) {
+ VIA2_iB2 = v;
+#ifdef VIA2_iB2_ChangeNtfy
+ VIA2_iB2_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanOut, 1)
+ if (ViaORcheckBit(1, VIA2_iB1)) {
+ VIA2_iB1 = v;
+#ifdef VIA2_iB1_ChangeNtfy
+ VIA2_iB1_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA2_ORB_CanOut, 0)
+ if (ViaORcheckBit(0, VIA2_iB0)) {
+ VIA2_iB0 = v;
+#ifdef VIA2_iB0_ChangeNtfy
+ VIA2_iB0_ChangeNtfy();
+#endif
+ }
+#endif
+}
+
+LOCALPROC VIA2_SetDDR_A(ui3b Data)
+{
+ ui3b floatbits = VIA2_D.DDR_A & ~ Data;
+ ui3b unfloatbits = Data & ~ VIA2_D.DDR_A;
+
+ if (floatbits != 0) {
+ VIA2_Put_ORA(floatbits, VIA2_ORA_FloatVal);
+ }
+ VIA2_D.DDR_A = Data;
+ if (unfloatbits != 0) {
+ VIA2_Put_ORA(unfloatbits, VIA2_D.ORA);
+ }
+ if ((Data & ~ VIA2_ORA_CanOut) != 0) {
+ ReportAbnormalID(0x0501,
+ "Set VIA2_D.DDR_A unexpected direction");
+ }
+}
+
+LOCALPROC VIA2_SetDDR_B(ui3b Data)
+{
+ ui3b floatbits = VIA2_D.DDR_B & ~ Data;
+ ui3b unfloatbits = Data & ~ VIA2_D.DDR_B;
+
+ if (floatbits != 0) {
+ VIA2_Put_ORB(floatbits, VIA2_ORB_FloatVal);
+ }
+ VIA2_D.DDR_B = Data;
+ if (unfloatbits != 0) {
+ VIA2_Put_ORB(unfloatbits, VIA2_D.ORB);
+ }
+ if ((Data & ~ VIA2_ORB_CanOut) != 0) {
+ ReportAbnormalID(0x0502,
+ "Set VIA2_D.DDR_B unexpected direction");
+ }
+}
+
+
+LOCALPROC VIA2_CheckInterruptFlag(void)
+{
+ ui3b NewInterruptRequest =
+ ((VIA2_D.IFR & VIA2_D.IER) != 0) ? 1 : 0;
+
+ if (NewInterruptRequest != VIA2_InterruptRequest) {
+ VIA2_InterruptRequest = NewInterruptRequest;
+#ifdef VIA2_interruptChngNtfy
+ VIA2_interruptChngNtfy();
+#endif
+ }
+}
+
+
+LOCALVAR ui3b VIA2_T1_Active = 0;
+LOCALVAR ui3b VIA2_T2_Active = 0;
+
+LOCALVAR blnr VIA2_T1IntReady = falseblnr;
+
+LOCALPROC VIA2_Clear(void)
+{
+ VIA2_D.ORA = 0; VIA2_D.DDR_A = 0;
+ VIA2_D.ORB = 0; VIA2_D.DDR_B = 0;
+ VIA2_D.T1L_L = VIA2_D.T1L_H = 0x00;
+ VIA2_D.T2L_L = 0x00;
+ VIA2_D.T1C_F = 0;
+ VIA2_D.T2C_F = 0;
+ VIA2_D.SR = VIA2_D.ACR = 0x00;
+ VIA2_D.PCR = VIA2_D.IFR = VIA2_D.IER = 0x00;
+ VIA2_T1_Active = VIA2_T2_Active = 0x00;
+ VIA2_T1IntReady = falseblnr;
+}
+
+GLOBALPROC VIA2_Zap(void)
+{
+ VIA2_Clear();
+ VIA2_InterruptRequest = 0;
+}
+
+GLOBALPROC VIA2_Reset(void)
+{
+ VIA2_SetDDR_A(0);
+ VIA2_SetDDR_B(0);
+
+ VIA2_Clear();
+
+ VIA2_CheckInterruptFlag();
+}
+
+LOCALPROC VIA2_SetInterruptFlag(ui3b VIA_Int)
+{
+ VIA2_D.IFR |= ((ui3b)1 << VIA_Int);
+ VIA2_CheckInterruptFlag();
+}
+
+LOCALPROC VIA2_ClrInterruptFlag(ui3b VIA_Int)
+{
+ VIA2_D.IFR &= ~ ((ui3b)1 << VIA_Int);
+ VIA2_CheckInterruptFlag();
+}
+
+#ifdef _VIA_Debug
+#include <stdio.h>
+#endif
+
+GLOBALPROC VIA2_ShiftInData(ui3b v)
+{
+ /*
+ external hardware generates 8 pulses on CB1,
+ writes 8 bits to CB2
+ */
+ ui3b ShiftMode = (VIA2_D.ACR & 0x1C) >> 2;
+
+ if (ShiftMode != 3) {
+#if ExtraAbnormalReports
+ if (ShiftMode == 0) {
+ /* happens on reset */
+ } else {
+ ReportAbnormalID(0x0503, "VIA Not ready to shift in");
+ /*
+ Observed (rarely) in Crystal Quest played
+ at 1x speed in "-t mc64".
+ */
+ }
+#endif
+ } else {
+ VIA2_D.SR = v;
+ VIA2_SetInterruptFlag(kIntSR);
+ VIA2_SetInterruptFlag(kIntCB1);
+ }
+}
+
+GLOBALFUNC ui3b VIA2_ShiftOutData(void)
+{
+ /*
+ external hardware generates 8 pulses on CB1,
+ reads 8 bits from CB2
+ */
+ if (((VIA2_D.ACR & 0x1C) >> 2) != 7) {
+ ReportAbnormalID(0x0504, "VIA Not ready to shift out");
+ return 0;
+ } else {
+ VIA2_SetInterruptFlag(kIntSR);
+ VIA2_SetInterruptFlag(kIntCB1);
+ VIA2_iCB2 = (VIA2_D.SR & 1);
+ return VIA2_D.SR;
+ }
+}
+
+#define CyclesPerViaTime (10 * kMyClockMult)
+#define CyclesScaledPerViaTime (kCycleScale * CyclesPerViaTime)
+
+LOCALVAR blnr VIA2_T1Running = trueblnr;
+LOCALVAR iCountt VIA2_T1LastTime = 0;
+
+GLOBALPROC VIA2_DoTimer1Check(void)
+{
+ if (VIA2_T1Running) {
+ iCountt NewTime = GetCuriCount();
+ iCountt deltaTime = (NewTime - VIA2_T1LastTime);
+ if (deltaTime != 0) {
+ ui5b Temp = VIA2_D.T1C_F; /* Get Timer 1 Counter */
+ ui5b deltaTemp =
+ (deltaTime / CyclesPerViaTime) << (16 - kLn2CycleScale);
+ /* may overflow */
+ ui5b NewTemp = Temp - deltaTemp;
+ if ((deltaTime > (0x00010000UL * CyclesScaledPerViaTime))
+ || ((Temp <= deltaTemp) && (Temp != 0)))
+ {
+ if ((VIA2_D.ACR & 0x40) != 0) { /* Free Running? */
+ /* Reload Counter from Latches */
+ ui4b v = (VIA2_D.T1L_H << 8) + VIA2_D.T1L_L;
+ ui4b ntrans = 1 + ((v == 0) ? 0 :
+ (((deltaTemp - Temp) / v) >> 16));
+ NewTemp += (((ui5b)v * ntrans) << 16);
+#if Ui3rTestBit(VIA2_ORB_CanOut, 7)
+ if ((VIA2_D.ACR & 0x80) != 0) { /* invert ? */
+ if ((ntrans & 1) != 0) {
+ VIA2_iB7 ^= 1;
+#ifdef VIA2_iB7_ChangeNtfy
+ VIA2_iB7_ChangeNtfy();
+#endif
+ }
+ }
+#endif
+ VIA2_SetInterruptFlag(kIntT1);
+#if VIA2_dolog && 1
+ dbglog_WriteNote("VIA2 Timer 1 Interrupt");
+#endif
+ } else {
+ if (VIA2_T1_Active == 1) {
+ VIA2_T1_Active = 0;
+ VIA2_SetInterruptFlag(kIntT1);
+#if VIA2_dolog && 1
+ dbglog_WriteNote("VIA2 Timer 1 Interrupt");
+#endif
+ }
+ }
+ }
+
+ VIA2_D.T1C_F = NewTemp;
+ VIA2_T1LastTime = NewTime;
+ }
+
+ VIA2_T1IntReady = falseblnr;
+ if ((VIA2_D.IFR & (1 << kIntT1)) == 0) {
+ if (((VIA2_D.ACR & 0x40) != 0) || (VIA2_T1_Active == 1)) {
+ ui5b NewTemp = VIA2_D.T1C_F; /* Get Timer 1 Counter */
+ ui5b NewTimer;
+#ifdef _VIA_Debug
+ fprintf(stderr, "posting Timer1Check, %d, %d\n",
+ Temp, GetCuriCount());
+#endif
+ if (NewTemp == 0) {
+ NewTimer = (0x00010000UL * CyclesScaledPerViaTime);
+ } else {
+ NewTimer =
+ (1 + (NewTemp >> (16 - kLn2CycleScale)))
+ * CyclesPerViaTime;
+ }
+ ICT_add(kICT_VIA2_Timer1Check, NewTimer);
+ VIA2_T1IntReady = trueblnr;
+ }
+ }
+ }
+}
+
+LOCALPROC CheckT1IntReady(void)
+{
+ if (VIA2_T1Running) {
+ blnr NewT1IntReady = falseblnr;
+
+ if ((VIA2_D.IFR & (1 << kIntT1)) == 0) {
+ if (((VIA2_D.ACR & 0x40) != 0) || (VIA2_T1_Active == 1)) {
+ NewT1IntReady = trueblnr;
+ }
+ }
+
+ if (VIA2_T1IntReady != NewT1IntReady) {
+ VIA2_T1IntReady = NewT1IntReady;
+ if (NewT1IntReady) {
+ VIA2_DoTimer1Check();
+ }
+ }
+ }
+}
+
+GLOBALFUNC ui4b VIA2_GetT1InvertTime(void)
+{
+ ui4b v;
+
+ if ((VIA2_D.ACR & 0xC0) == 0xC0) {
+ v = (VIA2_D.T1L_H << 8) + VIA2_D.T1L_L;
+ } else {
+ v = 0;
+ }
+ return v;
+}
+
+LOCALVAR blnr VIA2_T2Running = trueblnr;
+LOCALVAR blnr VIA2_T2C_ShortTime = falseblnr;
+LOCALVAR iCountt VIA2_T2LastTime = 0;
+
+GLOBALPROC VIA2_DoTimer2Check(void)
+{
+ if (VIA2_T2Running) {
+ iCountt NewTime = GetCuriCount();
+ ui5b Temp = VIA2_D.T2C_F; /* Get Timer 2 Counter */
+ iCountt deltaTime = (NewTime - VIA2_T2LastTime);
+ ui5b deltaTemp = (deltaTime / CyclesPerViaTime)
+ << (16 - kLn2CycleScale); /* may overflow */
+ ui5b NewTemp = Temp - deltaTemp;
+ if (VIA2_T2_Active == 1) {
+ if ((deltaTime > (0x00010000UL * CyclesScaledPerViaTime))
+ || ((Temp <= deltaTemp) && (Temp != 0)))
+ {
+ VIA2_T2C_ShortTime = falseblnr;
+ VIA2_T2_Active = 0;
+ VIA2_SetInterruptFlag(kIntT2);
+#if VIA2_dolog && 1
+ dbglog_WriteNote("VIA2 Timer 2 Interrupt");
+#endif
+ } else {
+ ui5b NewTimer;
+#ifdef _VIA_Debug
+ fprintf(stderr, "posting Timer2Check, %d, %d\n",
+ Temp, GetCuriCount());
+#endif
+ if (NewTemp == 0) {
+ NewTimer = (0x00010000UL * CyclesScaledPerViaTime);
+ } else {
+ NewTimer = (1 + (NewTemp >> (16 - kLn2CycleScale)))
+ * CyclesPerViaTime;
+ }
+ ICT_add(kICT_VIA2_Timer2Check, NewTimer);
+ }
+ }
+ VIA2_D.T2C_F = NewTemp;
+ VIA2_T2LastTime = NewTime;
+ }
+}
+
+#define kORB 0x00
+#define kORA_H 0x01
+#define kDDR_B 0x02
+#define kDDR_A 0x03
+#define kT1C_L 0x04
+#define kT1C_H 0x05
+#define kT1L_L 0x06
+#define kT1L_H 0x07
+#define kT2_L 0x08
+#define kT2_H 0x09
+#define kSR 0x0A
+#define kACR 0x0B
+#define kPCR 0x0C
+#define kIFR 0x0D
+#define kIER 0x0E
+#define kORA 0x0F
+
+GLOBALFUNC ui5b VIA2_Access(ui5b Data, blnr WriteMem, CPTR addr)
+{
+ switch (addr) {
+ case kORB :
+#if VIA2_CB2modesAllowed != 0x01
+ if ((VIA2_D.PCR & 0xE0) == 0)
+#endif
+ {
+ VIA2_ClrInterruptFlag(kIntCB2);
+ }
+ VIA2_ClrInterruptFlag(kIntCB1);
+ if (WriteMem) {
+ VIA2_D.ORB = Data;
+ VIA2_Put_ORB(VIA2_D.DDR_B, VIA2_D.ORB);
+ } else {
+ Data = (VIA2_D.ORB & VIA2_D.DDR_B)
+ | VIA2_Get_ORB(~ VIA2_D.DDR_B);
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kORB", Data, WriteMem);
+#endif
+ break;
+ case kDDR_B :
+ if (WriteMem) {
+ VIA2_SetDDR_B(Data);
+ } else {
+ Data = VIA2_D.DDR_B;
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kDDR_B", Data, WriteMem);
+#endif
+ break;
+ case kDDR_A :
+ if (WriteMem) {
+ VIA2_SetDDR_A(Data);
+ } else {
+ Data = VIA2_D.DDR_A;
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kDDR_A", Data, WriteMem);
+#endif
+ break;
+ case kT1C_L :
+ if (WriteMem) {
+ VIA2_D.T1L_L = Data;
+ } else {
+ VIA2_ClrInterruptFlag(kIntT1);
+ VIA2_DoTimer1Check();
+ Data = (VIA2_D.T1C_F & 0x00FF0000) >> 16;
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kT1C_L", Data, WriteMem);
+#endif
+ break;
+ case kT1C_H :
+ if (WriteMem) {
+ VIA2_D.T1L_H = Data;
+ VIA2_ClrInterruptFlag(kIntT1);
+ VIA2_D.T1C_F = (Data << 24) + (VIA2_D.T1L_L << 16);
+ if ((VIA2_D.ACR & 0x40) == 0) {
+ VIA2_T1_Active = 1;
+ }
+ VIA2_T1LastTime = GetCuriCount();
+ VIA2_DoTimer1Check();
+ } else {
+ VIA2_DoTimer1Check();
+ Data = (VIA2_D.T1C_F & 0xFF000000) >> 24;
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kT1C_H", Data, WriteMem);
+#endif
+ break;
+ case kT1L_L :
+ if (WriteMem) {
+ VIA2_D.T1L_L = Data;
+ } else {
+ Data = VIA2_D.T1L_L;
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kT1L_L", Data, WriteMem);
+#endif
+ break;
+ case kT1L_H :
+ if (WriteMem) {
+ VIA2_D.T1L_H = Data;
+ } else {
+ Data = VIA2_D.T1L_H;
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kT1L_H", Data, WriteMem);
+#endif
+ break;
+ case kT2_L :
+ if (WriteMem) {
+ VIA2_D.T2L_L = Data;
+ } else {
+ VIA2_ClrInterruptFlag(kIntT2);
+ VIA2_DoTimer2Check();
+ Data = (VIA2_D.T2C_F & 0x00FF0000) >> 16;
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kT2_L", Data, WriteMem);
+#endif
+ break;
+ case kT2_H :
+ if (WriteMem) {
+ VIA2_D.T2C_F = (Data << 24) + (VIA2_D.T2L_L << 16);
+ VIA2_ClrInterruptFlag(kIntT2);
+ VIA2_T2_Active = 1;
+
+ if ((VIA2_D.T2C_F < (128UL << 16))
+ && (VIA2_D.T2C_F != 0))
+ {
+ VIA2_T2C_ShortTime = trueblnr;
+ VIA2_T2Running = trueblnr;
+ /*
+ Running too many instructions during
+ a short timer interval can crash when
+ playing sounds in System 7. So
+ in this case don't let timer pause.
+ */
+ }
+ VIA2_T2LastTime = GetCuriCount();
+ VIA2_DoTimer2Check();
+ } else {
+ VIA2_DoTimer2Check();
+ Data = (VIA2_D.T2C_F & 0xFF000000) >> 24;
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kT2_H", Data, WriteMem);
+#endif
+ break;
+ case kSR:
+#ifdef _VIA_Debug
+ fprintf(stderr, "VIA2_D.SR: %d, %d, %d\n",
+ WriteMem, ((VIA2_D.ACR & 0x1C) >> 2), Data);
+#endif
+ if (WriteMem) {
+ VIA2_D.SR = Data;
+ }
+ VIA2_ClrInterruptFlag(kIntSR);
+ switch ((VIA2_D.ACR & 0x1C) >> 2) {
+ case 3 : /* Shifting In */
+ break;
+ case 6 : /* shift out under o2 clock */
+ if ((! WriteMem) || (VIA2_D.SR != 0)) {
+ ReportAbnormalID(0x0505,
+ "VIA shift mode 6, non zero");
+ } else {
+#ifdef _VIA_Debug
+ fprintf(stderr, "posting Foo2Task\n");
+#endif
+ if (VIA2_iCB2 != 0) {
+ VIA2_iCB2 = 0;
+#ifdef VIA2_iCB2_ChangeNtfy
+ VIA2_iCB2_ChangeNtfy();
+#endif
+ }
+ }
+#if 0 /* possibly should do this. seems not to affect anything. */
+ VIA2_SetInterruptFlag(kIntSR); /* don't wait */
+#endif
+ break;
+ case 7 : /* Shifting Out */
+ break;
+ }
+ if (! WriteMem) {
+ Data = VIA2_D.SR;
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kSR", Data, WriteMem);
+#endif
+ break;
+ case kACR:
+ if (WriteMem) {
+#if 1
+ if ((VIA2_D.ACR & 0x10) != ((ui3b)Data & 0x10)) {
+ /* shift direction has changed */
+ if ((Data & 0x10) == 0) {
+ /*
+ no longer an output,
+ set data to float value
+ */
+ if (VIA2_iCB2 == 0) {
+ VIA2_iCB2 = 1;
+#ifdef VIA2_iCB2_ChangeNtfy
+ VIA2_iCB2_ChangeNtfy();
+#endif
+ }
+ }
+ }
+#endif
+ VIA2_D.ACR = Data;
+ if ((VIA2_D.ACR & 0x20) != 0) {
+ /* Not pulse counting? */
+ ReportAbnormalID(0x0506,
+ "Set VIA2_D.ACR T2 Timer pulse counting");
+ }
+ switch ((VIA2_D.ACR & 0xC0) >> 6) {
+ /* case 1: happens in early System 6 */
+ case 2:
+ ReportAbnormalID(0x0507,
+ "Set VIA2_D.ACR T1 Timer mode 2");
+ break;
+ }
+ CheckT1IntReady();
+ switch ((VIA2_D.ACR & 0x1C) >> 2) {
+ case 0: /* this isn't sufficient */
+ VIA2_ClrInterruptFlag(kIntSR);
+ break;
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ ReportAbnormalID(0x0508,
+ "Set VIA2_D.ACR shift mode 1,2,4,5");
+ break;
+ default:
+ break;
+ }
+ if ((VIA2_D.ACR & 0x03) != 0) {
+ ReportAbnormalID(0x0509,
+ "Set VIA2_D.ACR T2 Timer latching enabled");
+ }
+ } else {
+ Data = VIA2_D.ACR;
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kACR", Data, WriteMem);
+#endif
+ break;
+ case kPCR:
+ if (WriteMem) {
+ VIA2_D.PCR = Data;
+#define Ui3rSetContains(s, i) (((s) & (1 << (i))) != 0)
+ if (! Ui3rSetContains(VIA2_CB2modesAllowed,
+ (VIA2_D.PCR >> 5) & 0x07))
+ {
+ ReportAbnormalID(0x050A,
+ "Set VIA2_D.PCR CB2 Control mode?");
+ }
+ if ((VIA2_D.PCR & 0x10) != 0) {
+ ReportAbnormalID(0x050B,
+ "Set VIA2_D.PCR CB1 INTERRUPT CONTROL?");
+ }
+ if (! Ui3rSetContains(VIA2_CA2modesAllowed,
+ (VIA2_D.PCR >> 1) & 0x07))
+ {
+ ReportAbnormalID(0x050C,
+ "Set VIA2_D.PCR CA2 INTERRUPT CONTROL?");
+ }
+ if ((VIA2_D.PCR & 0x01) != 0) {
+ ReportAbnormalID(0x050D,
+ "Set VIA2_D.PCR CA1 INTERRUPT CONTROL?");
+ }
+ } else {
+ Data = VIA2_D.PCR;
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kPCR", Data, WriteMem);
+#endif
+ break;
+ case kIFR:
+ if (WriteMem) {
+ VIA2_D.IFR = VIA2_D.IFR & ((~ Data) & 0x7F);
+ /* Clear Flag Bits */
+ VIA2_CheckInterruptFlag();
+ CheckT1IntReady();
+ } else {
+ Data = VIA2_D.IFR;
+ if ((VIA2_D.IFR & VIA2_D.IER) != 0) {
+ Data |= 0x80;
+ }
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kIFR", Data, WriteMem);
+#endif
+ break;
+ case kIER :
+ if (WriteMem) {
+ if ((Data & 0x80) == 0) {
+ VIA2_D.IER = VIA2_D.IER & ((~ Data) & 0x7F);
+ /* Clear Enable Bits */
+#if 0 != VIA2_IER_Never0
+ /*
+ of course, will be 0 initially,
+ this just checks not cleared later.
+ */
+ if ((Data & VIA2_IER_Never0) != 0) {
+ ReportAbnormalID(0x050E, "IER Never0 clr");
+ }
+#endif
+ } else {
+ VIA2_D.IER = VIA2_D.IER | (Data & 0x7F);
+ /* Set Enable Bits */
+#if 0 != VIA2_IER_Never1
+ if ((VIA2_D.IER & VIA2_IER_Never1) != 0) {
+ ReportAbnormalID(0x050F, "IER Never1 set");
+ }
+#endif
+ }
+ VIA2_CheckInterruptFlag();
+ } else {
+ Data = VIA2_D.IER | 0x80;
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kIER", Data, WriteMem);
+#endif
+ break;
+ case kORA :
+ case kORA_H :
+ if ((VIA2_D.PCR & 0xE) == 0) {
+ VIA2_ClrInterruptFlag(kIntCA2);
+ }
+ VIA2_ClrInterruptFlag(kIntCA1);
+ if (WriteMem) {
+ VIA2_D.ORA = Data;
+ VIA2_Put_ORA(VIA2_D.DDR_A, VIA2_D.ORA);
+ } else {
+ Data = (VIA2_D.ORA & VIA2_D.DDR_A)
+ | VIA2_Get_ORA(~ VIA2_D.DDR_A);
+ }
+#if VIA2_dolog && 1
+ dbglog_Access("VIA2_Access kORA", Data, WriteMem);
+#endif
+ break;
+ }
+ return Data;
+}
+
+GLOBALPROC VIA2_ExtraTimeBegin(void)
+{
+ if (VIA2_T1Running) {
+ VIA2_DoTimer1Check(); /* run up to this moment */
+ VIA2_T1Running = falseblnr;
+ }
+ if (VIA2_T2Running & (! VIA2_T2C_ShortTime)) {
+ VIA2_DoTimer2Check(); /* run up to this moment */
+ VIA2_T2Running = falseblnr;
+ }
+}
+
+GLOBALPROC VIA2_ExtraTimeEnd(void)
+{
+ if (! VIA2_T1Running) {
+ VIA2_T1Running = trueblnr;
+ VIA2_T1LastTime = GetCuriCount();
+ VIA2_DoTimer1Check();
+ }
+ if (! VIA2_T2Running) {
+ VIA2_T2Running = trueblnr;
+ VIA2_T2LastTime = GetCuriCount();
+ VIA2_DoTimer2Check();
+ }
+}
+
+/* VIA Interrupt Interface */
+
+#ifdef VIA2_iCA1_PulseNtfy
+GLOBALPROC VIA2_iCA1_PulseNtfy(void)
+{
+ VIA2_SetInterruptFlag(kIntCA1);
+}
+#endif
+
+#ifdef VIA2_iCA2_PulseNtfy
+GLOBALPROC VIA2_iCA2_PulseNtfy(void)
+{
+ VIA2_SetInterruptFlag(kIntCA2);
+}
+#endif
+
+#ifdef VIA2_iCB1_PulseNtfy
+GLOBALPROC VIA2_iCB1_PulseNtfy(void)
+{
+ VIA2_SetInterruptFlag(kIntCB1);
+}
+#endif
+
+#ifdef VIA2_iCB2_PulseNtfy
+GLOBALPROC VIA2_iCB2_PulseNtfy(void)
+{
+ VIA2_SetInterruptFlag(kIntCB2);
+}
+#endif
--- /dev/null
+++ b/src/VIA2EMDV.h
@@ -1,0 +1,48 @@
+/*
+ VIA2EMDV.h
+
+ Copyright (C) 2004 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef VIA2EMDV_H
+#error "header already included"
+#else
+#define VIA2EMDV_H
+#endif
+
+EXPORTPROC VIA2_Zap(void);
+EXPORTPROC VIA2_Reset(void);
+
+EXPORTFUNC ui5b VIA2_Access(ui5b Data, blnr WriteMem, CPTR addr);
+
+EXPORTPROC VIA2_ExtraTimeBegin(void);
+EXPORTPROC VIA2_ExtraTimeEnd(void);
+#ifdef VIA2_iCA1_PulseNtfy
+EXPORTPROC VIA2_iCA1_PulseNtfy(void);
+#endif
+#ifdef VIA2_iCA2_PulseNtfy
+EXPORTPROC VIA2_iCA2_PulseNtfy(void);
+#endif
+#ifdef VIA2_iCB1_PulseNtfy
+EXPORTPROC VIA2_iCB1_PulseNtfy(void);
+#endif
+#ifdef VIA2_iCB2_PulseNtfy
+EXPORTPROC VIA2_iCB2_PulseNtfy(void);
+#endif
+EXPORTPROC VIA2_DoTimer1Check(void);
+EXPORTPROC VIA2_DoTimer2Check(void);
+
+EXPORTFUNC ui4b VIA2_GetT1InvertTime(void);
+
+EXPORTPROC VIA2_ShiftInData(ui3b v);
+EXPORTFUNC ui3b VIA2_ShiftOutData(void);
--- /dev/null
+++ b/src/VIAEMDEV.c
@@ -1,0 +1,1224 @@
+/*
+ VIAEMDEV.c
+
+ Copyright (C) 2008 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ Versatile Interface Adapter EMulated DEVice
+
+ Emulates the VIA found in the Mac Plus.
+
+ This code adapted from vMac by Philip Cummins.
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+
+#include "MYOSGLUE.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#endif
+
+#include "VIAEMDEV.h"
+
+/*
+ ReportAbnormalID unused 0x0410 - 0x04FF
+*/
+
+#ifdef VIA1_iA0_ChangeNtfy
+IMPORTPROC VIA1_iA0_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iA1_ChangeNtfy
+IMPORTPROC VIA1_iA1_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iA2_ChangeNtfy
+IMPORTPROC VIA1_iA2_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iA3_ChangeNtfy
+IMPORTPROC VIA1_iA3_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iA4_ChangeNtfy
+IMPORTPROC VIA1_iA4_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iA5_ChangeNtfy
+IMPORTPROC VIA1_iA5_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iA6_ChangeNtfy
+IMPORTPROC VIA1_iA6_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iA7_ChangeNtfy
+IMPORTPROC VIA1_iA7_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iB0_ChangeNtfy
+IMPORTPROC VIA1_iB0_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iB1_ChangeNtfy
+IMPORTPROC VIA1_iB1_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iB2_ChangeNtfy
+IMPORTPROC VIA1_iB2_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iB3_ChangeNtfy
+IMPORTPROC VIA1_iB3_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iB4_ChangeNtfy
+IMPORTPROC VIA1_iB4_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iB5_ChangeNtfy
+IMPORTPROC VIA1_iB5_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iB6_ChangeNtfy
+IMPORTPROC VIA1_iB6_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iB7_ChangeNtfy
+IMPORTPROC VIA1_iB7_ChangeNtfy(void);
+#endif
+
+#ifdef VIA1_iCB2_ChangeNtfy
+IMPORTPROC VIA1_iCB2_ChangeNtfy(void);
+#endif
+
+#define Ui3rPowOf2(p) (1 << (p))
+#define Ui3rTestBit(i, p) (((i) & Ui3rPowOf2(p)) != 0)
+
+#define VIA1_ORA_CanInOrOut (VIA1_ORA_CanIn | VIA1_ORA_CanOut)
+
+#if ! Ui3rTestBit(VIA1_ORA_CanInOrOut, 7)
+#ifdef VIA1_iA7
+#error "VIA1_iA7 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORA_CanInOrOut, 6)
+#ifdef VIA1_iA6
+#error "VIA1_iA6 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORA_CanInOrOut, 5)
+#ifdef VIA1_iA5
+#error "VIA1_iA5 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORA_CanInOrOut, 4)
+#ifdef VIA1_iA4
+#error "VIA1_iA4 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORA_CanInOrOut, 3)
+#ifdef VIA1_iA3
+#error "VIA1_iA3 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORA_CanInOrOut, 2)
+#ifdef VIA1_iA2
+#error "VIA1_iA2 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORA_CanInOrOut, 1)
+#ifdef VIA1_iA1
+#error "VIA1_iA1 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORA_CanInOrOut, 0)
+#ifdef VIA1_iA0
+#error "VIA1_iA0 defined but not used"
+#endif
+#endif
+
+#define VIA1_ORB_CanInOrOut (VIA1_ORB_CanIn | VIA1_ORB_CanOut)
+
+#if ! Ui3rTestBit(VIA1_ORB_CanInOrOut, 7)
+#ifdef VIA1_iB7
+#error "VIA1_iB7 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORB_CanInOrOut, 6)
+#ifdef VIA1_iB6
+#error "VIA1_iB6 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORB_CanInOrOut, 5)
+#ifdef VIA1_iB5
+#error "VIA1_iB5 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORB_CanInOrOut, 4)
+#ifdef VIA1_iB4
+#error "VIA1_iB4 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORB_CanInOrOut, 3)
+#ifdef VIA1_iB3
+#error "VIA1_iB3 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORB_CanInOrOut, 2)
+#ifdef VIA1_iB2
+#error "VIA1_iB2 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORB_CanInOrOut, 1)
+#ifdef VIA1_iB1
+#error "VIA1_iB1 defined but not used"
+#endif
+#endif
+
+#if ! Ui3rTestBit(VIA1_ORB_CanInOrOut, 0)
+#ifdef VIA1_iB0
+#error "VIA1_iB0 defined but not used"
+#endif
+#endif
+
+typedef struct {
+ ui5b T1C_F; /* Timer 1 Counter Fixed Point */
+ ui5b T2C_F; /* Timer 2 Counter Fixed Point */
+ ui3b ORB; /* Buffer B */
+ /* ui3b ORA_H; Buffer A with Handshake */
+ ui3b DDR_B; /* Data Direction Register B */
+ ui3b DDR_A; /* Data Direction Register A */
+ ui3b T1L_L; /* Timer 1 Latch Low */
+ ui3b T1L_H; /* Timer 1 Latch High */
+ ui3b T2L_L; /* Timer 2 Latch Low */
+ ui3b SR; /* Shift Register */
+ ui3b ACR; /* Auxiliary Control Register */
+ ui3b PCR; /* Peripheral Control Register */
+ ui3b IFR; /* Interrupt Flag Register */
+ ui3b IER; /* Interrupt Enable Register */
+ ui3b ORA; /* Buffer A */
+} VIA1_Ty;
+
+LOCALVAR VIA1_Ty VIA1_D;
+
+#define kIntCA2 0 /* One_Second */
+#define kIntCA1 1 /* Vertical_Blanking */
+#define kIntSR 2 /* Keyboard_Data_Ready */
+#define kIntCB2 3 /* Keyboard_Data */
+#define kIntCB1 4 /* Keyboard_Clock */
+#define kIntT2 5 /* Timer_2 */
+#define kIntT1 6 /* Timer_1 */
+
+#define VIA1_dolog (dbglog_HAVE && 0)
+
+/* VIA1_Get_ORA : VIA Get Port A Data */
+/*
+ This function queries VIA Port A interfaced hardware
+ about their status
+*/
+
+LOCALFUNC ui3b VIA1_Get_ORA(ui3b Selection)
+{
+ ui3b Value = (~ VIA1_ORA_CanIn) & Selection & VIA1_ORA_FloatVal;
+
+#if Ui3rTestBit(VIA1_ORA_CanIn, 7)
+ if (Ui3rTestBit(Selection, 7)) {
+ Value |= (VIA1_iA7 << 7);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanIn, 6)
+ if (Ui3rTestBit(Selection, 6)) {
+ Value |= (VIA1_iA6 << 6);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanIn, 5)
+ if (Ui3rTestBit(Selection, 5)) {
+ Value |= (VIA1_iA5 << 5);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanIn, 4)
+ if (Ui3rTestBit(Selection, 4)) {
+ Value |= (VIA1_iA4 << 4);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanIn, 3)
+ if (Ui3rTestBit(Selection, 3)) {
+ Value |= (VIA1_iA3 << 3);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanIn, 2)
+ if (Ui3rTestBit(Selection, 2)) {
+ Value |= (VIA1_iA2 << 2);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanIn, 1)
+ if (Ui3rTestBit(Selection, 1)) {
+ Value |= (VIA1_iA1 << 1);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanIn, 0)
+ if (Ui3rTestBit(Selection, 0)) {
+ Value |= (VIA1_iA0 << 0);
+ }
+#endif
+
+ return Value;
+}
+
+/* VIA1_Get_ORB : VIA Get Port B Data */
+/*
+ This function queries VIA Port B interfaced hardware
+ about their status
+*/
+
+LOCALFUNC ui3b VIA1_Get_ORB(ui3b Selection)
+{
+ ui3b Value = (~ VIA1_ORB_CanIn) & Selection & VIA1_ORB_FloatVal;
+
+#if Ui3rTestBit(VIA1_ORB_CanIn, 7)
+ if (Ui3rTestBit(Selection, 7)) {
+ Value |= (VIA1_iB7 << 7);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanIn, 6)
+ if (Ui3rTestBit(Selection, 6)) {
+ Value |= (VIA1_iB6 << 6);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanIn, 5)
+ if (Ui3rTestBit(Selection, 5)) {
+ Value |= (VIA1_iB5 << 5);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanIn, 4)
+ if (Ui3rTestBit(Selection, 4)) {
+ Value |= (VIA1_iB4 << 4);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanIn, 3)
+ if (Ui3rTestBit(Selection, 3)) {
+ Value |= (VIA1_iB3 << 3);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanIn, 2)
+ if (Ui3rTestBit(Selection, 2)) {
+ Value |= (VIA1_iB2 << 2);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanIn, 1)
+ if (Ui3rTestBit(Selection, 1)) {
+ Value |= (VIA1_iB1 << 1);
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanIn, 0)
+ if (Ui3rTestBit(Selection, 0)) {
+ Value |= (VIA1_iB0 << 0);
+ }
+#endif
+
+ return Value;
+}
+
+#define ViaORcheckBit(p, x) \
+ (Ui3rTestBit(Selection, p) && \
+ ((v = (Data >> p) & 1) != x))
+
+LOCALPROC VIA1_Put_ORA(ui3b Selection, ui3b Data)
+{
+#if 0 != VIA1_ORA_CanOut
+ ui3b v;
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanOut, 7)
+ if (ViaORcheckBit(7, VIA1_iA7)) {
+ VIA1_iA7 = v;
+#ifdef VIA1_iA7_ChangeNtfy
+ VIA1_iA7_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanOut, 6)
+ if (ViaORcheckBit(6, VIA1_iA6)) {
+ VIA1_iA6 = v;
+#ifdef VIA1_iA6_ChangeNtfy
+ VIA1_iA6_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanOut, 5)
+ if (ViaORcheckBit(5, VIA1_iA5)) {
+ VIA1_iA5 = v;
+#ifdef VIA1_iA5_ChangeNtfy
+ VIA1_iA5_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanOut, 4)
+ if (ViaORcheckBit(4, VIA1_iA4)) {
+ VIA1_iA4 = v;
+#ifdef VIA1_iA4_ChangeNtfy
+ VIA1_iA4_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanOut, 3)
+ if (ViaORcheckBit(3, VIA1_iA3)) {
+ VIA1_iA3 = v;
+#ifdef VIA1_iA3_ChangeNtfy
+ VIA1_iA3_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanOut, 2)
+ if (ViaORcheckBit(2, VIA1_iA2)) {
+ VIA1_iA2 = v;
+#ifdef VIA1_iA2_ChangeNtfy
+ VIA1_iA2_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanOut, 1)
+ if (ViaORcheckBit(1, VIA1_iA1)) {
+ VIA1_iA1 = v;
+#ifdef VIA1_iA1_ChangeNtfy
+ VIA1_iA1_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORA_CanOut, 0)
+ if (ViaORcheckBit(0, VIA1_iA0)) {
+ VIA1_iA0 = v;
+#ifdef VIA1_iA0_ChangeNtfy
+ VIA1_iA0_ChangeNtfy();
+#endif
+ }
+#endif
+}
+
+LOCALPROC VIA1_Put_ORB(ui3b Selection, ui3b Data)
+{
+#if 0 != VIA1_ORB_CanOut
+ ui3b v;
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanOut, 7)
+ if (ViaORcheckBit(7, VIA1_iB7)) {
+ VIA1_iB7 = v;
+#ifdef VIA1_iB7_ChangeNtfy
+ VIA1_iB7_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanOut, 6)
+ if (ViaORcheckBit(6, VIA1_iB6)) {
+ VIA1_iB6 = v;
+#ifdef VIA1_iB6_ChangeNtfy
+ VIA1_iB6_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanOut, 5)
+ if (ViaORcheckBit(5, VIA1_iB5)) {
+ VIA1_iB5 = v;
+#ifdef VIA1_iB5_ChangeNtfy
+ VIA1_iB5_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanOut, 4)
+ if (ViaORcheckBit(4, VIA1_iB4)) {
+ VIA1_iB4 = v;
+#ifdef VIA1_iB4_ChangeNtfy
+ VIA1_iB4_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanOut, 3)
+ if (ViaORcheckBit(3, VIA1_iB3)) {
+ VIA1_iB3 = v;
+#ifdef VIA1_iB3_ChangeNtfy
+ VIA1_iB3_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanOut, 2)
+ if (ViaORcheckBit(2, VIA1_iB2)) {
+ VIA1_iB2 = v;
+#ifdef VIA1_iB2_ChangeNtfy
+ VIA1_iB2_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanOut, 1)
+ if (ViaORcheckBit(1, VIA1_iB1)) {
+ VIA1_iB1 = v;
+#ifdef VIA1_iB1_ChangeNtfy
+ VIA1_iB1_ChangeNtfy();
+#endif
+ }
+#endif
+
+#if Ui3rTestBit(VIA1_ORB_CanOut, 0)
+ if (ViaORcheckBit(0, VIA1_iB0)) {
+ VIA1_iB0 = v;
+#ifdef VIA1_iB0_ChangeNtfy
+ VIA1_iB0_ChangeNtfy();
+#endif
+ }
+#endif
+}
+
+LOCALPROC VIA1_SetDDR_A(ui3b Data)
+{
+ ui3b floatbits = VIA1_D.DDR_A & ~ Data;
+ ui3b unfloatbits = Data & ~ VIA1_D.DDR_A;
+
+ if (floatbits != 0) {
+ VIA1_Put_ORA(floatbits, VIA1_ORA_FloatVal);
+ }
+ VIA1_D.DDR_A = Data;
+ if (unfloatbits != 0) {
+ VIA1_Put_ORA(unfloatbits, VIA1_D.ORA);
+ }
+ if ((Data & ~ VIA1_ORA_CanOut) != 0) {
+ ReportAbnormalID(0x0401,
+ "Set VIA1_D.DDR_A unexpected direction");
+ }
+}
+
+LOCALPROC VIA1_SetDDR_B(ui3b Data)
+{
+ ui3b floatbits = VIA1_D.DDR_B & ~ Data;
+ ui3b unfloatbits = Data & ~ VIA1_D.DDR_B;
+
+ if (floatbits != 0) {
+ VIA1_Put_ORB(floatbits, VIA1_ORB_FloatVal);
+ }
+ VIA1_D.DDR_B = Data;
+ if (unfloatbits != 0) {
+ VIA1_Put_ORB(unfloatbits, VIA1_D.ORB);
+ }
+ if ((Data & ~ VIA1_ORB_CanOut) != 0) {
+ ReportAbnormalID(0x0402,
+ "Set VIA1_D.DDR_B unexpected direction");
+ }
+}
+
+
+LOCALPROC VIA1_CheckInterruptFlag(void)
+{
+ ui3b NewInterruptRequest =
+ ((VIA1_D.IFR & VIA1_D.IER) != 0) ? 1 : 0;
+
+ if (NewInterruptRequest != VIA1_InterruptRequest) {
+ VIA1_InterruptRequest = NewInterruptRequest;
+#ifdef VIA1_interruptChngNtfy
+ VIA1_interruptChngNtfy();
+#endif
+ }
+}
+
+
+LOCALVAR ui3b VIA1_T1_Active = 0;
+LOCALVAR ui3b VIA1_T2_Active = 0;
+
+LOCALVAR blnr VIA1_T1IntReady = falseblnr;
+
+LOCALPROC VIA1_Clear(void)
+{
+ VIA1_D.ORA = 0; VIA1_D.DDR_A = 0;
+ VIA1_D.ORB = 0; VIA1_D.DDR_B = 0;
+ VIA1_D.T1L_L = VIA1_D.T1L_H = 0x00;
+ VIA1_D.T2L_L = 0x00;
+ VIA1_D.T1C_F = 0;
+ VIA1_D.T2C_F = 0;
+ VIA1_D.SR = VIA1_D.ACR = 0x00;
+ VIA1_D.PCR = VIA1_D.IFR = VIA1_D.IER = 0x00;
+ VIA1_T1_Active = VIA1_T2_Active = 0x00;
+ VIA1_T1IntReady = falseblnr;
+}
+
+GLOBALPROC VIA1_Zap(void)
+{
+ VIA1_Clear();
+ VIA1_InterruptRequest = 0;
+}
+
+GLOBALPROC VIA1_Reset(void)
+{
+ VIA1_SetDDR_A(0);
+ VIA1_SetDDR_B(0);
+
+ VIA1_Clear();
+
+ VIA1_CheckInterruptFlag();
+}
+
+LOCALPROC VIA1_SetInterruptFlag(ui3b VIA_Int)
+{
+ VIA1_D.IFR |= ((ui3b)1 << VIA_Int);
+ VIA1_CheckInterruptFlag();
+}
+
+LOCALPROC VIA1_ClrInterruptFlag(ui3b VIA_Int)
+{
+ VIA1_D.IFR &= ~ ((ui3b)1 << VIA_Int);
+ VIA1_CheckInterruptFlag();
+}
+
+#ifdef _VIA_Debug
+#include <stdio.h>
+#endif
+
+GLOBALPROC VIA1_ShiftInData(ui3b v)
+{
+ /*
+ external hardware generates 8 pulses on CB1,
+ writes 8 bits to CB2
+ */
+ ui3b ShiftMode = (VIA1_D.ACR & 0x1C) >> 2;
+
+ if (ShiftMode != 3) {
+#if ExtraAbnormalReports
+ if (ShiftMode == 0) {
+ /* happens on reset */
+ } else {
+ ReportAbnormalID(0x0403, "VIA Not ready to shift in");
+ /*
+ Observed (rarely) in Crystal Quest played
+ at 1x speed in "-t mc64".
+ */
+ }
+#endif
+ } else {
+ VIA1_D.SR = v;
+ VIA1_SetInterruptFlag(kIntSR);
+ VIA1_SetInterruptFlag(kIntCB1);
+ }
+}
+
+GLOBALFUNC ui3b VIA1_ShiftOutData(void)
+{
+ /*
+ external hardware generates 8 pulses on CB1,
+ reads 8 bits from CB2
+ */
+ if (((VIA1_D.ACR & 0x1C) >> 2) != 7) {
+ ReportAbnormalID(0x0404, "VIA Not ready to shift out");
+ return 0;
+ } else {
+ VIA1_SetInterruptFlag(kIntSR);
+ VIA1_SetInterruptFlag(kIntCB1);
+ VIA1_iCB2 = (VIA1_D.SR & 1);
+ return VIA1_D.SR;
+ }
+}
+
+#define CyclesPerViaTime (10 * kMyClockMult)
+#define CyclesScaledPerViaTime (kCycleScale * CyclesPerViaTime)
+
+LOCALVAR blnr VIA1_T1Running = trueblnr;
+LOCALVAR iCountt VIA1_T1LastTime = 0;
+
+GLOBALPROC VIA1_DoTimer1Check(void)
+{
+ if (VIA1_T1Running) {
+ iCountt NewTime = GetCuriCount();
+ iCountt deltaTime = (NewTime - VIA1_T1LastTime);
+ if (deltaTime != 0) {
+ ui5b Temp = VIA1_D.T1C_F; /* Get Timer 1 Counter */
+ ui5b deltaTemp =
+ (deltaTime / CyclesPerViaTime) << (16 - kLn2CycleScale);
+ /* may overflow */
+ ui5b NewTemp = Temp - deltaTemp;
+ if ((deltaTime > (0x00010000UL * CyclesScaledPerViaTime))
+ || ((Temp <= deltaTemp) && (Temp != 0)))
+ {
+ if ((VIA1_D.ACR & 0x40) != 0) { /* Free Running? */
+ /* Reload Counter from Latches */
+ ui4b v = (VIA1_D.T1L_H << 8) + VIA1_D.T1L_L;
+ ui4b ntrans = 1 + ((v == 0) ? 0 :
+ (((deltaTemp - Temp) / v) >> 16));
+ NewTemp += (((ui5b)v * ntrans) << 16);
+#if Ui3rTestBit(VIA1_ORB_CanOut, 7)
+ if ((VIA1_D.ACR & 0x80) != 0) { /* invert ? */
+ if ((ntrans & 1) != 0) {
+ VIA1_iB7 ^= 1;
+#ifdef VIA1_iB7_ChangeNtfy
+ VIA1_iB7_ChangeNtfy();
+#endif
+ }
+ }
+#endif
+ VIA1_SetInterruptFlag(kIntT1);
+#if VIA1_dolog && 1
+ dbglog_WriteNote("VIA1 Timer 1 Interrupt");
+#endif
+ } else {
+ if (VIA1_T1_Active == 1) {
+ VIA1_T1_Active = 0;
+ VIA1_SetInterruptFlag(kIntT1);
+#if VIA1_dolog && 1
+ dbglog_WriteNote("VIA1 Timer 1 Interrupt");
+#endif
+ }
+ }
+ }
+
+ VIA1_D.T1C_F = NewTemp;
+ VIA1_T1LastTime = NewTime;
+ }
+
+ VIA1_T1IntReady = falseblnr;
+ if ((VIA1_D.IFR & (1 << kIntT1)) == 0) {
+ if (((VIA1_D.ACR & 0x40) != 0) || (VIA1_T1_Active == 1)) {
+ ui5b NewTemp = VIA1_D.T1C_F; /* Get Timer 1 Counter */
+ ui5b NewTimer;
+#ifdef _VIA_Debug
+ fprintf(stderr, "posting Timer1Check, %d, %d\n",
+ Temp, GetCuriCount());
+#endif
+ if (NewTemp == 0) {
+ NewTimer = (0x00010000UL * CyclesScaledPerViaTime);
+ } else {
+ NewTimer =
+ (1 + (NewTemp >> (16 - kLn2CycleScale)))
+ * CyclesPerViaTime;
+ }
+ ICT_add(kICT_VIA1_Timer1Check, NewTimer);
+ VIA1_T1IntReady = trueblnr;
+ }
+ }
+ }
+}
+
+LOCALPROC CheckT1IntReady(void)
+{
+ if (VIA1_T1Running) {
+ blnr NewT1IntReady = falseblnr;
+
+ if ((VIA1_D.IFR & (1 << kIntT1)) == 0) {
+ if (((VIA1_D.ACR & 0x40) != 0) || (VIA1_T1_Active == 1)) {
+ NewT1IntReady = trueblnr;
+ }
+ }
+
+ if (VIA1_T1IntReady != NewT1IntReady) {
+ VIA1_T1IntReady = NewT1IntReady;
+ if (NewT1IntReady) {
+ VIA1_DoTimer1Check();
+ }
+ }
+ }
+}
+
+GLOBALFUNC ui4b VIA1_GetT1InvertTime(void)
+{
+ ui4b v;
+
+ if ((VIA1_D.ACR & 0xC0) == 0xC0) {
+ v = (VIA1_D.T1L_H << 8) + VIA1_D.T1L_L;
+ } else {
+ v = 0;
+ }
+ return v;
+}
+
+LOCALVAR blnr VIA1_T2Running = trueblnr;
+LOCALVAR blnr VIA1_T2C_ShortTime = falseblnr;
+LOCALVAR iCountt VIA1_T2LastTime = 0;
+
+GLOBALPROC VIA1_DoTimer2Check(void)
+{
+ if (VIA1_T2Running) {
+ iCountt NewTime = GetCuriCount();
+ ui5b Temp = VIA1_D.T2C_F; /* Get Timer 2 Counter */
+ iCountt deltaTime = (NewTime - VIA1_T2LastTime);
+ ui5b deltaTemp = (deltaTime / CyclesPerViaTime)
+ << (16 - kLn2CycleScale); /* may overflow */
+ ui5b NewTemp = Temp - deltaTemp;
+ if (VIA1_T2_Active == 1) {
+ if ((deltaTime > (0x00010000UL * CyclesScaledPerViaTime))
+ || ((Temp <= deltaTemp) && (Temp != 0)))
+ {
+ VIA1_T2C_ShortTime = falseblnr;
+ VIA1_T2_Active = 0;
+ VIA1_SetInterruptFlag(kIntT2);
+#if VIA1_dolog && 1
+ dbglog_WriteNote("VIA1 Timer 2 Interrupt");
+#endif
+ } else {
+ ui5b NewTimer;
+#ifdef _VIA_Debug
+ fprintf(stderr, "posting Timer2Check, %d, %d\n",
+ Temp, GetCuriCount());
+#endif
+ if (NewTemp == 0) {
+ NewTimer = (0x00010000UL * CyclesScaledPerViaTime);
+ } else {
+ NewTimer = (1 + (NewTemp >> (16 - kLn2CycleScale)))
+ * CyclesPerViaTime;
+ }
+ ICT_add(kICT_VIA1_Timer2Check, NewTimer);
+ }
+ }
+ VIA1_D.T2C_F = NewTemp;
+ VIA1_T2LastTime = NewTime;
+ }
+}
+
+#define kORB 0x00
+#define kORA_H 0x01
+#define kDDR_B 0x02
+#define kDDR_A 0x03
+#define kT1C_L 0x04
+#define kT1C_H 0x05
+#define kT1L_L 0x06
+#define kT1L_H 0x07
+#define kT2_L 0x08
+#define kT2_H 0x09
+#define kSR 0x0A
+#define kACR 0x0B
+#define kPCR 0x0C
+#define kIFR 0x0D
+#define kIER 0x0E
+#define kORA 0x0F
+
+GLOBALFUNC ui5b VIA1_Access(ui5b Data, blnr WriteMem, CPTR addr)
+{
+ switch (addr) {
+ case kORB :
+#if VIA1_CB2modesAllowed != 0x01
+ if ((VIA1_D.PCR & 0xE0) == 0)
+#endif
+ {
+ VIA1_ClrInterruptFlag(kIntCB2);
+ }
+ VIA1_ClrInterruptFlag(kIntCB1);
+ if (WriteMem) {
+ VIA1_D.ORB = Data;
+ VIA1_Put_ORB(VIA1_D.DDR_B, VIA1_D.ORB);
+ } else {
+ Data = (VIA1_D.ORB & VIA1_D.DDR_B)
+ | VIA1_Get_ORB(~ VIA1_D.DDR_B);
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kORB", Data, WriteMem);
+#endif
+ break;
+ case kDDR_B :
+ if (WriteMem) {
+ VIA1_SetDDR_B(Data);
+ } else {
+ Data = VIA1_D.DDR_B;
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kDDR_B", Data, WriteMem);
+#endif
+ break;
+ case kDDR_A :
+ if (WriteMem) {
+ VIA1_SetDDR_A(Data);
+ } else {
+ Data = VIA1_D.DDR_A;
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kDDR_A", Data, WriteMem);
+#endif
+ break;
+ case kT1C_L :
+ if (WriteMem) {
+ VIA1_D.T1L_L = Data;
+ } else {
+ VIA1_ClrInterruptFlag(kIntT1);
+ VIA1_DoTimer1Check();
+ Data = (VIA1_D.T1C_F & 0x00FF0000) >> 16;
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kT1C_L", Data, WriteMem);
+#endif
+ break;
+ case kT1C_H :
+ if (WriteMem) {
+ VIA1_D.T1L_H = Data;
+ VIA1_ClrInterruptFlag(kIntT1);
+ VIA1_D.T1C_F = (Data << 24) + (VIA1_D.T1L_L << 16);
+ if ((VIA1_D.ACR & 0x40) == 0) {
+ VIA1_T1_Active = 1;
+ }
+ VIA1_T1LastTime = GetCuriCount();
+ VIA1_DoTimer1Check();
+ } else {
+ VIA1_DoTimer1Check();
+ Data = (VIA1_D.T1C_F & 0xFF000000) >> 24;
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kT1C_H", Data, WriteMem);
+#endif
+ break;
+ case kT1L_L :
+ if (WriteMem) {
+ VIA1_D.T1L_L = Data;
+ } else {
+ Data = VIA1_D.T1L_L;
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kT1L_L", Data, WriteMem);
+#endif
+ break;
+ case kT1L_H :
+ if (WriteMem) {
+ VIA1_D.T1L_H = Data;
+ } else {
+ Data = VIA1_D.T1L_H;
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kT1L_H", Data, WriteMem);
+#endif
+ break;
+ case kT2_L :
+ if (WriteMem) {
+ VIA1_D.T2L_L = Data;
+ } else {
+ VIA1_ClrInterruptFlag(kIntT2);
+ VIA1_DoTimer2Check();
+ Data = (VIA1_D.T2C_F & 0x00FF0000) >> 16;
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kT2_L", Data, WriteMem);
+#endif
+ break;
+ case kT2_H :
+ if (WriteMem) {
+ VIA1_D.T2C_F = (Data << 24) + (VIA1_D.T2L_L << 16);
+ VIA1_ClrInterruptFlag(kIntT2);
+ VIA1_T2_Active = 1;
+
+ if ((VIA1_D.T2C_F < (128UL << 16))
+ && (VIA1_D.T2C_F != 0))
+ {
+ VIA1_T2C_ShortTime = trueblnr;
+ VIA1_T2Running = trueblnr;
+ /*
+ Running too many instructions during
+ a short timer interval can crash when
+ playing sounds in System 7. So
+ in this case don't let timer pause.
+ */
+ }
+ VIA1_T2LastTime = GetCuriCount();
+ VIA1_DoTimer2Check();
+ } else {
+ VIA1_DoTimer2Check();
+ Data = (VIA1_D.T2C_F & 0xFF000000) >> 24;
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kT2_H", Data, WriteMem);
+#endif
+ break;
+ case kSR:
+#ifdef _VIA_Debug
+ fprintf(stderr, "VIA1_D.SR: %d, %d, %d\n",
+ WriteMem, ((VIA1_D.ACR & 0x1C) >> 2), Data);
+#endif
+ if (WriteMem) {
+ VIA1_D.SR = Data;
+ }
+ VIA1_ClrInterruptFlag(kIntSR);
+ switch ((VIA1_D.ACR & 0x1C) >> 2) {
+ case 3 : /* Shifting In */
+ break;
+ case 6 : /* shift out under o2 clock */
+ if ((! WriteMem) || (VIA1_D.SR != 0)) {
+ ReportAbnormalID(0x0405,
+ "VIA shift mode 6, non zero");
+ } else {
+#ifdef _VIA_Debug
+ fprintf(stderr, "posting Foo2Task\n");
+#endif
+ if (VIA1_iCB2 != 0) {
+ VIA1_iCB2 = 0;
+#ifdef VIA1_iCB2_ChangeNtfy
+ VIA1_iCB2_ChangeNtfy();
+#endif
+ }
+ }
+#if 0 /* possibly should do this. seems not to affect anything. */
+ VIA1_SetInterruptFlag(kIntSR); /* don't wait */
+#endif
+ break;
+ case 7 : /* Shifting Out */
+ break;
+ }
+ if (! WriteMem) {
+ Data = VIA1_D.SR;
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kSR", Data, WriteMem);
+#endif
+ break;
+ case kACR:
+ if (WriteMem) {
+#if 1
+ if ((VIA1_D.ACR & 0x10) != ((ui3b)Data & 0x10)) {
+ /* shift direction has changed */
+ if ((Data & 0x10) == 0) {
+ /*
+ no longer an output,
+ set data to float value
+ */
+ if (VIA1_iCB2 == 0) {
+ VIA1_iCB2 = 1;
+#ifdef VIA1_iCB2_ChangeNtfy
+ VIA1_iCB2_ChangeNtfy();
+#endif
+ }
+ }
+ }
+#endif
+ VIA1_D.ACR = Data;
+ if ((VIA1_D.ACR & 0x20) != 0) {
+ /* Not pulse counting? */
+ ReportAbnormalID(0x0406,
+ "Set VIA1_D.ACR T2 Timer pulse counting");
+ }
+ switch ((VIA1_D.ACR & 0xC0) >> 6) {
+ /* case 1: happens in early System 6 */
+ case 2:
+ ReportAbnormalID(0x0407,
+ "Set VIA1_D.ACR T1 Timer mode 2");
+ break;
+ }
+ CheckT1IntReady();
+ switch ((VIA1_D.ACR & 0x1C) >> 2) {
+ case 0: /* this isn't sufficient */
+ VIA1_ClrInterruptFlag(kIntSR);
+ break;
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ ReportAbnormalID(0x0408,
+ "Set VIA1_D.ACR shift mode 1,2,4,5");
+ break;
+ default:
+ break;
+ }
+ if ((VIA1_D.ACR & 0x03) != 0) {
+ ReportAbnormalID(0x0409,
+ "Set VIA1_D.ACR T2 Timer latching enabled");
+ }
+ } else {
+ Data = VIA1_D.ACR;
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kACR", Data, WriteMem);
+#endif
+ break;
+ case kPCR:
+ if (WriteMem) {
+ VIA1_D.PCR = Data;
+#define Ui3rSetContains(s, i) (((s) & (1 << (i))) != 0)
+ if (! Ui3rSetContains(VIA1_CB2modesAllowed,
+ (VIA1_D.PCR >> 5) & 0x07))
+ {
+ ReportAbnormalID(0x040A,
+ "Set VIA1_D.PCR CB2 Control mode?");
+ }
+ if ((VIA1_D.PCR & 0x10) != 0) {
+ ReportAbnormalID(0x040B,
+ "Set VIA1_D.PCR CB1 INTERRUPT CONTROL?");
+ }
+ if (! Ui3rSetContains(VIA1_CA2modesAllowed,
+ (VIA1_D.PCR >> 1) & 0x07))
+ {
+ ReportAbnormalID(0x040C,
+ "Set VIA1_D.PCR CA2 INTERRUPT CONTROL?");
+ }
+ if ((VIA1_D.PCR & 0x01) != 0) {
+ ReportAbnormalID(0x040D,
+ "Set VIA1_D.PCR CA1 INTERRUPT CONTROL?");
+ }
+ } else {
+ Data = VIA1_D.PCR;
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kPCR", Data, WriteMem);
+#endif
+ break;
+ case kIFR:
+ if (WriteMem) {
+ VIA1_D.IFR = VIA1_D.IFR & ((~ Data) & 0x7F);
+ /* Clear Flag Bits */
+ VIA1_CheckInterruptFlag();
+ CheckT1IntReady();
+ } else {
+ Data = VIA1_D.IFR;
+ if ((VIA1_D.IFR & VIA1_D.IER) != 0) {
+ Data |= 0x80;
+ }
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kIFR", Data, WriteMem);
+#endif
+ break;
+ case kIER :
+ if (WriteMem) {
+ if ((Data & 0x80) == 0) {
+ VIA1_D.IER = VIA1_D.IER & ((~ Data) & 0x7F);
+ /* Clear Enable Bits */
+#if 0 != VIA1_IER_Never0
+ /*
+ of course, will be 0 initially,
+ this just checks not cleared later.
+ */
+ if ((Data & VIA1_IER_Never0) != 0) {
+ ReportAbnormalID(0x040E, "IER Never0 clr");
+ }
+#endif
+ } else {
+ VIA1_D.IER = VIA1_D.IER | (Data & 0x7F);
+ /* Set Enable Bits */
+#if 0 != VIA1_IER_Never1
+ if ((VIA1_D.IER & VIA1_IER_Never1) != 0) {
+ ReportAbnormalID(0x040F, "IER Never1 set");
+ }
+#endif
+ }
+ VIA1_CheckInterruptFlag();
+ } else {
+ Data = VIA1_D.IER | 0x80;
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kIER", Data, WriteMem);
+#endif
+ break;
+ case kORA :
+ case kORA_H :
+ if ((VIA1_D.PCR & 0xE) == 0) {
+ VIA1_ClrInterruptFlag(kIntCA2);
+ }
+ VIA1_ClrInterruptFlag(kIntCA1);
+ if (WriteMem) {
+ VIA1_D.ORA = Data;
+ VIA1_Put_ORA(VIA1_D.DDR_A, VIA1_D.ORA);
+ } else {
+ Data = (VIA1_D.ORA & VIA1_D.DDR_A)
+ | VIA1_Get_ORA(~ VIA1_D.DDR_A);
+ }
+#if VIA1_dolog && 1
+ dbglog_Access("VIA1_Access kORA", Data, WriteMem);
+#endif
+ break;
+ }
+ return Data;
+}
+
+GLOBALPROC VIA1_ExtraTimeBegin(void)
+{
+ if (VIA1_T1Running) {
+ VIA1_DoTimer1Check(); /* run up to this moment */
+ VIA1_T1Running = falseblnr;
+ }
+ if (VIA1_T2Running & (! VIA1_T2C_ShortTime)) {
+ VIA1_DoTimer2Check(); /* run up to this moment */
+ VIA1_T2Running = falseblnr;
+ }
+}
+
+GLOBALPROC VIA1_ExtraTimeEnd(void)
+{
+ if (! VIA1_T1Running) {
+ VIA1_T1Running = trueblnr;
+ VIA1_T1LastTime = GetCuriCount();
+ VIA1_DoTimer1Check();
+ }
+ if (! VIA1_T2Running) {
+ VIA1_T2Running = trueblnr;
+ VIA1_T2LastTime = GetCuriCount();
+ VIA1_DoTimer2Check();
+ }
+}
+
+/* VIA Interrupt Interface */
+
+#ifdef VIA1_iCA1_PulseNtfy
+GLOBALPROC VIA1_iCA1_PulseNtfy(void)
+{
+ VIA1_SetInterruptFlag(kIntCA1);
+}
+#endif
+
+#ifdef VIA1_iCA2_PulseNtfy
+GLOBALPROC VIA1_iCA2_PulseNtfy(void)
+{
+ VIA1_SetInterruptFlag(kIntCA2);
+}
+#endif
+
+#ifdef VIA1_iCB1_PulseNtfy
+GLOBALPROC VIA1_iCB1_PulseNtfy(void)
+{
+ VIA1_SetInterruptFlag(kIntCB1);
+}
+#endif
+
+#ifdef VIA1_iCB2_PulseNtfy
+GLOBALPROC VIA1_iCB2_PulseNtfy(void)
+{
+ VIA1_SetInterruptFlag(kIntCB2);
+}
+#endif
--- /dev/null
+++ b/src/VIAEMDEV.h
@@ -1,0 +1,48 @@
+/*
+ VIAEMDEV.h
+
+ Copyright (C) 2004 Philip Cummins, Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef VIAEMDEV_H
+#error "header already included"
+#else
+#define VIAEMDEV_H
+#endif
+
+EXPORTPROC VIA1_Zap(void);
+EXPORTPROC VIA1_Reset(void);
+
+EXPORTFUNC ui5b VIA1_Access(ui5b Data, blnr WriteMem, CPTR addr);
+
+EXPORTPROC VIA1_ExtraTimeBegin(void);
+EXPORTPROC VIA1_ExtraTimeEnd(void);
+#ifdef VIA1_iCA1_PulseNtfy
+EXPORTPROC VIA1_iCA1_PulseNtfy(void);
+#endif
+#ifdef VIA1_iCA2_PulseNtfy
+EXPORTPROC VIA1_iCA2_PulseNtfy(void);
+#endif
+#ifdef VIA1_iCB1_PulseNtfy
+EXPORTPROC VIA1_iCB1_PulseNtfy(void);
+#endif
+#ifdef VIA1_iCB2_PulseNtfy
+EXPORTPROC VIA1_iCB2_PulseNtfy(void);
+#endif
+EXPORTPROC VIA1_DoTimer1Check(void);
+EXPORTPROC VIA1_DoTimer2Check(void);
+
+EXPORTFUNC ui4b VIA1_GetT1InvertTime(void);
+
+EXPORTPROC VIA1_ShiftInData(ui3b v);
+EXPORTFUNC ui3b VIA1_ShiftOutData(void);
--- /dev/null
+++ b/src/VIDEMDEV.c
@@ -1,0 +1,1004 @@
+/*
+ VIDEMDEV.c
+
+ Copyright (C) 2008 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+/*
+ VIDeo card EMulated DEVice
+
+ Emulation of video card for Macintosh II.
+
+ Written referring to:
+ Sample firmware code in "Designing Cards and Drivers
+ for Macintosh II and Macintosh SE", Apple Computer,
+ page 8-20.
+
+ Basilisk II source code, especially slot_rom.cpp
+*/
+
+#ifndef AllFiles
+#include "SYSDEPNS.h"
+#include "MYOSGLUE.h"
+#include "ENDIANAC.h"
+#include "EMCONFIG.h"
+#include "GLOBGLUE.h"
+#include "MINEM68K.h"
+#include "SONYEMDV.h"
+#endif
+
+#include "VIDEMDEV.h"
+
+/*
+ ReportAbnormalID unused 0x0A08 - 0x0AFF
+*/
+
+#define VID_dolog (dbglog_HAVE && 0)
+
+LOCALVAR const ui3b VidDrvr_contents[] = {
+0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x2A, 0x00, 0x00, 0x00, 0xE2, 0x00, 0xEC,
+0x00, 0xB6, 0x15, 0x2E, 0x44, 0x69, 0x73, 0x70,
+0x6C, 0x61, 0x79, 0x5F, 0x56, 0x69, 0x64, 0x65,
+0x6F, 0x5F, 0x53, 0x61, 0x6D, 0x70, 0x6C, 0x65,
+0x00, 0x00, 0x24, 0x48, 0x26, 0x49, 0x70, 0x04,
+0xA4, 0x40, 0x70, 0x04, 0xA7, 0x22, 0x66, 0x00,
+0x00, 0x50, 0x27, 0x48, 0x00, 0x14, 0xA0, 0x29,
+0x49, 0xFA, 0x00, 0x4A, 0x70, 0x10, 0xA7, 0x1E,
+0x66, 0x00, 0x00, 0x3E, 0x31, 0x7C, 0x00, 0x06,
+0x00, 0x04, 0x21, 0x4C, 0x00, 0x08, 0x21, 0x4B,
+0x00, 0x0C, 0x70, 0x00, 0x10, 0x2B, 0x00, 0x28,
+0xA0, 0x75, 0x66, 0x24, 0x22, 0x6B, 0x00, 0x14,
+0x22, 0x51, 0x22, 0x88, 0x3F, 0x3C, 0x00, 0x01,
+0x55, 0x4F, 0x3F, 0x3C, 0x00, 0x03, 0x41, 0xFA,
+0x00, 0x9C, 0x2F, 0x18, 0x20, 0x50, 0x20, 0x8F,
+0xDE, 0xFC, 0x00, 0x0A, 0x70, 0x00, 0x60, 0x02,
+0x70, 0xE9, 0x4E, 0x75, 0x2F, 0x08, 0x55, 0x4F,
+0x3F, 0x3C, 0x00, 0x04, 0x41, 0xFA, 0x00, 0x7E,
+0x2F, 0x18, 0x20, 0x50, 0x20, 0x8F, 0x50, 0x4F,
+0x20, 0x29, 0x00, 0x2A, 0xE1, 0x98, 0x02, 0x40,
+0x00, 0x0F, 0x20, 0x78, 0x0D, 0x28, 0x4E, 0x90,
+0x20, 0x5F, 0x70, 0x01, 0x4E, 0x75, 0x2F, 0x0B,
+0x26, 0x69, 0x00, 0x14, 0x42, 0x67, 0x55, 0x4F,
+0x3F, 0x3C, 0x00, 0x03, 0x41, 0xFA, 0x00, 0x4E,
+0x2F, 0x18, 0x20, 0x50, 0x20, 0x8F, 0xDE, 0xFC,
+0x00, 0x0A, 0x20, 0x53, 0x20, 0x50, 0xA0, 0x76,
+0x20, 0x4B, 0xA0, 0x23, 0x70, 0x00, 0x26, 0x5F,
+0x4E, 0x75, 0x2F, 0x08, 0x55, 0x4F, 0x3F, 0x3C,
+0x00, 0x06, 0x60, 0x08, 0x2F, 0x08, 0x55, 0x4F,
+0x3F, 0x3C, 0x00, 0x05, 0x41, 0xFA, 0x00, 0x1E,
+0x2F, 0x18, 0x20, 0x50, 0x20, 0x8F, 0x5C, 0x4F,
+0x30, 0x1F, 0x20, 0x5F, 0x08, 0x28, 0x00, 0x09,
+0x00, 0x06, 0x67, 0x02, 0x4E, 0x75, 0x20, 0x78,
+0x08, 0xFC, 0x4E, 0xD0
+};
+
+LOCALPROC ChecksumSlotROM(void)
+{
+ /* Calculate CRC */
+ /* assuming check sum field initialized to zero */
+ int i;
+ ui3p p = VidROM;
+ ui5b crc = 0;
+
+ for (i = kVidROM_Size; --i >= 0; ) {
+ crc = ((crc << 1) | (crc >> 31)) + *p++;
+ }
+ do_put_mem_long(p - 12, crc);
+}
+
+LOCALVAR ui3p pPatch;
+
+LOCALPROC PatchAByte(ui3b v)
+{
+ *pPatch++ = v;
+}
+
+LOCALPROC PatchAWord(ui4r v)
+{
+ PatchAByte(v >> 8);
+ PatchAByte(v & 0x00FF);
+}
+
+LOCALPROC PatchALong(ui5r v)
+{
+ PatchAWord(v >> 16);
+ PatchAWord(v & 0x0000FFFF);
+}
+
+#if 0
+LOCALPROC PatchAOSLstEntry0(ui3r Id, ui5r Offset)
+{
+ PatchALong((Id << 24) | (Offset & 0x00FFFFFF));
+}
+#endif
+
+LOCALPROC PatchAOSLstEntry(ui3r Id, ui3p Offset)
+{
+ PatchALong((Id << 24) | ((Offset - pPatch) & 0x00FFFFFF));
+}
+
+LOCALFUNC ui3p ReservePatchOSLstEntry(void)
+{
+ ui3p v = pPatch;
+ pPatch += 4;
+ return v;
+}
+
+LOCALPROC PatchAReservedOSLstEntry(ui3p p, ui3r Id)
+{
+ ui3p pPatchSave = pPatch;
+ pPatch = p;
+ PatchAOSLstEntry(Id, pPatchSave);
+ pPatch = pPatchSave;
+}
+
+LOCALPROC PatchADatLstEntry(ui3r Id, ui5r Data)
+{
+ PatchALong((Id << 24) | (Data & 0x00FFFFFF));
+}
+
+LOCALPROC PatchAnEndOfLst(void)
+{
+ PatchADatLstEntry(0xFF /* endOfList */, 0x00000000);
+}
+
+GLOBALFUNC blnr Vid_Init(void)
+{
+ int i;
+ ui5r UsedSoFar;
+
+ ui3p pAt_sRsrcDir;
+ ui3p pTo_sRsrc_Board;
+ ui3p pTo_BoardType;
+ ui3p pTo_BoardName;
+ ui3p pTo_VenderInfo;
+ ui3p pTo_VendorID;
+ ui3p pTo_RevLevel;
+ ui3p pTo_PartNum;
+ ui3p pTo_sRsrc_Video;
+ ui3p pTo_VideoType;
+ ui3p pTo_VideoName;
+ ui3p pTo_MinorBase;
+ ui3p pTo_MinorLength;
+#if 0
+ ui3p pTo_MajorBase;
+ ui3p pTo_MajorLength;
+#endif
+ ui3p pTo_VidDrvrDir;
+ ui3p pTo_sMacOS68020;
+ ui3p pTo_OneBitMode;
+ ui3p pTo_OneVidParams;
+#if 0 != vMacScreenDepth
+ ui3p pTo_ColorBitMode = nullpr;
+ ui3p pTo_ColorVidParams;
+#endif
+
+ pPatch = VidROM;
+
+ pAt_sRsrcDir = pPatch;
+ pTo_sRsrc_Board = ReservePatchOSLstEntry();
+ pTo_sRsrc_Video = ReservePatchOSLstEntry();
+ PatchAnEndOfLst();
+
+ PatchAReservedOSLstEntry(pTo_sRsrc_Board, 0x01 /* sRsrc_Board */);
+ pTo_BoardType = ReservePatchOSLstEntry();
+ pTo_BoardName = ReservePatchOSLstEntry();
+ PatchADatLstEntry(0x20 /* BoardId */, 0x0000764D);
+ /* 'vM', for Mini vMac */
+ pTo_VenderInfo = ReservePatchOSLstEntry();
+ PatchAnEndOfLst();
+
+ PatchAReservedOSLstEntry(pTo_BoardType, 0x01 /* sRsrcType */);
+ PatchAWord(0x0001);
+ PatchAWord(0x0000);
+ PatchAWord(0x0000);
+ PatchAWord(0x0000);
+
+ PatchAReservedOSLstEntry(pTo_BoardName, 0x02 /* sRsrcName */);
+ /*
+ 'Mini vMac video card' as ascii c string
+ (null terminated), and
+ zero padded to end aligned long.
+ */
+ PatchALong(0x4D696E69);
+ PatchALong(0x20764D61);
+ PatchALong(0x63207669);
+ PatchALong(0x64656F20);
+ PatchALong(0x63617264);
+ PatchALong(0x00000000);
+
+ PatchAReservedOSLstEntry(pTo_VenderInfo, 0x24 /* vendorInfo */);
+
+ pTo_VendorID = ReservePatchOSLstEntry();
+ pTo_RevLevel = ReservePatchOSLstEntry();
+ pTo_PartNum = ReservePatchOSLstEntry();
+ PatchAnEndOfLst();
+
+ PatchAReservedOSLstEntry(pTo_VendorID, 0x01 /* vendorId */);
+ /*
+ 'Paul C. Pratt' as ascii c string
+ (null terminated), and
+ zero padded to end aligned long.
+ */
+ PatchALong(0x5061756C);
+ PatchALong(0x20432E20);
+ PatchALong(0x50726174);
+ PatchALong(0x74000000);
+
+ PatchAReservedOSLstEntry(pTo_RevLevel, 0x03 /* revLevel */);
+ /*
+ '1.0' as ascii c string
+ (null terminated), and
+ zero padded to end aligned long.
+ */
+ PatchALong(0x312E3000);
+
+ PatchAReservedOSLstEntry(pTo_PartNum, 0x04 /* partNum */);
+ /*
+ 'TFB-1' as ascii c string
+ (null terminated), and
+ zero padded to end aligned long.
+ */
+ PatchALong(0x5446422D);
+ PatchALong(0x31000000);
+
+ PatchAReservedOSLstEntry(pTo_sRsrc_Video, 0x80 /* sRsrc_Video */);
+
+ pTo_VideoType = ReservePatchOSLstEntry();
+ pTo_VideoName = ReservePatchOSLstEntry();
+ pTo_VidDrvrDir = ReservePatchOSLstEntry();
+ PatchADatLstEntry(0x08 /* sRsrcHWDevId */, 0x00000001);
+ pTo_MinorBase = ReservePatchOSLstEntry();
+ pTo_MinorLength = ReservePatchOSLstEntry();
+#if 0
+ pTo_MajorBase = ReservePatchOSLstEntry();
+ pTo_MajorLength = ReservePatchOSLstEntry();
+#endif
+ pTo_OneBitMode = ReservePatchOSLstEntry();
+#if 0 != vMacScreenDepth
+ if (ColorModeWorks) {
+ pTo_ColorBitMode = ReservePatchOSLstEntry();
+ }
+#endif
+ PatchAnEndOfLst();
+
+ PatchAReservedOSLstEntry(pTo_VideoType, 0x01 /* sRsrcType */);
+
+ PatchAWord(0x0003); /* catDisplay */
+ PatchAWord(0x0001); /* typVideo */
+ PatchAWord(0x0001); /* drSwApple */
+ PatchAWord(0x0001); /* drHwTFB */
+
+ PatchAReservedOSLstEntry(pTo_VideoName, 0x02 /* sRsrcName */);
+ /*
+ 'Display_Video_Apple_TFB' as ascii c string
+ (null terminated), and
+ zero padded to end aligned long.
+ */
+ PatchALong(0x44697370);
+ PatchALong(0x6C61795F);
+ PatchALong(0x56696465);
+ PatchALong(0x6F5F4170);
+ PatchALong(0x706C655F);
+ PatchALong(0x54464200);
+
+ PatchAReservedOSLstEntry(pTo_MinorBase, 0x0A /* MinorBaseOS */);
+ PatchALong(0x00000000);
+
+ PatchAReservedOSLstEntry(pTo_MinorLength, 0x0B /* MinorLength */);
+ PatchALong(kVidMemRAM_Size);
+
+#if 0
+ PatchAReservedOSLstEntry(pTo_MajorBase, 0x0C /* MinorBaseOS */);
+ PatchALong(0x00000000);
+
+ PatchAReservedOSLstEntry(pTo_MajorLength, 0x0D /* MinorLength */);
+ PatchALong(kVidMemRAM_Size);
+#endif
+
+ PatchAReservedOSLstEntry(pTo_VidDrvrDir, 0x04 /* sRsrcDrvrDir */);
+ pTo_sMacOS68020 = ReservePatchOSLstEntry();
+ PatchAnEndOfLst();
+
+ PatchAReservedOSLstEntry(pTo_sMacOS68020, 0x02 /* sMacOS68020 */);
+
+ PatchALong(4 + sizeof(VidDrvr_contents) + 8);
+ MyMoveBytes((ui3p)VidDrvr_contents,
+ pPatch, sizeof(VidDrvr_contents));
+ pPatch += sizeof(VidDrvr_contents);
+ PatchAWord(kcom_callcheck);
+ PatchAWord(kExtnVideo);
+ PatchALong(kExtn_Block_Base);
+
+ PatchAReservedOSLstEntry(pTo_OneBitMode, 0x80 /* oneBitMode */);
+ pTo_OneVidParams = ReservePatchOSLstEntry();
+ PatchADatLstEntry(0x03 /* mVidParams */, 0x00000001);
+ PatchADatLstEntry(0x04 /* mDevType */, 0x00000000);
+ PatchAnEndOfLst();
+
+ PatchAReservedOSLstEntry(pTo_OneVidParams, 0x01 /* mVidParams */);
+ PatchALong(0x0000002E); /* physical Block Size */
+ PatchALong(0x00000000); /* defmBaseOffset */
+ PatchAWord(vMacScreenWidth / 8);
+ /* (Bounds.R-Bounds.L)*PixelSize/8 */
+ PatchAWord(0x0000); /* Bounds.T */
+ PatchAWord(0x0000); /* Bounds.L */
+ PatchAWord(vMacScreenHeight); /* Bounds.B */
+ PatchAWord(vMacScreenWidth); /* Bounds.R */
+ PatchAWord(0x0000); /* bmVersion */
+ PatchAWord(0x0000); /* packType not used */
+ PatchALong(0x00000000); /* packSize not used */
+ PatchALong(0x00480000); /* bmHRes */
+ PatchALong(0x00480000); /* bmVRes */
+ PatchAWord(0x0000); /* bmPixelType */
+ PatchAWord(0x0001); /* bmPixelSize */
+ PatchAWord(0x0001); /* bmCmpCount */
+ PatchAWord(0x0001); /* bmCmpSize */
+ PatchALong(0x00000000); /* bmPlaneBytes */
+
+#if 0 != vMacScreenDepth
+ if (ColorModeWorks) {
+
+ PatchAReservedOSLstEntry(pTo_ColorBitMode, 0x81);
+ pTo_ColorVidParams = ReservePatchOSLstEntry();
+ PatchADatLstEntry(0x03 /* mVidParams */, 0x00000001);
+ PatchADatLstEntry(0x04 /* mDevType */,
+ (vMacScreenDepth < 4) ? 0x00000000 : 0x00000002);
+ /* 2 for direct devices, according to Basilisk II */
+ PatchAnEndOfLst();
+
+ PatchAReservedOSLstEntry(pTo_ColorVidParams, 0x01);
+ PatchALong(0x0000002E); /* physical Block Size */
+ PatchALong(0x00000000); /* defmBaseOffset */
+ PatchAWord(vMacScreenByteWidth);
+ PatchAWord(0x0000); /* Bounds.T */
+ PatchAWord(0x0000); /* Bounds.L */
+ PatchAWord(vMacScreenHeight); /* Bounds.B */
+ PatchAWord(vMacScreenWidth); /* Bounds.R */
+ PatchAWord(0x0000); /* bmVersion */
+ PatchAWord(0x0000); /* packType not used */
+ PatchALong(0x00000000); /* packSize not used */
+ PatchALong(0x00480000); /* bmHRes */
+ PatchALong(0x00480000); /* bmVRes */
+ PatchAWord((vMacScreenDepth < 4) ? 0x0000 : 0x0010);
+ /* bmPixelType */
+ PatchAWord(1 << vMacScreenDepth); /* bmPixelSize */
+ PatchAWord((vMacScreenDepth < 4) ? 0x0001 : 0x0003);
+ /* bmCmpCount */
+#if 4 == vMacScreenDepth
+ PatchAWord(0x0005); /* bmCmpSize */
+#elif 5 == vMacScreenDepth
+ PatchAWord(0x0008); /* bmCmpSize */
+#else
+ PatchAWord(1 << vMacScreenDepth); /* bmCmpSize */
+#endif
+ PatchALong(0x00000000); /* bmPlaneBytes */
+
+ }
+#endif
+
+ UsedSoFar = (pPatch - VidROM) + 20;
+ if (UsedSoFar > kVidROM_Size) {
+ ReportAbnormalID(0x0A01, "kVidROM_Size to small");
+ return falseblnr;
+ }
+
+ for (i = kVidROM_Size - UsedSoFar; --i >= 0; ) {
+ PatchAByte(0);
+ }
+
+ pPatch = (kVidROM_Size - 20) + VidROM;
+ PatchALong((pAt_sRsrcDir - pPatch) & 0x00FFFFFF);
+ PatchALong(/* 0x0000041E */ kVidROM_Size);
+ PatchALong(0x00000000);
+ PatchAByte(0x01);
+ PatchAByte(0x01);
+ PatchALong(0x5A932BC7);
+ PatchAByte(0x00);
+ PatchAByte(0x0F);
+
+ ChecksumSlotROM();
+
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ CLUT_reds[0] = 0xFFFF;
+ CLUT_greens[0] = 0xFFFF;
+ CLUT_blues[0] = 0xFFFF;
+ CLUT_reds[CLUT_size - 1] = 0;
+ CLUT_greens[CLUT_size - 1] = 0;
+ CLUT_blues[CLUT_size - 1] = 0;
+#endif
+
+ return trueblnr;
+}
+
+IMPORTPROC Vid_VBLinterrupt_PulseNotify(void);
+
+GLOBALPROC Vid_Update(void)
+{
+ if (! Vid_VBLintunenbl) {
+ Vid_VBLinterrupt = 0;
+ Vid_VBLinterrupt_PulseNotify();
+ }
+}
+
+LOCALFUNC ui4r Vid_GetMode(void)
+{
+ return
+#if 0 != vMacScreenDepth
+ UseColorMode ? 129 :
+#endif
+ 128;
+}
+
+LOCALFUNC tMacErr Vid_SetMode(ui4r v)
+{
+#if 0 == vMacScreenDepth
+ UnusedParam(v);
+#else
+ if (UseColorMode != ((v != 128) && ColorModeWorks)) {
+ UseColorMode = ! UseColorMode;
+ ColorMappingChanged = trueblnr;
+ }
+#endif
+ return mnvm_noErr;
+}
+
+GLOBALFUNC ui4r Vid_Reset(void)
+{
+#if 0 != vMacScreenDepth
+ UseColorMode = falseblnr;
+#endif
+ return 128;
+}
+
+#define kCmndVideoFeatures 1
+#define kCmndVideoGetIntEnbl 2
+#define kCmndVideoSetIntEnbl 3
+#define kCmndVideoClearInt 4
+#define kCmndVideoStatus 5
+#define kCmndVideoControl 6
+
+#define CntrlParam_csCode 0x1A /* control/status code [word] */
+#define CntrlParam_csParam 0x1C /* operation-defined parameters */
+
+#define VDPageInfo_csMode 0
+#define VDPageInfo_csData 2
+#define VDPageInfo_csPage 6
+#define VDPageInfo_csBaseAddr 8
+
+#define VDSetEntryRecord_csTable 0
+#define VDSetEntryRecord_csStart 4
+#define VDSetEntryRecord_csCount 6
+
+#define VDGammaRecord_csGTable 0
+
+#define VidBaseAddr 0xF9900000
+ /* appears to be completely ignored */
+
+LOCALVAR blnr UseGrayTones = falseblnr;
+
+LOCALPROC FillScreenWithGrayPattern(void)
+{
+ int i;
+ int j;
+ ui5b *p1 = (ui5b *)VidMem;
+
+#if 0 != vMacScreenDepth
+ if (UseColorMode) {
+#if 1 == vMacScreenDepth
+ ui5b pat = 0xCCCCCCCC;
+#elif 2 == vMacScreenDepth
+ ui5b pat = 0xF0F0F0F0;
+#elif 3 == vMacScreenDepth
+ ui5b pat = 0xFF00FF00;
+#elif 4 == vMacScreenDepth
+ ui5b pat = 0x00007FFF;
+#elif 5 == vMacScreenDepth
+ ui5b pat = 0x00000000;
+#endif
+ for (i = vMacScreenHeight; --i >= 0; ) {
+ for (j = vMacScreenByteWidth >> 2; --j >= 0; ) {
+ *p1++ = pat;
+#if 5 == vMacScreenDepth
+ pat = (~ pat) & 0x00FFFFFF;
+#endif
+ }
+ pat = (~ pat)
+#if 4 == vMacScreenDepth
+ & 0x7FFF7FFF
+#elif 5 == vMacScreenDepth
+ & 0x00FFFFFF
+#endif
+ ;
+ }
+ } else
+#endif
+ {
+ ui5b pat = 0xAAAAAAAA;
+
+ for (i = vMacScreenHeight; --i >= 0; ) {
+ for (j = vMacScreenMonoByteWidth >> 2; --j >= 0; ) {
+ *p1++ = pat;
+ }
+ pat = ~ pat;
+ }
+ }
+}
+
+GLOBALPROC ExtnVideo_Access(CPTR p)
+{
+ tMacErr result = mnvm_controlErr;
+
+ switch (get_vm_word(p + ExtnDat_commnd)) {
+ case kCmndVersion:
+#if VID_dolog
+ dbglog_WriteNote("Video_Access kCmndVersion");
+#endif
+ put_vm_word(p + ExtnDat_version, 1);
+ result = mnvm_noErr;
+ break;
+ case kCmndVideoGetIntEnbl:
+#if VID_dolog
+ dbglog_WriteNote("Video_Access kCmndVideoGetIntEnbl");
+#endif
+ put_vm_word(p + 8,
+ Vid_VBLintunenbl ? 0 : 1);
+ result = mnvm_noErr;
+ break;
+ case kCmndVideoSetIntEnbl:
+#if VID_dolog
+ dbglog_WriteNote("Video_Access kCmndVideoSetIntEnbl");
+#endif
+ Vid_VBLintunenbl =
+ (0 == get_vm_word(p + 8))
+ ? 1 : 0;
+ result = mnvm_noErr;
+ break;
+ case kCmndVideoClearInt:
+#if VID_dolog && 0 /* frequent */
+ dbglog_WriteNote("Video_Access kCmndVideoClearInt");
+#endif
+ Vid_VBLinterrupt = 1;
+ result = mnvm_noErr;
+ break;
+ case kCmndVideoControl:
+ {
+ CPTR CntrlParams = get_vm_long(p + 8);
+ CPTR csParam =
+ get_vm_long(CntrlParams + CntrlParam_csParam);
+ ui4r csCode =
+ get_vm_word(CntrlParams + CntrlParam_csCode);
+
+ switch (csCode) {
+ case 0: /* VidReset */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoControl, VidReset");
+#endif
+ put_vm_word(csParam + VDPageInfo_csMode,
+ Vid_GetMode());
+ put_vm_word(csParam + VDPageInfo_csPage, 0);
+ /* page is always 0 */
+ put_vm_long(csParam + VDPageInfo_csBaseAddr,
+ VidBaseAddr);
+
+ result = mnvm_noErr;
+ break;
+ case 1: /* KillIO */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoControl, KillIO");
+#endif
+ result = mnvm_noErr;
+ break;
+ case 2: /* SetVidMode */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoControl, "
+ "SetVidMode");
+#endif
+ if (0 != get_vm_word(
+ csParam + VDPageInfo_csPage))
+ {
+ /* return mnvm_controlErr, page must be 0 */
+ ReportAbnormalID(0x0A02,
+ "SetVidMode not page 0");
+ } else {
+ result = Vid_SetMode(get_vm_word(
+ csParam + VDPageInfo_csMode));
+ put_vm_long(csParam + VDPageInfo_csBaseAddr,
+ VidBaseAddr);
+ }
+ break;
+ case 3: /* SetEntries */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoControl, "
+ "SetEntries");
+#endif
+#if (0 != vMacScreenDepth) && (vMacScreenDepth < 4)
+ if (UseColorMode) {
+ CPTR csTable = get_vm_long(
+ csParam + VDSetEntryRecord_csTable);
+ ui4r csStart = get_vm_word(
+ csParam + VDSetEntryRecord_csStart);
+ ui4r csCount = 1 + get_vm_word(
+ csParam + VDSetEntryRecord_csCount);
+
+ if (((ui4r) 0xFFFF) == csStart) {
+ int i;
+
+ result = mnvm_noErr;
+ for (i = 0; i < csCount; ++i) {
+ ui4r j = get_vm_word(csTable + 0);
+ if (j == 0) {
+ /* ignore input, leave white */
+ } else
+ if (j == CLUT_size - 1) {
+ /* ignore input, leave black */
+ } else
+ if (j >= CLUT_size) {
+ /* out of range */
+ result = mnvm_paramErr;
+ } else
+ {
+ ui4r r =
+ get_vm_word(csTable + 2);
+ ui4r g =
+ get_vm_word(csTable + 4);
+ ui4r b =
+ get_vm_word(csTable + 6);
+ CLUT_reds[j] = r;
+ CLUT_greens[j] = g;
+ CLUT_blues[j] = b;
+ }
+ csTable += 8;
+ }
+ ColorMappingChanged = trueblnr;
+ } else
+ if (csStart + csCount < csStart) {
+ /* overflow */
+ result = mnvm_paramErr;
+ } else
+ if (csStart + csCount > CLUT_size) {
+ result = mnvm_paramErr;
+ } else
+ {
+ int i;
+
+ for (i = 0; i < csCount; ++i) {
+ int j = i + csStart;
+
+ if (j == 0) {
+ /* ignore input, leave white */
+ } else
+ if (j == CLUT_size - 1) {
+ /* ignore input, leave black */
+ } else
+ {
+ ui4r r =
+ get_vm_word(csTable + 2);
+ ui4r g =
+ get_vm_word(csTable + 4);
+ ui4r b =
+ get_vm_word(csTable + 6);
+ CLUT_reds[j] = r;
+ CLUT_greens[j] = g;
+ CLUT_blues[j] = b;
+ }
+ csTable += 8;
+ }
+ ColorMappingChanged = trueblnr;
+ result = mnvm_noErr;
+ }
+ } else
+#endif
+ {
+ /* not implemented */
+ }
+ break;
+ case 4: /* SetGamma */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoControl, SetGamma");
+#endif
+ {
+#if 0
+ CPTR csTable = get_vm_long(
+ csParam + VDGammaRecord_csGTable);
+ /* not implemented */
+#endif
+ }
+#if 0
+ ReportAbnormalID(0x0A03,
+ "Video_Access SetGamma not implemented");
+#else
+ result = mnvm_noErr;
+#endif
+ break;
+ case 5: /* GrayScreen */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoControl, "
+ "GrayScreen");
+#endif
+ {
+#if 0
+ ui4r csPage = get_vm_word(
+ csParam + VDPageInfo_csPage);
+ /* not implemented */
+#endif
+ FillScreenWithGrayPattern();
+ result = mnvm_noErr;
+ }
+ break;
+ case 6: /* SetGray */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoControl, SetGray");
+#endif
+ {
+ ui3r csMode = get_vm_byte(
+ csParam + VDPageInfo_csMode);
+ /*
+ "Designing Cards and Drivers" book
+ says this is a word, but it seems
+ to be a byte.
+ */
+
+ UseGrayTones = (csMode != 0);
+ result = mnvm_noErr;
+ }
+ break;
+ case 9: /* SetDefaultMode */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoControl, "
+ "SetDefaultMode");
+#endif
+ /* not handled yet */
+ /*
+ seen when close Monitors control panel
+ in system 7.5.5
+ */
+ break;
+ case 16: /* SavePreferredConfiguration */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoControl, "
+ "SavePreferredConfiguration");
+#endif
+ /* not handled yet */
+ /*
+ seen when close Monitors control panel
+ in system 7.5.5
+ */
+ break;
+ default:
+ ReportAbnormalID(0x0A04,
+ "kCmndVideoControl, unknown csCode");
+#if dbglog_HAVE
+ dbglog_writelnNum("csCode", csCode);
+#endif
+ break;
+ }
+ }
+ break;
+ case kCmndVideoStatus:
+ {
+ CPTR CntrlParams = get_vm_long(p + 8);
+ CPTR csParam = get_vm_long(
+ CntrlParams + CntrlParam_csParam);
+ ui4r csCode = get_vm_word(
+ CntrlParams + CntrlParam_csCode);
+
+ result = mnvm_statusErr;
+ switch (csCode) {
+ case 2: /* GetMode */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus, GetMode");
+#endif
+ put_vm_word(csParam + VDPageInfo_csMode,
+ Vid_GetMode());
+ put_vm_word(csParam + VDPageInfo_csPage, 0);
+ /* page is always 0 */
+ put_vm_long(csParam + VDPageInfo_csBaseAddr,
+ VidBaseAddr);
+ result = mnvm_noErr;
+ break;
+ case 3: /* GetEntries */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus, "
+ "GetEntries");
+#endif
+ {
+#if 0
+ CPTR csTable = get_vm_long(
+ csParam + VDSetEntryRecord_csTable);
+ put_vm_word(
+ csParam + VDSetEntryRecord_csStart,
+ csStart);
+ put_vm_word(
+ csParam + VDSetEntryRecord_csCount,
+ csCount);
+#endif
+ ReportAbnormalID(0x0A05,
+ "GetEntries not implemented");
+ }
+ break;
+ case 4: /* GetPages */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus, GetPages");
+#endif
+ put_vm_word(csParam + VDPageInfo_csPage, 1);
+ /* always 1 page */
+ result = mnvm_noErr;
+ break;
+ case 5: /* GetPageAddr */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus,"
+ " GetPageAddr");
+#endif
+ {
+ ui4r csPage = get_vm_word(
+ csParam + VDPageInfo_csPage);
+ if (0 != csPage) {
+ /*
+ return mnvm_statusErr,
+ page must be 0
+ */
+ } else {
+ put_vm_long(
+ csParam + VDPageInfo_csBaseAddr,
+ VidBaseAddr);
+ result = mnvm_noErr;
+ }
+ }
+ break;
+ case 6: /* GetGray */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus, GetGray");
+#endif
+ put_vm_word(csParam + VDPageInfo_csMode,
+ UseGrayTones ? 0x0100 : 0);
+ /*
+ "Designing Cards and Drivers" book
+ says this is a word, but it seems
+ to be a byte.
+ */
+ result = mnvm_noErr;
+ break;
+ case 8: /* GetGamma */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus, "
+ "GetGamma");
+#endif
+ /* not handled yet */
+ /*
+ seen when close Monitors control panel
+ in system 7.5.5
+ */
+ break;
+ case 9: /* GetDefaultMode */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus, "
+ "GetDefaultMode");
+#endif
+ /* not handled yet */
+ /* seen in System 7.5.5 boot */
+ break;
+ case 10: /* GetCurrentMode */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus, "
+ "GetCurrentMode");
+#endif
+#if 0
+ put_vm_word(csParam + VDPageInfo_csMode,
+ Vid_GetMode());
+ put_vm_long(csParam + VDPageInfo_csData, 0);
+ /* what is this ? */
+ put_vm_word(csParam + VDPageInfo_csPage, 0);
+ /* page is always 0 */
+ put_vm_long(csParam + VDPageInfo_csBaseAddr,
+ VidBaseAddr);
+
+ result = mnvm_noErr;
+#endif
+ break;
+ case 12: /* GetConnection */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus, "
+ "GetConnection");
+#endif
+ /* not handled yet */
+ /* seen in System 7.5.5 boot */
+ break;
+ case 13: /* GetCurrentMode */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus, "
+ "GetCurrentMode");
+#endif
+ /* not handled yet */
+ /* seen in System 7.5.5 boot */
+ break;
+ case 14: /* GetModeBaseAddress */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus, "
+ "GetModeBaseAddress");
+#endif
+ /* not handled yet */
+ /*
+ seen in System 7.5.5 Monitors control panel
+ */
+ break;
+ case 16: /* GetPreferredConfiguration */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus, "
+ "GetPreferredConfiguration");
+#endif
+ /* not handled yet */
+ /* seen in System 7.5.5 boot */
+ break;
+ case 17: /* GetNextResolution */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus, "
+ "GetNextResolution");
+#endif
+ /* not handled yet */
+ /*
+ seen in System 7.5.5 monitors control panel
+ option button
+ */
+ break;
+ case 18: /* GetVideoParameters */
+#if VID_dolog
+ dbglog_WriteNote(
+ "Video_Access kCmndVideoStatus, "
+ "GetVideoParameters");
+#endif
+ /* not handled yet */
+ /* seen in System 7.5.5 boot */
+ break;
+ default:
+ ReportAbnormalID(0x0A06,
+ "Video_Access kCmndVideoStatus, "
+ "unknown csCode");
+#if dbglog_HAVE
+ dbglog_writelnNum("csCode", csCode);
+#endif
+ break;
+ }
+ }
+ break;
+ default:
+ ReportAbnormalID(0x0A07,
+ "Video_Access, unknown commnd");
+ break;
+ }
+
+ put_vm_word(p + ExtnDat_result, result);
+}
--- /dev/null
+++ b/src/VIDEMDEV.h
@@ -1,0 +1,27 @@
+/*
+ VIDEMDEV.h
+
+ Copyright (C) 2008 Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#ifdef VIDEMDEV_H
+#error "header already included"
+#else
+#define VIDEMDEV_H
+#endif
+
+EXPORTFUNC blnr Vid_Init(void);
+EXPORTFUNC ui4r Vid_Reset(void);
+EXPORTPROC Vid_Update(void);
+
+EXPORTPROC ExtnVideo_Access(CPTR p);
--- /dev/null
+++ b/src/main.r
@@ -1,0 +1,55 @@
+/*
+ main.r
+
+ Copyright (C) 2003 Philip Cummins, Richard F. Bannister,
+ Paul C. Pratt
+
+ You can redistribute this file and/or modify it under the terms
+ of version 2 of the GNU General Public License as published by
+ the Free Software Foundation. You should have received a copy
+ of the license along with this file; see the file COPYING.
+
+ This file is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ license for more details.
+*/
+
+#include "CNFGRSRC.h"
+
+/* Alerts Constants */
+
+#define kMyStandardAlert 128
+
+resource 'DITL' (kMyStandardAlert, purgeable) {
+ { /* array DITLarray: 2 elements */
+ /* [1] */
+ {177, 293, 197, 351},
+ Button {
+ enabled,
+ "OK"
+ },
+ /* [2] */
+ {10, 72, 162, 353},
+ StaticText {
+ disabled,
+ "^0\n\n^1^2^3"
+ }
+ }
+};
+
+resource 'ALRT' (kMyStandardAlert, "Non Fatal Error", purgeable) {
+ {40, 43, 249, 405},
+ kMyStandardAlert,
+ { /* array: 4 elements */
+ /* [1] */
+ OK, visible, sound1,
+ /* [2] */
+ OK, visible, sound1,
+ /* [3] */
+ OK, visible, sound1,
+ /* [4] */
+ OK, visible, sound1
+ },
+ alertPositionMainScreen
+};