Merge branch 'activegs_tests'

Conflicts:
	jni/sound.c
This commit is contained in:
James Sanford 2012-08-12 16:26:54 -07:00
commit 77af605387
79 changed files with 4248 additions and 7936 deletions

View File

@ -910,9 +910,14 @@ inst44_out_of_time_16
#else
GET_2BYTE_ARG;
/* arg & 0xff = dest bank, arg & 0xff00 = src bank */
if(psr & 0x110) {
// OG MVP should work even with no native mode - keep the warning though
printf("MVP but not native m or x!\n");
/*
halt_printf("MVP but not native m or x!\n");
break;
*/
}
CYCLES_MINUS_2
dbank = arg & 0xff;
@ -1158,8 +1163,12 @@ inst54_notnat_16
GET_2BYTE_ARG;
/* arg & 0xff = dest bank, arg & 0xff00 = src bank */
if(psr & 0x110) {
// OG MVP should work even with no native mode - keep the warning though
printf("MVP but not native m or x!\n");
/*
halt_printf("MVN but not native m or x!\n");
break;
*/
}
CYCLES_MINUS_2;
dbank = arg & 0xff;

Binary file not shown.

Binary file not shown.

View File

@ -911,8 +911,12 @@ inst44_out_of_time_8
GET_2BYTE_ARG;
/* arg & 0xff = dest bank, arg & 0xff00 = src bank */
if(psr & 0x110) {
// OG MVP should work even with no native mode - keep the warning though
printf("MVP but not native m or x!\n");
/*
halt_printf("MVP but not native m or x!\n");
break;
*/
}
CYCLES_MINUS_2
dbank = arg & 0xff;
@ -1158,8 +1162,12 @@ inst54_notnat_8
GET_2BYTE_ARG;
/* arg & 0xff = dest bank, arg & 0xff00 = src bank */
if(psr & 0x110) {
// OG MVN should work even with no native mode - keep the warning though
printf("MVN but not native m or x!\n");
/*
halt_printf("MVN but not native m or x!\n");
break;
*/
}
CYCLES_MINUS_2;
dbank = arg & 0xff;

View File

@ -4,10 +4,14 @@ include $(CLEAR_VARS)
LOCAL_CFLAGS := -DNDEBUG -DKEGS_LITTLE_ENDIAN -O2 -I.
LOCAL_MODULE := kegs
LOCAL_SRC_FILES := adb.c clock.c config.c dis.c engine_c.c scc.c iwm.c \
joystick_driver.c moremem.c paddles.c sim65816.c smartport.c \
LOCAL_SRC_FILES := adb.c clock.c config_generic.c config_kegs.c \
dis.c engine_c.c scc.c iwm.c \
joystick_dummy.c moremem.c paddles.c sim65816.c smartport.c \
sound.c sound_driver.c video.c scc_socket_driver.c scc_windriver.c \
scc_macdriver.c android_driver.c android_sound_driver.c
LOCAL_LDLIBS := -lm -llog -ljnigraphics -lOpenSLES
# To peek at the generated code:
# android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/arm-linux-androideabi-objdump -h -S -z objectfile.o
include $(BUILD_SHARED_LIBRARY)

View File

@ -1,280 +0,0 @@
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

View File

@ -1,239 +0,0 @@
KEGS's Apple //gs IWM emulation routines.
The IWM code does 5.25" and 3.5" reads & writes, and updates the Unix disk
image on writes. It is also nearly cycle-accurate--Let me know if you
have a program which can detect it's not a real Apple II. There are
a few 5.25" features missing (No 1/4 or 1/2 tracks, no support for Unix nibble
images, limited disk switching), but what's there is pretty accurate.
The low-level code support 1/4 and 1/2 tracks--it's the arm movement
and image-handling routines which don't. And lack of Unix nibble images
are also due to lack of higher-level routines to make those features work.
How my disk emulation works: The routines have a nibblized image of each
track of each drive (two 5.25" and two 3.5" drives are supported) in memory.
The nibble images are declared as arrays, but it could be made to use
more dynamic memory allocation.
Each track's data format is a series of two-byte pairs. The first byte
of the pair is the number of bits in this disk byte, and the second byte
is the value. So a size of 8 is normal. A size of 10 means that there
are 2 sync bits written before this byte on the disk. So for 5.25" disk
accesses, 40 cycles need to pass in the simulator before providing a
valid nibble. Partial nibbles are correctly formed if a read happens
too early (this actually makes things slower, but is required if you
want to make nibble copiers work). Similarly, writing to the disk
watches timing carefully to write out the correct number of bits per
disk byte. These routines will definitely test out your emulator's cycle
counting ability.
If a long delay occurs between a read (or a write) the routines skips
the correct number of bits to return the correctly formed disk byte.
After a long delay, for efficiency, I always return a full disk byte,
instead of a partial one, even if the timing would put it in the middle
of a disk byte.
The arm stepping is really lame. I will clean it up soon.
Smartport support is sufficient to claim that there are no smartport
devices. This is necessary since the ROM tries to see if there are
smartport devices at power-on.
I tested my 5.25" drive routines on EDD, which could correctly measure
drive speed and other disk factors. I also nibble-copied some disks,
which also worked fine. I tested the 3.5" routines using Copy II+,
which successfully nibble-copied several disks.
Code description:
Most code is in iwm.c, with some defines in iwm.h, and some stuff in
iwm_35_525.h.
Code only supports DOS3.3 ordered 5.25" images now, and ProDOS-ordered 3.5"
images. Well, the code supports ProDOS-order 5.25" also, but has no
mechanism to tell it an image is prodos-order yet. :-)
Iwm state is encoded in the Iwm structure.
drive525[2]: Disk structure for each 5.25" disk
drive35[2]: Disk structure for each 3.5" disk
smarport[32]: Disk structure for each "smartport" device emulated
via slot 7 (this code not included)
motor_on: True if IWM motor_on signal (c0e9) is asserted. Some
drive is on.
motor_off: True if motor has been turned off in software, but the
1 second timeout has not expired yet.
motor_on35: True if 3.5" motor is on (controlled differently than
5.25" c0e9).
motor_off_vbl_count: VBL count to turn motor off.
head35, step_direction35: 3.5" controls, useless.
iwm_phase[4]: Has '1' for each 5.25" phase that is on.
iwm_mode: IWM mode register.
drive_select: 0 = drive 1, 1 = drive 2.
q6, q7: IWM q6, q7 registers.
enable2: Smartport /ENABLE2 asserted.
reset: Smartport /RESET asserted.
previous_write_val: Partial write value.
previous_write_bits: How many bits are valid in previous_write_val.
Each disk (3.5" and 5.25") is encoded in the Disk struct:
fd: Unix file descriptor. If < 0, no disk.
name_ptr: Unix file name for this disk.
image_start: offset from beginning of file for this partition.
image_size: size of this partition.
smartport: 1 if this is a smartport image, 0 if it is 5.25" or 3.5"
disk_525: 1 if this is a 5.25" image, 0 if it is 3.5"
drive: 0 = drive 1, 1 = drive 2.
cur_qtr_track: Current qtr track. So track 1 == qtr_track 4.
For 3.5", cur_qtr_track encodes the side also, so track 3
side 1 would be qtr_track 7.
prodos_order: True if Unix image is ProDOS order.
vol_num: DOS3.3 volume number to use. Always 254.
write_prot: True if disk is write protected.
write_through_to_unix: True if writes should be passed through to
the unix image. If this is false, you can write
to the image in memory, but it won't get reflected
into the Unix file. If you create a non-DOS3.3
or ProDOS format image, it automatically sets this
false.
disk_dirty: Some track has dirty data that need to be flushed.
just_ejected: Ejection flag.
dcycs_last_read: Cycle count of last disk data register access.
last_phase: Phase number last accessed.
nib_pos: Nibble offset ptr--points to a byte.
num_tracks: Number of tracks: 140 for 5.25" and 160 for 3.5"
track[MAX_TRACKS]: nibble image of all possible tracks.
Each track is represented by the Track structure:
track_dirty: Contains data that needs to be written back to
the Unix image file.
overflow_size: Count of overflow bits, used in writing.
track_len: Number of nibbles on this track.
dsk: Handy pointer to parent Disk structure.
nib_area[]: ptr to memory containing pairs of [size,data],
encoding disk data bytes.
pad1: If the structure is 32 bytes long, some array
indexing is done better by my compiler.
Externally callable routines:
iwm_init(): Init various data structures at simulation start.
iwm_reset(): Called at Apple //gs reset time.
iwm_vbl_update(): Called every VBL (60 Hz) period. Used to turn motor
off, and flush out dirty data.
g_vbl_count is the count of VBL ticks (so it counts
at 60 times a second).
iwm_read_c0ec(double dcycs): Optimized routine to handle reading $C0EC
faster. Exactly the same as read_iwm(0xc, dcycs);
read_iwm(loc, dcycs):
Read from 0xc0e0 + loc. Loc is between 0x0 and 0xf.
Dcycs is an artifact from my simulator. Dcycs is a
double holding the number of Apple //gs cycles since the
emulator started. Dcycs always counts at 1.024MHz. If
you are running at 2.5MHz, it increments by 0.4 every
"cycle". This is a very convenient timing strategy. It
also allows emulating the delay caused by synchronizing
the fast part of a real Apple //gs with slow memory,
which means my emulator knows that reading softswitches
takes longer than reading fast memory.
write_iwm(int loc, int val, double dcycs):
Write to 0xc0e0 + loc. Just like read_iwm, but write "val" into
loc.
Tricky routines:
IWM_READ_ROUT(): called by read_iwm() if q6,q7 = 0,0.
This is actually in the file iwm_35_525.h. This is so I
write the basic code once for 5.25" and 3.5" disk reads,
but then include the file with some macros set to create
the correct function optimized for 5.25" or 3.5"
accesses. The function for 5.25" is called
iwm_read_data_525, and iwm_read_data_35 for 3.5".
Returns next disk byte.
Takes three arguments: ptr to the Disk structure for
the active drive, fast_disk_emul, and dcycs. dcycs is
so that it can see how many cycles have passed since
the last read (stored in dsk->dcycs_last_read).
16.0 dcycs need to pass for an 8 bit nibble for 3.5"
accesses, and 32.0 dcycs for an 8 bit nibble for 5.25".
Fast_disk_emul == 1 says don't mess around with accuracy,
and always return the next fully-formed nibble.
There is a lot of complexity in this routine. All IWM
routines must skip over nibbles (stored as byte pairs in
dsk->nib_area[]) which have a size of 0 (special padding
trick, described later). It then determines how much
time has passed, and so how many bits are valid.
If too many bits have gone by (11 cycs is almost 3 5.25"
bit times, which is about the nibble valid time in
the Apple //gs IWM hardware latch), it tries to skip
to the correct position.
Handles IWM latch mode for 3.5" or 5.25" accesses. If a
partial read is indicated, it ensures that the high bit
is clear by shifting the nibble to the right
appropriately. Again, nib_area[] is an array of bytes,
which are treated as pairs. Byte 0 = size, byte 1 =
disk nibble.
IWM_WRITE_ROUT(): called by write_iwm() if q6,q7 = 1,1.
Similar to above. Handles async and sync mode writes.
Handles partial writes. Handles the ROM writing
0xff, 0x3f, 0xcf, 0xf3, 0xfc to be four 10-bit nibbles.
Routine disk_nib_out(dsk, val, bits_read) does the
actual work of merging the bits into the track image.
disk_nib_out(): called by IWM_WRITE_ROUTE() and iwm_nibblize_track_*().
Writes byte into nib_area[]. If size > 10, makes it 10.
If high order bit not set, it sets it (makes certain routines
in EDD happy).
overflow_size:
Writing to the disk creates some problems. I need to
maintain 2 things at all times on the track:
1) Constant number of bits for the entire track.
2) know where each synchronized byte starts on
the track.
If the track was just stored as raw bits, then correctly
simulating a delay of 300*4 cycles is tough, since it has to
be done by reading through all 300 bits on the track,
so that we keep in sync with where bytes really start.
But if you just store the bytes themselves, then sync
bytes look like every other byte. And if you now add
the size field, you have a situation where a track could
gain or lose bits when rewritten. Here's the case:
Assume the track contains: 10,ff 10,ff 10,ff 10,ff.
(That is 4 self-sync disk bytes of 10 bits each).
If we rewrite that area of the track with 'D5 AA 96 FF',
where each byte is 8 bits, we would have:
8,D5 8,AA, 8,96, 8,FF.
Looks OK, but we just lost 8 bits! The original 4 nibbles
were using 40 bits of space on the disk. Our new 4 nibbles
are using 32 bits. 8 bits are lost.
Solution: log these missing bits via overflow_size.
When writing, if overflow_size gets > 8, force out a 0,0
nibble. So sync bytes get written as:
10,FF 10,FF 10,FF 10,FF 0,0 10,FF 10,FF 10,FF 10,FF, 0,0.
So when they get re-written with 8,xx, we don't lose any
bytes on the disk.
Unfortunately, it doesn't quite work that easily, and bits
can still be lost when sync fields are partially overwritten.
This happens when all the 0,0's end up in a place on the
track where few overwrites occur, but other sync bytes
are being turned into 8,xx. So overflow_size goes negative,
saying we've got too much on the track.
The code prints an error when it gains more than 64 bits.
If someone can come up with a better scheme, I'd love to
hear it. A partial solution would be to have a routine
re-space the track to spread the needed 0,0's around
a little better when overflow_size gets too negative.
In iwm_nibblize_track_35(), the comments with hex numbers correspond
to the ROM 01 addresses which I disassembled to determine the checksum
algorithm. The code is not well written--it's basically hand-translated
65816 assembly code. I'll clean it up someday.
Much of the code is not well-optimized. I'll get to that someday, but
the speed has been adequate for me so far.

View File

@ -1,96 +0,0 @@
KEGS Internals
--------------
The INTERNALS* files describe the internal structure of KEGS and how
it works. It is meant to be useful to those who would attempt to
port KEGS to non-Unix platforms, or just want to know how KEGS works.
Documentation files:
--------------------
INTERNALS.overview: Provides overview of KEGS's file structure
KEGS SOURCE FILES:
-----------------
adb.c: ADB emulation routines. This includes keyboard, mouse, and
joystick.
adb.h: Defines for ADB routines.
clock.c: Clock, BRAM, and some timing routines.
compile_time.c: Trick file to put the time you compiled in g_compile_time[].
defc.h: Global defines included by all .c files. Useful trick
to avoid complex multi-level include problems.
defs.h: Global defines included by all .s files (assembly language).
defcomm.h: Global defines included by all files (must be assembly and
C safe, such as #defines).
defs_instr.h: C and assembly definitions for various addressing modes
and for some repeated instructions (like LDA, STA, etc).
dis.c: Disassembler and debugger interface. The debugger interface
is similar to the Apple // monitor, but has many
more commands.
disas.h: Tables for disassembling 65816 instructions. Not very
efficient, but it works.
engine_c.c: C main instruction dispatch loop.
engine_s.s: Assembly main instruction dispatch loop.
instable.h: Instruction table. It is C and assembly-safe through
the make_inst script. make_inst turns instable.h into
8inst_c and 16inst_c, which are both valid C code.
iwm.c: IWM routines for 5.25" and 3.5" disks. See INTERNALS.iwm
iwm.h: IWM defines
iwm_35_525.h: File for reading and writing a disk byte, which is included
in iwm.c twice, once for 5.25" and again for 3.5".
Forcing out compile-time constants this way makes it
faster.
moremem.c: Awful name--this file contains the page table change
routines (fixup_*) and io_read() and io_write() to
emulate all $C000 I/O accesses.
op_routs.h: More macros for 65816 emulation.
protos.h: Prototypes for all C functions. Auto-generated through
the "cproto" program (not included).
protos_xdriver.h: Prototypes for functions in xdriver.c.
scc.c: Serial chip emulation.
scc_driver.h: Unix-specific socket routines, stubbed out if you're not
on Linux or HP-UX.
scc.h: Defines for scc.c.
sim65816.c: main() is here along with many other housekeeping
functions, such as events, and interrupts.
The main loop of KEGS is run_prog().
size_tab.h: Used by assembly for a jump table (make_size script
turns it into 8size_s and 16size_s) and by both C and
assembly to get the size of instructions.
smartport.c: Smartport emulation, emulates s7dx devices.
sound.c: Sound emulation. Builds sound samples, but does not
send sound to output device.
sound.h: Header file for sound.c.
sound_driver.c: Sound driver routines. Takes samples generated by sound.c
and sends them to the correct output device. Supports
HP Alib, HP /dev/audio, and Linux /dev/dsp currently.
superhires.h: "macro" routine used by video.c so that I could write
one generic superhires routine, but then include it
multiple times to get optimized 320 vs 640 mode routines.
video.c: Display routines. Builds 8 bit video buffers in a
device independent way. Functions here know nothing
about X windows.
xdriver.c: X windows driver routines. Takes buffers from video.c
and sends them on to X windows. Get keypresses from
X and sends them to adb.c.
Porting Advice:
--------------
To a non-unix platform, disabling scc emulation would be a good start.
Just make sure you get the dummy stub routines in scc_driver.h.
If you don't have gettimeofday(), clock.c will need to modified with
whatever timer facilities are available. A high-resolution clock works
best, but even a low-resolution clock will work.
Modify sound_driver.c to get it to compile, if necessary. Always run with
"-audio 0" to turn audio off. No routines in sound_driver.c will get
called if you run with -audio 0.
Replace xdriver.c with new routines for whatever platform you are porting to.
See INTERNALS.xdriver for more information.

View File

@ -1,148 +0,0 @@
xdriver.c contains the routines for interfacing to X windows. The rest
of KEGS interacts with X windows only through xdriver.c routines.
Externally called routines are:
show_xcolor_array(): Debug routine, it does not need to do anything.
dev_video_init(): Called at startup, it should open up the
window and do other initialization.
update_physical_colormap(): Updates the X windows palette with the colors
from xcolor_a2vid_array[], which is maintained by
other xdriver routines.
update_status_line(): Call to update the internal array of chars
representing the status lines at the bottom of
the window. Does not draw the chars to the screen.
xdriver_end(): Shutdown routine
check_input_events(): Called up to 60 times a second (see video_update() in
video.c) to handle any X window events and get
keypresses.
On a mouse press, call update_mouse() with the
new x, y coordinates, and the status of the mouse
button.
If g_warp_pointer is set, constrain mouse within
the window.
On keypress, calls handle_keysym().
handle_keysym(): Takes X keysym, and converts to the appropriate
a2code using the a2_key_to_xsym[] lookup table.
The a2codes are the Apple // ADB keycodes.
Special work is done to handle shift and control
properly since Apple only has one keycode for both
shift and control keys. Then call
adb_physical_key_update() with the a2 keycode and
is_up = 1 if keyup, 0 = if key down.
In addition, this routine handles all the Function
keys doing special actions, which should be easy to
port.
x_refresh_ximage(): Redraws the window using the a2_line_* arrays.
Described in more detail below.
update_color_array(): Interface to the color map. Sets color[col_num]
of the internal colormap array to a2_color.
a2_color is the 12 bit apple color of the form:
(red << 8) + (green << 4) + (blue).
There are 16 palettes of 16 colors each, managed as
one 256-color colormap. See discussion of
g_a2vid_palette below.
x_auto_repeat_on(): The X routines turn off key repeat when the cursor
enters the graphics window automatically, and turn
it back on when the cursor leaves. But if the
debugger gets control due to a breakpoint, keyrepeat
would be left off. So the debugger calls this
routine to make sure key repeat is back on.
redraw_status_lines(): Draw the status lines from the g_status_buf[][] array
to the graphics window.
Externally referenced data:
g_use_shmem: Set by main() to enable/disable MIT-SHM for X.
Also used by sound routines to auto-turn-off sound
if not using MIT-SHM.
Bytes representing screen data:
byte *data_text[2]: Array of bytes for the lores and text pages 1 and 2.
Just 400*640 bytes.
byte *data_hires[2]: Array of bytes for the hires pages 1 and 2.
byte *data_superhires: Array of bytes for superhires screen.
byte *data_border_sides: Array of bytes representing the border sides.
Basically just A2_WINDOW_HEIGHT*EFF_BORDER_WIDTH bytes.
byte *data_border_special: Top and bottom border bytes.
(X_A2_WINDOW_HEIGHT - A2_WINDOW_HEIGHT + 2*8) *
(X_A2_WINDOW_WIDTH) bytes.
Handles used for X windows drawing:
XImage *ximage_hires[2]: Opaque handle to XImage object for hires page 1 and
page 2.
XImage *ximage_text[2]: Text pages 1 and 2.
XImage *ximage_superhires: Superhires graphics XImage
XImage *ximage_border_special: Top and bottom border XImage.
XImage *ximage_border_sides: Left and right sides (only one copy, it is
drawn at two different locations to be both sides).
Basic operation of xdriver:
--------------------------
X windows can push arrays of bytes to the screen through structures
called XImages. An XImage is a structure describing an offscreen bitmap.
For efficiency of page flipping, KEGS maintains separate bitmaps for the
two lores/text screens, the two hires screens, and the superhires screen.
It also maintains bitmaps for the border. For MIT-SHM to work, X
requires a unique XImage for each bitmap, and the bitmap must be allocated
within xdriver.c since it must be obtained through an shmat() call.
The X code also has non-MIT-SHM code which allocates the data_* buffers
just through malloc().
All bitmaps are 8-bits of Pseudo-color. The color arrays are managed
through the update_color_array() and update_physical_colormap() routines.
KEGS manages all 256 colors in the colormap as 16 palettes of 16 colors.
One of the palettes is reserved for the 16 lores colors, and is
indicated by the variable g_a2vid_palette. It defaults to 0xe.
Update_color_array() is called to update superhires colormap entries.
Update_color_array must not update colors corresponding to g_a2vid_palette.
Update_physical_colormap() pushes the color array managed by
update_color_array() to the screen, but first forces the lores colors into
the g_a2vid_palette palette. g_installed_full_superhires_colormap is
always false in KEGS for now. video.c calls update_color_array and changes
g_a2vid_palette. No xdriver routines gets notified when g_a2vid_palette
changes, so update_physical_colormap must handle the case where
g_a2vid_palette might have changed since it was last called.
x_redraw_ximage():
Routines in video.c are free to draw into the corresponding data_*
arrays to change any byte at any time. video.c manages remembering
which lines need to be redrawn and which parts of the screen are in
which video mode via the a2_line_* arrays.
KEGS divides the video screen up into 25 groups, corresponding to each
text line. Each of these groups consists of 16 sublines. 25*8 = 400 lines.
(video.c has already doubled the vertical resolution in all video modes).
KEGS can allow any group to be from any of the five screens it manages:
The two text/lores pages, the two hires pages, and the superhires screen.
For each group, KEGS keeps track of what part of it needs to be redrawn.
g_a2_screen_buffer_changed has a bit set for each group which has changed
since the last call to x_redraw_ximage(). The rightmost bit (bit 0)
corresponds to group 0. If g_a2_screen_buffer_changed == 0, no groups
need to be redrawn. x_redraw_ximage clears out g_a2_screen_buffer_changed
after drawing the screen.
For each group, a2_line_left_edge[] and a2_line_right_edge give the pixel
offsets of what should be redrawn. a2_line_xim[] gives the ximage handle
of what needs to be redrawn. KEGS always redraws 8 verticals of a group.
g_full_refresh_needed also has one bit set in it for each group, which
indicates overriding the a2_line_*_edge functions and redraw from 0 to
640 pixels of each group that needs to be redrawn. x_redraw_ximage()
interprets this information now using a simple algorithm: Skip over
groups which have not changed (using g_a2_screen_buffer_changed).
Save the ximage of this group, the left pixel and the right pixel.
Continue with the next group if it has changed. Widen the pixel region
and keep sucking up new groups to the same ximage. At group 25, or
when the ximage changes, call x_refresh_lines to redraw this large
rectangle from this ximage. x_refresh_lines() knows the ximage
corresponding to the border for the last group has to be handled
specially since the border group is not 640*400 pixels like the others.
Other porting info:
a2_key_to_xsym[][3] contains the mapping function from X keysyms to
a2 keycodes. The first element is the a2 keycode, the second element
is the unshifted X keysym, and the third element is the shifted keysym.
A port must make the conversion to a2 keycodes, and provide up and
down events.

View File

@ -1,64 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>2mg</string>
<string>2MG</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>2mg.icns</string>
<key>CFBundleTypeName</key>
<string>Apple II 2MG Disk Image</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>a2mg</string>
</array>
<key>CFBundleTypeRole</key>
<string>None</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>kegs</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>525.icns</string>
<key>CFBundleTypeName</key>
<string>KEGS Configuration File</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>kegs</string>
</array>
<key>CFBundleTypeRole</key>
<string>None</string>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>KEGSMAC</string>
<key>CFBundleName</key>
<string>KEGSMAC</string>
<key>CFBundleIconFile</key>
<string>kegsicon.icns</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>KEGS</string>
<key>CFBundleVersion</key>
<string>0.91</string>
<key>CFBundleShortVersionString</key>
<string>KEGSMAC version 0.91</string>
<key>CFBundleGetInfoString</key>
<string>KEGSMAC v0.91, Copyright 2004 Kent Dickey, http://kegs.sourceforge.net</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright 2004 Kent Dickey</string>
</dict>
</plist>

View File

@ -1,124 +0,0 @@
# $Id: release_makefile_base,v 1.15 2003/11/21 20:00:42 kentd Exp kentd $
OBJECTS1 = adb.o clock.o config.o dis.o engine_c.o scc.o iwm.o \
joystick_driver.o moremem.o paddles.o sim65816.o smartport.o \
sound.o sound_driver.o video.o scc_socket_driver.o scc_windriver.o \
scc_macdriver.o
include vars
.SUFFIXES: .dep .proto
AS = $(CC)
XLIBS = -L/usr/X11R6/lib
PERL = perl
all: $(TARGET)
specials: 8inst_s 16inst_s 8size 16size 8inst_c 16inst_c size_c size_s
specials_clean:
rm -f 8inst_s 16inst_s 8size 16size 8inst_c 16inst_c size_c size_s
# Mac builds:
kegsmac: $(OBJECTS) compile_time.o
$(CC) $(CCOPTS) $(LDOPTS) -arch ppc $(OBJECTS) compile_time.o $(LDFLAGS) -o kegsmac $(EXTRA_LIBS) -prebind -framework Carbon -framework Quicktime
mkdir -p ../KEGSMAC.app/Contents/Resources/English.lproj/main.nib
mkdir -p ../KEGSMAC.app/Contents/MacOS
mv kegsmac ../KEGSMAC.app/Contents/MacOS/KEGSMAC
echo "APPL????" > ../KEGSMAC.app/Contents/PkgInfo
cp -f Info.plist ../KEGSMAC.app/Contents/
cp -f info.nib ../KEGSMAC.app/Contents/Resources/English.lproj/main.nib
cp -f classes.nib ../KEGSMAC.app/Contents/Resources/English.lproj/main.nib
cp -f objects.xib ../KEGSMAC.app/Contents/Resources/English.lproj/main.nib
cp -f kegsicon.icns ../KEGSMAC.app/Contents/Resources/
cp -f 525.icns ../KEGSMAC.app/Contents/Resources/
cp -f 2mg.icns ../KEGSMAC.app/Contents/Resources/
touch '../KEGSMAC.app/Icon?'
# Linux for X builds:
xkegs: $(OBJECTS) compile_time.o
$(CC) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(XLIBS) $(EXTRA_LIBS) -lX11
mv xkegs ..
# Cygwin for X builds:
kegs.exe: $(OBJECTS) compile_time.o
$(CC) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(XLIBS) $(EXTRA_LIBS) -lXext -lX11 -lm
mv kegs.exe ..
# Mingw32 (native windows) builds:
kegswin.exe: $(OBJECTS) compile_time.o
$(CC) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -lwinmm -lgdi32 -ldsound -lcomctl32 -lws2_32
mv $(NAME)$(SUFFIX) ..
8inst_c.h: instable.h
$(PERL) make_inst c 8 instable.h > 8inst_c.h
16inst_c.h: instable.h
$(PERL) make_inst c 16 instable.h > 16inst_c.h
size_c.h: size_tab.h
$(PERL) make_size c size_tab.h > size_c.h
engine_c.o: 8inst_c.h 16inst_c.h size_c.h
8inst_s.h: instable.h
$(PERL) make_inst s 8 instable.h > 8inst_s.h
16inst_s.h: instable.h
$(PERL) make_inst s 16 instable.h > 16inst_s.h
size_s.h: size_tab.h
$(PERL) make_size s size_tab.h > size_s.h
8size_s.h: size_tab.h
$(PERL) make_size 8 size_tab.h > 8size_s.h
16size_s.h: size_tab.h
$(PERL) make_size 16 size_tab.h > 16size_s.h
engine_s.o: 8inst_s.h 16inst_s.h 8size_s.h 16size_s.h size_s.h
.s.o:
$(AS) -c $(OPTS) -I. $*.s
.c.o:
$(CC) $(CCOPTS) $(XOPTS) -c $(OPTS) -I. $*.c
partls: partls.c
cc $(CCOPTS) $(XOPTS) $(OPTS) -o partls partls.c
to_pro: prodos.h prodos_protos.h to_pro.c
cc $(CCOPTS) $(XOPTS) $(OPTS) -o to_pro to_pro.c
compile_time.o: $(OBJECTS)
# dependency stuff
adb.o: adb.c adb.h defc.h defcomm.h iwm.h protos.h
engine_c.o: engine_c.c defc.h defcomm.h iwm.h protos.h protos_engine_c.h size_c.h op_routs.h defs_instr.h 8inst_c.h 16inst_c.h
clock.o: clock.c defc.h defcomm.h iwm.h protos.h
compile_time.o: compile_time.c
config.o: config.c defc.h defcomm.h iwm.h protos.h config.h
dis.o: dis.c defc.h defcomm.h iwm.h protos.h disas.h
scc.o: scc.c defc.h defcomm.h iwm.h protos.h scc.h
scc_socket_driver.o: scc_socket_driver.c defc.h defcomm.h iwm.h protos.h scc.h
scc_windriver.o: scc_windriver.c defc.h defcomm.h iwm.h protos.h scc.h
scc_macdriver.o: scc_macdriver.c defc.h defcomm.h iwm.h protos.h scc.h
iwm.o: iwm.c defc.h defcomm.h iwm.h protos.h iwm_35_525.h
joystick_driver.o: joystick_driver.c defc.h defcomm.h iwm.h protos.h
moremem.o: moremem.c defc.h defcomm.h iwm.h protos.h
paddles.o: paddles.c defc.h defcomm.h iwm.h protos.h
sim65816.o: sim65816.c defc.h defcomm.h iwm.h protos.h
smartport.o: smartport.c defc.h defcomm.h iwm.h protos.h
sound.o: sound.c defc.h defcomm.h iwm.h protos.h sound.h
sound_driver.o: sound_driver.c defc.h defcomm.h iwm.h protos.h sound.h
video.o: video.c defc.h defcomm.h iwm.h protos.h superhires.h kegsfont.h
macdriver.o: macdriver.c defc.h defcomm.h iwm.h protos.h protos_macdriver.h
macsnd_driver.o: macsnd_driver.c defc.h defcomm.h iwm.h protos.h sound.h
windriver.o: windriver.c defc.h defcomm.h iwm.h protos.h protos_windriver.h winresource.h
win32snd_driver.o: win32snd_driver.c defc.h defcomm.h iwm.h protos.h sound.h

View File

@ -1,123 +0,0 @@
# $Id: README.a2.compatibility,v 1.2 2004/10/18 18:17:21 kentd Exp $
Flobynoid: Must disable Fast Disk Emul (hit F7 to toggle it off) since
game's loader relies on the sector order on the disk (reads 8
sectors from the start without checking headers, assumes every other
physical sector is skipped due to decode delays).
Bard's Tale II GS: Doesn't recognize any save disk as a ProDOS disk.
It's detecting a "ProDOS" disk by checking for a string on block
0 at offset 0x15e. GSOS on system 6 has moved the string to 0x162,
so disks inited under GSOS will be detected as "Not a PRODOS disk".
Just make a copy of the Bard's Tale disk image to another file and
then mount that new image and remove all the files using the Finder.
Then rename the volume and you have a working save disk.
Robotron 2084:
Robot Battle:
These cracks use a "Fastloader" which is buggy.
It tries to JMP $F3D4 and expects to hit an RTS soon.
But on a IIgs it will access some illegal memory causing a code
yellow. You can just ignore the code yellow.
Beyond Castle Wolfenstein: Make sure your disk is writeable (not compressed!)
Breakout: Has trouble loading from the cracked copy.
From the BASIC prompt, do: "CALL -151" then "C083 N C083" then
"BLOAD INTBASIC" then run breakout. Then it runs fine.
Burgertime: This is a bad crack. Loader starts the game by writing
the game entry point into $0036/$0037, and then executing a BRK
instruction. The BRK handler on an old Apple II will try to write
out a message by calling through $0036/$0037, and this will start
the game. But on a IIgs, the ROM sets the $0036/$0037 vectors
back to the default, and so we crash into the monitor instead.
Here's a memory fix and a disk-image fix: From the crack screen,
press Shift-F6 (or middle mouse button) and in the KEGS debugger
window enter: "1d0a:ea 6c 36 0" and then "g". You can make
this fix to the disk image using a sector editor and change
Track $1E sector $09 offset $0A from "60 78 A9 03" to "EA 6C 36 00"
and write it back.
Caverns of Callisto: Requires old C600 ROM in slot 6 (Slot 6==Your Card).
Championship Loderunner: Requires disk to be writeable or else it starts
the level and then jumps immediately back to the title page.
Jeopardy: Disk must be writeable or else it displays "DISK ERROR" and
then crashes into the monitor.
Drol: Needs slot 6 set to "Your Card" from the IIgs control panel
(Ctrl-Cmd-ESC, then choose "Slots").
I found Drol hard, so here are some cheats. First, the standard cheat
for Drol is to have infinite lives, this cheat is to edit the disk
image:
Track $0B, Sector $0A, byte $22 to EA EA
Track $11, Sector $0A, byte $10 to EA EA
Track $17, Sector $09, byte $B2 to EA EA
I didn't create those cheats, I got it from textfiles.com.
My cheats are for the monsters to never kill you--just run right
through them.
While playing Drol, press Shift-F6 (or middle mouse button) to
enter the KEGS debugger, and then:
0/f28:18 18 # Monsters' missiles won't kill you
0/e05:90 0c # Monsters won't kill you
Continue emulation by type "g" and then enter.
Other things, like the bird, axes, swords still kill you.
To easily solve the third screen, move your man to the far right
side on the top level, so that you are directly above the woman
on the bottom row. Fly into the air "A" and then get to the KEGS
debugger, and type:
0/c:4
and then continue with "g". Now press "Z" and you will go all
the way down and land on the woman and end the level. It's
useful to have made the two above patches so that touching monsters
won't kill you.
Two more patches that only apply to level 3, and so most be made
in memory each time you enter level 3:
6cf3:18 18 18 # Axes won't kill you
6f70:38 38 # Swords/arrows won't kill you
The bird and the guy you can't kill will still kill you. These
cheats were enough to make the game easily playable.
In the game, your death is indicated by setting location $001E to
$FF. Setting breakpoints there can let you find other cheats.
Moon Patrol: Crashes into the monitor after completing checkpoint E.
To fix the Moon Patrol/Dung beetles version, from within KEGS:
BLOAD MOON PATROL
CALL -151
1E15:EA
919G
and it will work fine.
If you have the booting version that just has Moon Patrol on it,
then from any point after the crack screen is shown, enter the
KEGS debugger (Shift-F6 or middle moust button) and then enter:
0/1e15:ea
g
and then it will play fine.
The bug is that the code executes an instruction with opcode $02,
which is a NOP on 6502, but is a COP instruction to 65816. The
COP instruction acts like BRK and will crash. The patch just
makes it a real NOP.
Microbe: Crashes upon booting.
Code at $599E tries to pull a return address off of a location
beneath the stack pointer and jump to it, but it doesn't add 1
correctly so it jumps to $5917 when it meant to jump to $5918.
On a IIgs, this causes a BRK to be executed and the game to crash.
This can be patched in memory in two places:
0/599e:ba ca 9a 7d 00 01 48 98 7d 01 01 9d 01 01 60
0/6f1d:ba ca 9a 7d 00 01 48 98 7d 01 01 9d 01 01 60
The original byte sequence for both locations is:
00/599e: ba TSX
00/599f: 7d ff 00 ADC $00ff,X
00/59a2: 85 94 STA $94
00/59a4: 98 TYA
00/59a5: 7d 00 01 ADC $0100,X
00/59a8: 85 95 STA $95
00/59aa: 6c 94 00 JMP ($0094)
You can also patch the code onto the disk image. I found
the $599E version on Track $05, Sector $06, Byte $9E.
I found the $6F1D version on the image at Track $0C, Sector $00,
at byte $1D.

View File

@ -1,118 +0,0 @@
# $Id: README.compile,v 1.20 2004/10/18 04:05:14 kentd Exp $
General build instructions:
--------------------------
You need to build with a make utility. I've only tested GNU make.
There's a default Makefile, which should work for nearly any environment.
The Makefile includes a file called "vars" which defines the platform-
dependent variables. You need to make vars point to the appropriate
file for your machine.
This makes my maintenance of the diverse platforms a bit easier.
WIN32 build instructions:
------------------------
See the file README.win32 for build instructions and other information
for Microsoft Windows.
Mac OS X build instructions (the default):
------------------------------------------
KEGS is easy to compile. Just cd to the src directory and type "make".
KEGS requires perl to be in your path (or just edit the vars file to give
the full path to wherever you installed perl). Perl version 4 or 5 is
fine.
After the "make" has finished, it will create the application KEGSMAC.
To run, see README.mac.
X86 Linux build instructions:
----------------------------
Use the vars_x86linux file with:
rm vars; ln -s vars_x86linux vars
make
The resulting executable is called "xkegs".
The build scripts assume perl is in your path. If it is somewhere else,
you need to edit the "PERL = perl" line in the vars file and make it point
to the correct place.
For audio, KEGS needs access to /dev/dsp. If the permissions do not allow
KEGS to access /dev/dsp, it can fail with a cryptic error message. As root,
just do: "chmod 666 /dev/dsp".
PowerPC Linux build instructions:
----------------------------
Use the vars_linuxppc vars file by:
rm vars; ln -s vars_linuxppc vars
make
The build scripts assume perl is in your path. If it is somewhere else,
you need to edit the "PERL = perl" line in the vars file and make it point
to the correct place.
Audio is currently disabled by default, but you can try turning it on
by runnning "xkegs -audio 1". It sounds horrible to me, but sounds do
come out.
Solaris SPARC build instructions:
--------------------------------
Use the vars_solaris vars file by:
rm vars; ln -s vars_solaris vars
make
The build scripts assume perl is in your path. If it is somewhere else,
you need to edit the "PERL = perl" line in the vars file and make it point
to the correct place.
Audio is currently disabled by default, but you can try turning it on
by runnning "xkegs -audio 1".
Solaris x86 build instructions:
--------------------------------
Use the vars_x86solaris vars file by:
rm vars; ln -s vars_x86solaris vars
make
The build scripts assume perl is in your path. If it is somewhere else,
you need to edit the "PERL = perl" line in the vars file and make it point
to the correct place.
Audio is currently disabled by default, but you can try turning it on
by runnning "xkegs -audio 1".
HP-UX assembly-emulation instructions:
-------------------------------------
Use the vars_hp vars file by:
rm vars; ln -s vars_hp vars
Edit the Makefile, and remove "engine_c.o" from the "OBJECTS1=" line at
the top. Then just type "make".
This version is quite out of date and most likely does not compile any more.
Other platform "C" build instructions:
-------------------------------------
If you are porting to an X-windows and Unix-based machine, it should be
easy. Start with vars_x86linux if you are a little-endian machine, or
vars_linuxppc if you are big endian. Don't define -DKEGS_LITTLE_ENDIAN
unless your processor is little-endian (x86, Alpha). Mac, Sun, MIPS,
HP, Motorola, and IBM are big-endian.

File diff suppressed because it is too large Load Diff

View File

@ -1,252 +0,0 @@
[ This info provided by Mike Thomas <phoenyx@texas.net> ]
[ Updated 10/30/2003 by Kent: This file mentions editing "kegs.conf" to ]
[ mount images--this is now replaced by the built-in Configuration Panel. ]
Setup and configuration for x86 Linux:
--------------------------------------
KEGS is very easy to setup on your Linux box, but not foolproof. First
you will need to decide where it will live. When doing this you will
have to take into consideration any users of your machine. It really
doesn't matter where it goes but it should have it's own directory and
any supplied sub-directories should be there. You may decide to use the
/usr/local path where most systems recommend you install applications.
Again, this is entirely up to you. On my system I have a separate
partition for KEGS and all the miscellaneous files I've accumulated for
it. This makes it easy for me to reinstall the system should the need
arise. Since I fool around with a large variety of software and OS's
this happens more often than it would for normal users.
Once you have put the files into the proper place you will need to
compile it. You should not need to be 'root' to do this part. The file
README.compile explains the steps required for this. Basically all you
should need to do is set the vars link to point to the file
vars_x86linux. You will want to check the file and make sure it is
accurate for your system. On my Redhat 6.0 system the default compile
setup works fine. I use the pentium GCC compiler instead of the
supplied EGCS since it seems to build better binaries. I do not
recommend using optimization levels higher than 2. Once you have
successfully built the binaries you will need to copy them to the KEGS
directory. At a minimum copy the file kegs and to_pro.
Ok, now that you have the binaries you're almost ready. You will need a
copy of the IIgs rom placed in the KEGS directory. It should be named
ROM. You will also need some disk images. This is the hardest part.
You will need to create an HD image to work with. Kent mentions an easy
way in his readme. From the shell type this:
echo "testfile" > testfile
to_pro -16384 testfile
If you're using bash try this:
echo "testfile" > testfile
./to_pro -16384 testfile
This should create a 16 megabyte HD image. This image will NOT be properly
formatted to boot a system. The block zero is not properly setup. There is no
easy way to fix this with the current KEGS/Linux system. There seems to be a
problem formating HD files for Prodos using KEGS. The system will easily erase
them but this doesn't help you. One solution is to make the primary boot drive
use a disk partition. This is more involved and will be explained later.
Another solution is to have access to the utility Block.Warden or some other
P8 block utility. What you need to do is copy the boot blocks (blocks 0 and 1)
from any bootable disk to the HD image. With that done you can now install
GS/OS.
Make sure you set the proper file permissions on files needed by KEGS. You
will not be able to properly use it while logged on as root. KEGS uses the
file permissions to test if it should write the image to disk or the memory
image. As root, KEGS will never write the image since it thinks root
always has execute privilege. The main files which you will need read/write
access to are bram.data.1 and disk_conf. I suggest you have read access to all
the other files in the directory.
Once you've got all the proper permissions set, log onto the system with your
normal account. Start up X and a shell and cd to the KEGS directory. Assuming
you have the disk images for GS/OS edit your disk_conf file so it looks
similar to this:
# boot from install disk
s7d1 = /usr/local/fst/gsos1
# our HD image
# you should rename POOF1 file created with to_pro
# I use *.hdv to be compatible with other utilities
s7d2 = /usr/local/fst/boot.hdv
# other GSOS images
s7d3 = /usr/local/fst/gsos2
...
If you include all the GSOS images this way you will have a simple setup.
Execute KEGS. For now go with the simplest command line possible. Since the
newer versions support auto detect on video resolutions this should be the
command kegs by itself. Hopefully you will boot into the emulator. If so,
install GSOS and you're ready to go.
Sound
-----
Kent says sound doesn't work under Linux. This is partially true and much
depends on the sound system you have installed. I have been successful with
sound on both Soundblaster and Soundpro systems. For long compositions the
sound may break up but it is functional for games and system sounds.
System Video Setup
------------------
This is rather personal and based upon system hardware so I'll just give you my
thoughts and setup info on this. My normal X system is configured
@ 1152x864 15bpp due to constraints in the X server for my video system. I
have custom configured it to boot into this mode and then I change to 800x600
by using the CTRL+ALT+(keypad)PLUS sequence when I use KEGS. This makes the
system much easier to read.
KEGS and disk partitions
------------------------
Kent mentions using partitions in his readme file but doesn't go into much
details. I suspect this is mostly for accessing CD-roms. But it also works
well for HFS and Prodos formatted partitions also. Linux can also handle HFS
partitions but not Prodos. To accomplish this you will need some free space on
your hard disk to create the partitions. You should not attempt this unless you
know what you are doing. You have been warned!
This task is not easy, nor is it supported by Kent. This was done and tested
on my own system so I know it works. You will need the HFS support utilities
for Linux. These are available on several Linux software sites. The primary
need for these utilities is to change an ext2fs partition to an HFS partition.
You can also use them to format the HFS volumes and copy files to and from
the partition. Newer versions of the Linux kernel support HFS file systems but
you will still need the utilities to create the original volume.
You must decide how you want to divide this partition. You can use it all for
HFS or you can create Prodos volumes and HFS volumes. There are pros and cons
for using Prodos partitions instead of files. The pros, it is a little faster
than using an HD file. It is a real Prodos partition, formatted by KEGS. The
cons, It must be backed up by using software on the emulator. You can't just
copy the HD file to another drive.
You must weigh these pros and cons and decide for yourself. Of course you
are not limited to using partitions. I have a mix of partitions and files
which works quite well. I like the P8 partitions for holding my boot system
and applications. I back them up with GSHK to an HFS volume which I can then
transfer to another drive if I need even more security.
If you decide to use the whole partition for HFS then all you need to do is
run the HFS utilities and setup the HFS volume. Read the documentation which
comes with the utility package and follow it faithfully.
If you want to use P8 and HFS partitions you have some more work to do. If
you have never worked with low level partitions or are worried about destroying
your HD then you should probably forget this. For this to work you will have
to change the partition table on your HD. This can and most likely will ruin
any data you already have on there. I can not state this enough. Back up any
important data on the hard drive! It is possible to change the partitions in
Linux and not destroy the system. I have done this on mine but I also used
the last defined partition to make the changes and designed the system for
change should it be necessary.
For those of you who know how to handle this, take the partition you have
decided to use for KEGS and divide it into at least one 32 meg partition.
More is better but you will have to use the emulator to back up any drives
setup this way since Linux can't access a Prodos partition (yet). I have setup
4 32 meg P8 partitions and several smaller HFS partitions of about 96 megs.
The reason I use smaller HFS partitions is because HFS isn't real efficient
with larger drives, but that's another story. The reason for the separate
HFS partitions is so Linux can mount the HFS volumes like any other file system.
I find this works quite easily for accessing files instead of using the HFS
utilities. Just my opinion though. For P8 utilities you will still need to
use the HFS utility and configure the drive as an HFS volume. This lets KEGS
read the partition when it loads the partition the first time. KEGS doesn't
like the Linux file system.
Ok, everybody got their partitions defined? You want to use the HFS tools
and setup all the partitions (P8 and HFS) as HFS volumes. Next you will have
to setup the HFS partitions. No, I'm not repeating myself. This is not the same
thing as the low level partitions. HFS volumes have their own partition table.
For our purposes the table will only hold one partition on each whole volume.
The utility will give you the block count when you setup the partitions,
write it down so you don't forget. After you have the volume partition setup
you can format the drive. Yeah I know you made a Prodos partition but it
doesn't hurt anything and KEGS will be able to read the partition when it
boots up.
Well, I think I covered everything needed to set them up. Now you will need to
edit the /etc/fstab file. Make sure there are no references to the original
partition. If you want to access the HFS volumes you will need to add them to
this file. You will also need to make sure that your Linux can understand the
HFS format. Most newer kernels will as long as you've compiled it into the
kernel or set it up as a module. KEGS doesn't need these entries to access
the volumes, they are just here for your convenience. In fact, if you don't
need Linux access I suggest you either leave them out or set them up as
NOAUTO and mount them only when needed. Unmount them when finished to avoid
any potential problems also. Do not give Linux access to any P8 partitions.
For one thing it can't recognize them and most likely will give you problems
when you boot the system. For safety's sake the only partition I have listed
in my /etc/fstab is a volume called transfer. You must set the filetype to HFS
so Linux doesn't complain about the partitions if you mount them.
Ok, all partitions are defined, the /etc/fstab is setup correct, now you need
to change the permissions on the device files associated with the partitions.
This allows you to access the files as a normal user. (Thanks Kent, guess I
got too involved and forgot it should be treated like the CD). You will need
to reboot to ensure the system sees the new partitions and has the correct
/dev/hd?# device files. If you setup the partitions with fdisk you should know
the correct hd info to select the files. For the sake of example let's assume
the device is HDB and the partitions numbers are 1,2,3. From the shell,
cd /dev
chmod 666 /dev/hdb1
chmod 666 /dev/hdb2
chmod 666 /dev/hdb3
After you start KEGS you can format the Prodos partitions. If you use the
method mentioned earlier for installing GS/OS you will want to quit the
installer and run the advanced disk utilities on the utilities disk, then
quit back to the installer program or reboot.
Now I know this all sounds like a lot of trouble but (IMHO) it's worth it. For
one thing, KEGS will format a Prodos partition without problems (unlike an HD
file image) which makes a great boot system. And with GS/OS 6.01 you can access
large HFS volumes for storage and GS applications. You can also download from
the net to the HFS volume (if it's mounted) and avoid the trouble of copying
files to an image with to_pro. Not to mention the fact that the newest GNO
works with HFS drives.
One more note, if you use HFS you will need to patch the HFS fst. There is a
one byte bug which mis-calculates HFS block sizes and WILL trash your HFS
drive. The patch is at several places on the net or ask someone in one of
the comp.sys.apple2 news groups.
Miscellanea
-----------
To ease access to the KEGS binary, make an executable script which contains
any command line parms you need. Then put this script somewhere in the path
so you can execute it from any shell. Depending on the desktop you use you
may want to setup links for editing the disk_conf file also. With GNO/ME you
can launch KEGS without the shell but I don't recommend this since you won't
know what happened when it dies. With KDE you can set up the launcher to use
a shell, this is much better but until you have your setup stable you will
want to use a regular terminal so you can keep track of what's going on. Like
GNO/ME, the KDE shell will close as soon as KEGS quits with an error.
Thanks
------
I hope this info helps you enjoy KEGS. Many thanks to Kent for creating this
fine emulator and for putting up with me bugging him with 'bug' reports. Many
of these weren't actually bugs but were my own fault due to lack of knowledge
about *nix systems. But Kent was prompt in fixing the ones which truly were
bugs. Thanks to him I can now play my favorite game, Questron 2 (gs version)
which requires a player disk in slot 5. I know no other emulator which can
actually play this game.
Mike Thomas

View File

@ -1,41 +0,0 @@
MAC OS X port of KEGS (KEGSMAC): http://kegs.sourceforge.net
-------------------------------------------------------------
There is a different port of KEGS to Mac OS X called KEGS-OSX.
You can get it from http://casags.net/.
This port is not leveraged from KEGS-OSX (which is based on SDL).
This is a Mac OS X Carbon port. It will not work on Mac OS 9.
Everything pretty much works, but 8-bit color doesn't work. Make sure your
Mac is set to Thousands or Millions of colors.
Usage:
-----
Like most other KEGS versions, KEGSMAC is usually run from a Terminal
window. Just type "./KEGSMAC.app/Contents/MacOS/KEGSMAC" in the directory
you installed/compiled it in. You need to have a ROM file (named
ROM, ROM.01, or ROM.03) and a config.kegs in the same directory or in your
home directory (read the README--these files are searched for in various
places).
KEGSMAC can also be run from the Finder, but if you do this, there
will be no debug window at all. This is not well tested, yet.
To quit, either click the window close box, or select Quit from the menu.
You can also middle-click (if you have a 3-button mouse) or
Shift-F6 to get the debugger in the terminal window, and then type "q".
Compile directions
------------------
In order to compile,
1) cd into the src/ directory
2) copy vars_mac to vars
3) run make
You can contact me at kadickey@alumni.princeton.edu

View File

@ -1,52 +0,0 @@
WIN32 port of KEGS (KEGSWIN)
----------------------------
There is a different port of KEGS by Chea Chee Keong (akilgard) called
KEGS32. You can get it from http://www.geocities.com/akilgard/kegs32.
This port is leveraged from KEGS32, but mostly a rewrite (perhaps for
the worse). I am grateful for Chea for doing the windows port since I
did not know any Windows programming.
This port is alpha quality. Don't expect much.
This is a bare-bones Win32 port. It was compiled with Mingw2.0,
which you can download at: http://www.mingw.org/. I also had
previously installed cygwin at http://www.cygwin.com/. Installing
these two beasts is a bit of a pain, so I'll eventually write up
directions (I hope).
Sound works, the mouse works, and a joystick might work (ported
from KEGS32). The user-interface is just like every other KEGS
version (i.e., bad), so you can just read the standard README file.
Only tested on a 32-bit graphics display, although I think 16-bit and
24-bit will work. 8-bit definitely does not work. There are many
other bugs I just haven't had time to list yet.
Usage:
-----
Like most other KEGS versions, KEGSWIN must be run from a terminal
window (command.com is fine). Just type "KEGSWIN" in the directory
you installed/compiled it in. You need to have a ROM file (named
ROM, ROM.01, or ROM.03) and a kegs_conf in the same directory (or
read the README--these files are searched for in various places).
To quit, either click the close box, or force quit the application.
You can also middle-click (if you have a 3-button mouse) or
Shift-F6 to get the debugger in the terminal window, and then type "q".
Compile directions
------------------
In order to compile,
1) cd into the src/ directory
2) rm vars
3) ln -s vars_win32 vars
3) ./make_win
You can contact me at kadickey@alumni.princeton.edu

View File

@ -188,6 +188,11 @@ adb_init()
adb_reset();
}
// OG Added adb_shut()
void adb_shut()
{
g_adb_init = 0;
}
void
adb_reset()
@ -787,9 +792,14 @@ adb_write_c026(int val)
}
break;
default:
halt_printf("ADB ucontroller cmd %02x unknown!\n", val);
/* The Gog's says ACS Demo 2 has a bug and writes to */
/* c026 */
// OG
if (val==0x84)
printf("ACS Demo2 (3: Colum& Music scroll) : discarding unknown controller command\n");
else
halt_printf("ADB ucontroller cmd %02x unknown!\n", val);
break;
}
break;
@ -1116,6 +1126,7 @@ adb_get_keypad_xy(int get_y)
}
}
int
update_mouse(int x, int y, int button_states, int buttons_valid)
{
@ -1205,6 +1216,7 @@ update_mouse(int x, int y, int button_states, int buttons_valid)
button1_changed = (buttons_valid & 1) &&
((button_states & 1) != (g_mouse_fifo[0].buttons & 1));
if((button_states & 4) && !(g_mouse_fifo[0].buttons & 4) &&
(buttons_valid & 4)) {
/* right button pressed */
@ -1434,6 +1446,7 @@ adb_key_event(int a2code, int is_up)
int tmp_ascii;
int ascii;
if(is_up) {
adb_printf("adb_key_event, key:%02x, is up, g_key_down: %02x\n",
a2code, g_key_down);
@ -1653,7 +1666,7 @@ adb_physical_key_update(int a2code, int is_up)
/* if autopoll on, pass it on through to c025,c000 regs */
/* else only put it in kbd reg 3, and pull SRQ if needed */
adb_printf("adb_phys_key_update: %02x, %d\n", a2code, is_up);
// printf("adb_phys_key_update: %02x, %d (vbl %d)\n", a2code, is_up,g_vbl_count);
adb_printf("Handle a2code: %02x, is_up: %d\n", a2code, is_up);
@ -1705,6 +1718,8 @@ adb_physical_key_update(int a2code, int is_up)
if(special && !is_up) {
switch(special) {
// OG Disabled special keys (but warp)
#ifndef ACTIVEGS
case 0x04: /* F4 - Emulator config panel */
cfg_toggle_config_panel();
break;
@ -1720,6 +1735,7 @@ adb_physical_key_update(int a2code, int is_up)
printf("g_fast_disk_emul is now %d\n",
g_fast_disk_emul);
break;
#endif
case 0x08: /* F8 - warp pointer */
g_warp_pointer = !g_warp_pointer;
if(g_hide_pointer != g_warp_pointer) {
@ -1727,6 +1743,7 @@ adb_physical_key_update(int a2code, int is_up)
x_hide_pointer(g_hide_pointer);
}
break;
#ifndef ACTIVEGS
case 0x09: /* F9 - swap paddles */
if(SHIFT_DOWN) {
g_swap_paddles = !g_swap_paddles;
@ -1745,6 +1762,7 @@ adb_physical_key_update(int a2code, int is_up)
g_fullscreen = !g_fullscreen;
x_full_screen(g_fullscreen);
break;
#endif
}
return;
@ -1759,7 +1777,7 @@ adb_physical_key_update(int a2code, int is_up)
if(ascii > 0x30 && ascii <= 0x39) {
g_keypad_key_is_down[ascii - 0x30] = !is_up;
}
if(g_joystick_type == 0) {
if(g_joystick_type == JOYSTICK_TYPE_KEYPAD) {
/* If Joystick type is keypad, then do not let these */
/* keypress pass on further, except for cmd/opt */
if(ascii == 0x30) {

View File

@ -132,7 +132,9 @@ const int a2_key_to_ascii[][4] = {
{ 0x67, 0x800b, 0x1067, -1 }, /* F11 */
{ 0x68, -1, -1, -1 },
{ 0x69, 0x800d, 0x1069, -1 }, /* F13 */
// { 0x69, 0x800d, 0x1069, -1 }, /* F13 */
// OG remap F13 to reset
{ 0x69, 0x800c, 0x1069, -1 }, /* F13 */
{ 0x6a, -1, -1, -1 },
{ 0x6b, 0x800e, 0x106b, -1 }, /* F14 */
{ 0x6c, -1, -1, -1 },

View File

@ -459,3 +459,19 @@ check_input_events()
}
} while(event_item != NULL && keep_going);
}
// OG
void x_release_kimage(Kimage* kimage_ptr)
{
if (kimage_ptr->dev_handle == (void*)-1)
{
free(kimage_ptr->data_ptr);
kimage_ptr->data_ptr = NULL;
}
}
// OG Addding ratio
int x_calc_ratio(float x,float y)
{
return 1;
}

View File

@ -32,9 +32,6 @@ static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
static SLVolumeItf bqPlayerVolume;
#define MACSND_REBUF_SIZE (64*1024)
#define MACSND_QUANTA 512
/* MACSND_QUANTA must be >= 128 and a power of 2 */
word32 g_macsnd_rebuf[MACSND_REBUF_SIZE];
volatile word32 *g_macsnd_rebuf_ptr;
volatile word32 *g_macsnd_rebuf_cur;
@ -42,32 +39,47 @@ volatile int g_macsnd_playing = 0;
void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
{
int samps;
assert(bq == bqPlayerBufferQueue);
assert(NULL == context);
samps = g_macsnd_rebuf_ptr - g_macsnd_rebuf_cur;
if(samps < 0) {
samps += MACSND_REBUF_SIZE;
}
samps = samps & -(MACSND_QUANTA); // quantize to 1024 samples
if(g_macsnd_rebuf_cur + samps > &(g_macsnd_rebuf[MACSND_REBUF_SIZE])) {
samps = &(g_macsnd_rebuf[MACSND_REBUF_SIZE]) - g_macsnd_rebuf_cur;
}
if(samps > 0) {
g_macsnd_playing = 1;
// Read volatile items once.
word32 *buf_ptr = (word32 *)g_macsnd_rebuf_ptr; // where new data is being written
word32 *buf_cur = (word32 *)g_macsnd_rebuf_cur; // where we play from
SLresult result;
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, (char *)g_macsnd_rebuf_cur, samps * 4);
assert(SL_RESULT_SUCCESS == result);
g_macsnd_rebuf_cur += samps;
if(g_macsnd_rebuf_cur >= &(g_macsnd_rebuf[MACSND_REBUF_SIZE])) {
g_macsnd_rebuf_cur -= MACSND_REBUF_SIZE;
}
} else {
// Bail early so g_macsnd_playing can be reset.
if (buf_ptr == buf_cur) {
g_macsnd_playing = 0;
return;
}
g_macsnd_playing = 1;
// Play g_macsnd_rebuf_cur to EITHER
// g_macsnd_rebuf_ptr
// OR
// &g_macsnd_rebuf[MACSND_REBUF_SIZE]
word32 *last;
if (buf_ptr < buf_cur) {
// new data has wrapped around, only play to the end of the buffer.
last = &g_macsnd_rebuf[MACSND_REBUF_SIZE];
} else {
// play to buf_ptr
last = buf_ptr;
}
int samps;
samps = last - buf_cur;
samps = MIN(samps, 768);
// Where we'll start playing from next time.
if (&buf_cur[samps] == &g_macsnd_rebuf[MACSND_REBUF_SIZE]) {
g_macsnd_rebuf_cur = &g_macsnd_rebuf[0];
} else {
g_macsnd_rebuf_cur = &buf_cur[samps];
}
SLresult result;
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, (char *)buf_cur, samps * 4);
assert(SL_RESULT_SUCCESS == result);
}
int android_send_audio(byte *ptr, int in_size) {

4
jni/classes.nib generated
View File

@ -1,4 +0,0 @@
{
IBClasses = ();
IBVersion = 1;
}

View File

@ -20,7 +20,7 @@ const char rcsid_clock_c[] = "@(#)$KmKId: clock.c,v 1.31 2004-10-19 17:32:07-04
#endif
extern int Verbose;
extern int g_vbl_count;
extern word32 g_vbl_count; // OG change int to word32
extern int g_rom_version;
extern int g_config_kegs_update_needed;
@ -97,7 +97,7 @@ micro_sleep(double dtime)
#endif
#ifdef _WIN32
Sleep(dtime * 1000);
Sleep((DWORD)(dtime * 1000));
#else
Timer.tv_sec = 0;
Timer.tv_usec = (dtime * 1000000.0);
@ -130,14 +130,13 @@ clk_bram_set(int bram_num, int offset, int val)
g_bram[bram_num][offset] = val;
}
extern void x_clk_setup_bram_version();
void
clk_setup_bram_version()
{
if(g_rom_version < 3) {
g_bram_ptr = (&g_bram[0][0]); // ROM 01
} else {
g_bram_ptr = (&g_bram[1][0]); // ROM 03
}
x_clk_setup_bram_version();
}
void
@ -164,14 +163,29 @@ update_cur_time()
time_t cur_time;
unsigned int secs, secs2;
#ifdef UNDER_CE // OG Not supported on WIndows CE
/*
SYSTEMTIME stime;
FILETIME ftime;
GetLocalTime(&stime);
SystemTimeToFileTime(&stime,&ftime);
cur_time = ftime.dwLowDateTime;
*/
cur_time = time(0);
secs=0;
secs2=0;
#else
cur_time = time(0);
/* Figure out the timezone (effectively) by diffing two times. */
/* this is probably not right for a few hours around daylight savings*/
/* time transition */
secs2 = mktime(gmtime(&cur_time));
secs2 = (unsigned int)mktime(gmtime(&cur_time));
tm_ptr = localtime(&cur_time);
secs = mktime(tm_ptr);
secs = (unsigned int)mktime(tm_ptr);
#ifdef MAC
/* Mac OS X's mktime function modifies the tm_ptr passed in for */
@ -186,7 +200,7 @@ update_cur_time()
secs += 3600;
}
#endif
#endif
/* add in secs to make date based on Apple Jan 1, 1904 instead of */
/* Unix's Jan 1, 1970 */
/* So add in 66 years and 17 leap year days (1904 is a leap year) */

678
jni/config_generic.c Normal file
View File

@ -0,0 +1,678 @@
#include "defc.h"
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
extern int g_rom_version;
extern word32 g_mem_size_base;
extern byte *g_rom_fc_ff_ptr;
extern byte *g_rom_cards_ptr;
extern word32 g_mem_size_exp;
extern Iwm iwm;
extern int Verbose;
extern int g_track_bytes_35[];
extern int g_track_nibs_35[];
extern int g_c031_disk35;
// was in config.cpp
int g_config_control_panel = 0;
int g_config_kegs_update_needed = 0;
int g_highest_smartport_unit = -1;
word32 g_cfg_vbl_count = 0;
int g_user_page2_shadow = 1;
int g_save_cur_a2_stat = 0;
byte g_rom_c600_rom01_diffs[256] = {
0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xe2, 0x00,
0xd0, 0x50, 0x0f, 0x77, 0x5b, 0xb9, 0xc3, 0xb1,
0xb1, 0xf8, 0xcb, 0x4e, 0xb8, 0x60, 0xc7, 0x2e,
0xfc, 0xe0, 0xbf, 0x1f, 0x66, 0x37, 0x4a, 0x70,
0x55, 0x2c, 0x3c, 0xfc, 0xc2, 0xa5, 0x08, 0x29,
0xac, 0x21, 0xcc, 0x09, 0x55, 0x03, 0x17, 0x35,
0x4e, 0xe2, 0x0c, 0xe9, 0x3f, 0x9d, 0xc2, 0x06,
0x18, 0x88, 0x0d, 0x58, 0x57, 0x6d, 0x83, 0x8c,
0x22, 0xd3, 0x4f, 0x0a, 0xe5, 0xb7, 0x9f, 0x7d,
0x2c, 0x3e, 0xae, 0x7f, 0x24, 0x78, 0xfd, 0xd0,
0xb5, 0xd6, 0xe5, 0x26, 0x85, 0x3d, 0x8d, 0xc9,
0x79, 0x0c, 0x75, 0xec, 0x98, 0xcc, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00,
0x00, 0x00, 0x00, 0x39, 0x00, 0x35, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00,
0x6c, 0x44, 0xce, 0x4c, 0x01, 0x08, 0x00, 0x00
};
extern void x_config_load_roms();
extern void x_config_load_additional_roms();
void
config_load_roms()
{
int more_than_8mb;
int changed_rom;
int i;
// OG load roms
x_config_load_roms();
memset(&g_rom_cards_ptr[0], 0, 256*16);
/* initialize c600 rom to be diffs from the real ROM, to build-in */
/* Apple II compatibility without distributing ROMs */
for(i = 0; i < 256; i++) {
g_rom_cards_ptr[0x600 + i] = g_rom_fc_ff_ptr[0x3c600 + i] ^
g_rom_c600_rom01_diffs[i];
}
if(g_rom_version >= 3) {
/* some patches */
g_rom_cards_ptr[0x61b] ^= 0x40;
g_rom_cards_ptr[0x61c] ^= 0x33;
g_rom_cards_ptr[0x632] ^= 0xc0;
g_rom_cards_ptr[0x633] ^= 0x33;
}
x_config_load_additional_roms();
more_than_8mb = (g_mem_size_exp > 0x800000);
/* Only do the patch if users wants more than 8MB of expansion mem */
changed_rom = 0;
if(g_rom_version == 1) {
/* make some patches to ROM 01 */
#if 0
/* 1: Patch ROM selftest to not do speed test */
printf("Patching out speed test failures from ROM 01\n");
g_rom_fc_ff_ptr[0x3785a] = 0x18;
changed_rom = 1;
#endif
#if 0
/* 2: Patch ROM selftests not to do tests 2,4 */
/* 0 = skip, 1 = do it, test 1 is bit 0 of LSByte */
g_rom_fc_ff_ptr[0x371e9] = 0xf5;
g_rom_fc_ff_ptr[0x371ea] = 0xff;
changed_rom = 1;
#endif
if(more_than_8mb) {
/* Geoff Weiss patch to use up to 14MB of RAM */
g_rom_fc_ff_ptr[0x30302] = 0xdf;
g_rom_fc_ff_ptr[0x30314] = 0xdf;
g_rom_fc_ff_ptr[0x3031c] = 0x00;
changed_rom = 1;
}
/* Patch ROM selftest to not do ROM cksum if any changes*/
if(changed_rom) {
g_rom_fc_ff_ptr[0x37a06] = 0x18;
g_rom_fc_ff_ptr[0x37a07] = 0x18;
}
} else if(g_rom_version == 3) {
/* patch ROM 03 */
printf("Patching ROM 03 smartport bug\n");
/* 1: Patch Smartport code to fix a stupid bug */
/* that causes it to write the IWM status reg into c036, */
/* which is the system speed reg...it's "safe" since */
/* IWM status reg bit 4 must be 0 (7MHz)..., otherwise */
/* it might have turned on shadowing in all banks! */
g_rom_fc_ff_ptr[0x357c9] = 0x00;
changed_rom = 1;
#if 0
/* patch ROM 03 to not to speed test */
/* skip fast speed test */
g_rom_fc_ff_ptr[0x36ad7] = 0x18;
g_rom_fc_ff_ptr[0x36ad8] = 0x18;
changed_rom = 1;
#endif
#if 0
/* skip slow speed test */
g_rom_fc_ff_ptr[0x36ae7] = 0x18;
g_rom_fc_ff_ptr[0x36ae8] = 0x6b;
changed_rom = 1;
#endif
#if 0
/* 4: Patch ROM 03 selftests not to do tests 1-4 */
g_rom_fc_ff_ptr[0x364a9] = 0xf0;
g_rom_fc_ff_ptr[0x364aa] = 0xff;
changed_rom = 1;
#endif
/* ROM tests are in ff/6403-642x, where 6403 = addr of */
/* test 1, etc. */
if(more_than_8mb) {
/* Geoff Weiss patch to use up to 14MB of RAM */
g_rom_fc_ff_ptr[0x30b] = 0xdf;
g_rom_fc_ff_ptr[0x31d] = 0xdf;
g_rom_fc_ff_ptr[0x325] = 0x00;
changed_rom = 1;
}
if(changed_rom) {
/* patch ROM 03 selftest to not do ROM cksum */
g_rom_fc_ff_ptr[0x36cb0] = 0x18;
g_rom_fc_ff_ptr[0x36cb1] = 0x18;
}
}
}
Disk *
cfg_get_dsk_from_slot_drive(int slot, int drive)
{
Disk *dsk;
int max_drive;
/* Get dsk */
max_drive = 2;
switch(slot) {
case 5:
dsk = &(iwm.drive35[drive]);
break;
case 6:
dsk = &(iwm.drive525[drive]);
break;
default:
max_drive = MAX_C7_DISKS;
dsk = &(iwm.smartport[drive]);
}
if(drive >= max_drive) {
dsk -= drive; /* move back to drive 0 effectively */
}
return dsk;
}
void
insert_disk(int slot, int drive, const char *name, int ejected, int force_size,
const char *partition_name, int part_num)
{
byte buf_2img[512];
Disk *dsk;
char *name_ptr;
char *part_ptr;
int size;
#ifndef ACTIVEGS
char *uncomp_ptr, *system_str;
int system_len;
#endif
int part_len;
int cmp_o, cmp_p, cmp_dot;
int cmp_b, cmp_i, cmp_n;
int can_write;
int len;
int nibs;
int unix_pos;
int name_len;
int image_identified;
int exp_size;
int save_track;
int ret;
int tmp;
int i;
g_config_kegs_update_needed = 1;
if((slot < 5) || (slot > 7)) {
fatal_printf("Invalid slot for insertiing disk: %d\n", slot);
return;
}
if(drive < 0 || ((slot == 7) && (drive >= MAX_C7_DISKS)) ||
((slot < 7) && (drive > 1))) {
fatal_printf("Invalid drive for inserting disk: %d\n", drive);
return;
}
dsk = cfg_get_dsk_from_slot_drive(slot, drive);
// OG Do not insert same disk at same place
if (( dsk->name_ptr && name) && !strcmp(dsk->name_ptr,name)) return ;
#if 0
printf("Inserting disk %s (%s or %d) in slot %d, drive: %d\n", name,
partition_name, part_num, slot, drive);
#endif
dsk->just_ejected = 0;
dsk->force_size = force_size;
if(dsk->fd >= 0) {
eject_disk(dsk);
}
// OG check for valid name first
if (!name) return ;
/* Before opening, make sure no other mounted disk has this name */
/* If so, unmount it */
if(!ejected) {
for(i = 0; i < 2; i++) {
eject_named_disk(&iwm.drive525[i], name,partition_name);
eject_named_disk(&iwm.drive35[i], name, partition_name);
}
for(i = 0; i < MAX_C7_DISKS; i++) {
eject_named_disk(&iwm.smartport[i],name,partition_name);
}
}
if(dsk->name_ptr != 0) {
/* free old name_ptr */
free(dsk->name_ptr);
}
name_len = strlen(name);
name_ptr = (char *)malloc(name_len + 1);
strncpy(name_ptr, name, name_len + 1);
dsk->name_ptr = name_ptr;
dsk->partition_name = 0;
if(partition_name != 0) {
part_len = strlen(partition_name) + 1;
part_ptr = (char *)malloc(part_len);
strncpy(part_ptr, partition_name, part_len);
dsk->partition_name = part_ptr;
}
dsk->partition_num = part_num;
iwm_printf("Opening up disk image named: %s\n", name_ptr);
if(ejected) {
/* just get out of here */
dsk->fd = -1;
return;
}
dsk->fd = -1;
can_write = 1;
//OG discard .GZ support
#ifndef ACTIVEGS
if((name_len > 3) && (strcmp(&name_ptr[name_len - 3], ".gz") == 0)) {
/* it's gzip'ed, try to gunzip it, then unlink the */
/* uncompressed file */
can_write = 0;
uncomp_ptr = (char *)malloc(name_len + 1);
strncpy(uncomp_ptr, name_ptr, name_len + 1);
uncomp_ptr[name_len - 3] = 0;
system_len = 2*name_len + 100;
system_str = (char *)malloc(system_len + 1);
snprintf(system_str, system_len,
"set -o noclobber;gunzip -c %c%s%c > %c%s%c",
0x22, name_ptr, 0x22,
0x22, uncomp_ptr, 0x22);
/* 0x22 are " to allow spaces in filenames */
printf("I am uncompressing %s into %s for mounting\n",
name_ptr, uncomp_ptr);
ret = system(system_str);
if(ret == 0) {
/* successfully ran */
dsk->fd = open(uncomp_ptr, O_RDONLY | O_BINARY, 0x1b6);
iwm_printf("Opening .gz file %s is fd: %d\n",
uncomp_ptr, dsk->fd);
/* and, unlink the temporary file */
(void)unlink(uncomp_ptr);
}
free(system_str);
free(uncomp_ptr);
/* Reduce name_len by 3 so that subsequent compares for .po */
/* look at the correct chars */
name_len -= 3;
}
#endif // OG
if(dsk->fd < 0 && can_write) {
dsk->fd = open(name_ptr, O_RDWR | O_BINARY, 0x1b6);
}
if(dsk->fd < 0 && can_write) {
printf("Trying to open %s read-only, errno: %d\n", name_ptr,
errno);
dsk->fd = open(name_ptr, O_RDONLY | O_BINARY, 0x1b6);
can_write = 0;
}
iwm_printf("open returned: %d\n", dsk->fd);
if(dsk->fd < 0) {
fatal_printf("Disk image %s does not exist!\n", name_ptr);
return;
}
if(can_write != 0) {
dsk->write_prot = 0;
dsk->write_through_to_unix = 1;
} else {
dsk->write_prot = 1;
dsk->write_through_to_unix = 0;
}
save_track = dsk->cur_qtr_track; /* save arm position */
dsk->image_type = DSK_TYPE_PRODOS;
dsk->image_start = 0;
/* See if it is in 2IMG format */
ret = read(dsk->fd, (char *)&buf_2img[0], 512);
size = force_size;
if(size <= 0) {
size = cfg_get_fd_size(dsk->fd) ;
}
/* Try to guess that there is a Mac Binary header of 128 bytes */
/* See if image size & 0xfff = 0x080 which indicates extra 128 bytes */
if((size & 0xfff) == 0x080) {
printf("Assuming Mac Binary header on %s\n", dsk->name_ptr);
dsk->image_start += 0x80;
}
image_identified = 0;
if(buf_2img[0] == '2' && buf_2img[1] == 'I' && buf_2img[2] == 'M' &&
buf_2img[3] == 'G') {
// OG Put back Gilles Tschopp hack to deal with corrupted 2IMG files
size -= 64;
size = size & -0x1000;
/* It's a 2IMG disk */
printf("Image named %s is in 2IMG format\n", dsk->name_ptr);
image_identified = 1;
if(buf_2img[12] == 0) {
printf("2IMG is in DOS 3.3 sector order\n");
dsk->image_type = DSK_TYPE_DOS33;
}
if(buf_2img[19] & 0x80) {
/* disk is locked */
printf("2IMG is write protected\n");
dsk->write_prot = 1;
dsk->write_through_to_unix = 0;
}
if((buf_2img[17] & 1) && (dsk->image_type == DSK_TYPE_DOS33)) {
dsk->vol_num = buf_2img[16];
printf("Setting DOS 3.3 vol num to %d\n", dsk->vol_num);
}
// OG do not overwrite when 2mg size = 0
int size2img = (buf_2img[31] << 24) + (buf_2img[30] << 16) + (buf_2img[29] << 8) + buf_2img[28];
if (size2img) size = size2img;
else printf(".2MG has corrupted size - fixed.\n");
unix_pos = (buf_2img[27] << 24) + (buf_2img[26] << 16) +
(buf_2img[25] << 8) + buf_2img[24];
// Some 2IMG archives have the size byte reversed
if(size == 0x800c00) {
// Byte reversed 0x0c8000
size = 0x0c8000;
}
dsk->image_start = unix_pos;
dsk->image_size = size;
}
exp_size = 800*1024;
if(dsk->disk_525) {
exp_size = 140*1024;
}
if(!image_identified) {
/* See if it might be the Mac diskcopy format */
tmp = (buf_2img[0x40] << 24) + (buf_2img[0x41] << 16) +
(buf_2img[0x42] << 8) + buf_2img[0x43];
if((size >= (exp_size + 0x54)) && (tmp == exp_size)) {
/* It's diskcopy since data size field matches */
printf("Image named %s is in Mac diskcopy format\n",
dsk->name_ptr);
image_identified = 1;
dsk->image_start += 0x54;
dsk->image_size = exp_size;
dsk->image_type = DSK_TYPE_PRODOS; /* ProDOS */
}
}
if(!image_identified) {
/* Assume raw image */
dsk->image_size = size;
dsk->image_type = DSK_TYPE_PRODOS;
if(dsk->disk_525) {
dsk->image_type = DSK_TYPE_DOS33;
if(name_len >= 4) {
cmp_o = dsk->name_ptr[name_len-1];
cmp_p = dsk->name_ptr[name_len-2];
cmp_dot = dsk->name_ptr[name_len-3];
if(cmp_dot == '.' &&
(cmp_p == 'p' || cmp_p == 'P') &&
(cmp_o == 'o' || cmp_o == 'O')) {
dsk->image_type = DSK_TYPE_PRODOS;
}
cmp_b = dsk->name_ptr[name_len-1];
cmp_i = dsk->name_ptr[name_len-2];
cmp_n = dsk->name_ptr[name_len-3];
cmp_dot = dsk->name_ptr[name_len-4];
if(cmp_dot == '.' &&
(cmp_n == 'n' || cmp_n == 'N') &&
(cmp_i == 'i' || cmp_i == 'I') &&
(cmp_b == 'b' || cmp_b == 'B')) {
dsk->image_type = DSK_TYPE_NIB;
dsk->write_prot = 0; // OG : Remove WriteProtect on .nib
dsk->write_through_to_unix = 0;
}
}
}
}
dsk->disk_dirty = 0;
dsk->nib_pos = 0;
dsk->trks = 0;
if(dsk->smartport) {
g_highest_smartport_unit = MAX(dsk->drive,
g_highest_smartport_unit);
// OG Disabled partition support
#ifndef ACTIVEGS
if(partition_name != 0 || part_num >= 0) {
ret = cfg_partition_find_by_name_or_num(dsk->fd,
partition_name, part_num, dsk);
printf("partition %s (num %d) mounted, wr_prot: %d\n",
partition_name, part_num, dsk->write_prot);
if(ret < 0) {
close(dsk->fd);
dsk->fd = -1;
return;
}
}
#endif
iwm_printf("adding smartport device[%d], size:%08x, "
"img_sz:%08x\n", dsk->drive, dsk->trks[0].unix_len,
dsk->image_size);
} else if(dsk->disk_525) {
unix_pos = dsk->image_start;
size = dsk->image_size;
disk_set_num_tracks(dsk, 4*35);
len = 0x1000;
nibs = NIB_LEN_525;
if(dsk->image_type == DSK_TYPE_NIB) {
len = dsk->image_size / 35;;
nibs = len;
}
if(size != 35*len) {
fatal_printf("Disk 5.25 error: size is %d, not 140K. "
"Will try to mount anyway\n", size, 35*len);
}
for(i = 0; i < 35; i++) {
iwm_move_to_track(dsk, 4*i);
disk_unix_to_nib(dsk, 4*i, unix_pos, len, nibs);
unix_pos += len;
}
} else {
/* disk_35 */
unix_pos = dsk->image_start;
size = dsk->image_size;
if(size != 800*1024) {
fatal_printf("Disk 3.5 error: size is %d, not 800K. "
"Will try to mount anyway\n", size);
}
disk_set_num_tracks(dsk, 2*80);
for(i = 0; i < 2*80; i++) {
iwm_move_to_track(dsk, i);
len = g_track_bytes_35[i >> 5];
nibs = g_track_nibs_35[i >> 5];
iwm_printf("Trk: %d.%d = unix: %08x, %04x, %04x\n",
i>>1, i & 1, unix_pos, len, nibs);
disk_unix_to_nib(dsk, i, unix_pos, len, nibs);
unix_pos += len;
iwm_printf(" trk_len:%05x\n", dsk->trks[i].track_len);
}
}
iwm_move_to_track(dsk, save_track);
// OG send info back to the container
#ifdef ACTIVEGS
{
extern void prepareDriveInfo(Disk* dsk,int slot, int drive);
prepareDriveInfo(dsk,slot,drive);
}
#endif
}
void
eject_named_disk(Disk *dsk, const char *name, const char *partition_name)
{
if(dsk->fd < 0) {
return;
}
/* If name matches, eject the disk! */
if(!strcmp(dsk->name_ptr, name)) {
/* It matches, eject it */
if((partition_name != 0) && (dsk->partition_name != 0)) {
/* If both have partitions, and they differ, then */
/* don't eject. Otherwise, eject */
if(strcmp(dsk->partition_name, partition_name) != 0) {
/* Don't eject */
return;
}
}
eject_disk(dsk);
}
}
void
eject_disk_by_num(int slot, int drive)
{
Disk *dsk;
dsk = cfg_get_dsk_from_slot_drive(slot, drive);
eject_disk(dsk);
}
void
eject_disk(Disk *dsk)
{
int motor_on;
int i;
if(dsk->fd < 0) {
return;
}
g_config_kegs_update_needed = 1;
motor_on = iwm.motor_on;
if(g_c031_disk35 & 0x40) {
motor_on = iwm.motor_on35;
}
if(motor_on) {
halt_printf("Try eject dsk:%s, but motor_on!\n", dsk->name_ptr);
}
iwm_flush_disk_to_unix(dsk);
printf("Ejecting disk: %s\n", dsk->name_ptr);
/* Free all memory, close file */
/* free the tracks first */
if(dsk->trks != 0) {
for(i = 0; i < dsk->num_tracks; i++) {
if(dsk->trks[i].nib_area) {
free(dsk->trks[i].nib_area);
}
dsk->trks[i].nib_area = 0;
dsk->trks[i].track_len = 0;
}
free(dsk->trks);
}
dsk->num_tracks = 0;
dsk->trks = 0;
/* close file, clean up dsk struct */
close(dsk->fd);
dsk->image_start = 0;
dsk->image_size = 0;
dsk->nib_pos = 0;
dsk->disk_dirty = 0;
dsk->write_through_to_unix = 0;
dsk->write_prot = 1;
dsk->fd = -1;
dsk->just_ejected = 1;
/* Leave name_ptr valid */ // OG WHY?
// OG Free memory allocated for the disk name
if (dsk->name_ptr)
{
free(dsk->name_ptr);
dsk->name_ptr = NULL;
}
}
int
cfg_get_fd_size(int fd)
{
struct stat stat_buf;
int ret;
ret = fstat(fd, &stat_buf);
if(ret != 0) {
fprintf(stderr,"fstat returned %d on fd %d, errno: %d\n",
ret, fd, errno);
stat_buf.st_size = 0;
}
return stat_buf.st_size;
}

View File

@ -13,7 +13,17 @@ const char rcsid_config_c[] = "@(#)$KmKId: config.c,v 1.50 2004-12-04 02:05:25-0
#include "defc.h"
#include <stdarg.h>
#include "config.h"
#include <dirent.h>
// OG (Not supported Header)
#ifndef _MSC_VER
#include <dirent.h>
#else
#ifndef UNDER_CE
#include <direct.h>
#include "dirent-win32.h"
#define mode_t int
#endif
#define snprintf _snprintf
#endif
extern int Verbose;
extern word32 g_vbl_count;
@ -51,36 +61,45 @@ extern int g_joystick_trim_amount_y;
extern int g_swap_paddles;
extern int g_invert_paddles;
extern int g_screen_index[];
extern int g_screen_index[];
extern word32 g_full_refresh_needed;
extern word32 g_a2_screen_buffer_changed;
extern int g_a2_new_all_stat[];
extern int g_new_a2_stat_cur_line;
extern int g_key_down;
extern const char g_kegs_version_str[];
extern const char* g_kegs_version_str;
int g_config_control_panel = 0;
// OG Moved to generic
//int g_config_control_panel = 0;
extern int g_config_control_panel ;
char g_config_kegs_name[1024];
char g_cfg_cwd_str[CFG_PATH_MAX] = { 0 };
int g_config_kegs_auto_update = 1;
int g_config_kegs_update_needed = 0;
// OG Moved to generic
extern int g_config_kegs_update_needed ;
const char *g_config_kegs_name_list[] = {
"config.kegs", "kegs_conf", ".config.kegs", 0
};
int g_highest_smartport_unit = -1;
// OG Moved to generic
extern int g_highest_smartport_unit ;
int g_reparse_delay = 0;
int g_user_page2_shadow = 1;
// OG Moved to generic
extern int g_user_page2_shadow ;
byte g_save_text_screen_bytes[0x800];
int g_save_cur_a2_stat = 0;
// OG Moved to generic
extern int g_save_cur_a2_stat ;
char g_cfg_printf_buf[CFG_PRINTF_BUFSIZE];
char g_config_kegs_buf[CONF_BUF_LEN];
word32 g_cfg_vbl_count = 0;
// Moved to generic
extern word32 g_cfg_vbl_count ;
int g_cfg_curs_x = 0;
int g_cfg_curs_y = 0;
@ -130,10 +149,14 @@ Cfg_menu g_cfg_disk_menu[] = {
{ 0, 0, 0, 0, 0 },
};
// OG Use define instead of const for joystick_types
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
Cfg_menu g_cfg_joystick_menu[] = {
{ "Joystick Configuration", g_cfg_joystick_menu, 0, 0, CFGTYPE_MENU },
{ "Joystick Emulation,0,Keypad Joystick,1,Mouse Joystick,2,Native Joystick 1,"
"3,Native Joystick 2", KNMP(g_joystick_type), CFGTYPE_INT },
{ "Joystick Emulation,"TOSTRING(JOYSTICK_TYPE_KEYPAD)",Keypad Joystick,"TOSTRING(JOYSTICK_TYPE_MOUSE)",Mouse Joystick,"TOSTRING(JOYSTICK_TYPE_NATIVE_1)",Native Joystick 1,"
TOSTRING(JOYSTICK_TYPE_NATIVE_2)",Native Joystick 2,"TOSTRING(JOYSTICK_TYPE_NONE)",No Joystick", KNMP(g_joystick_type), CFGTYPE_INT },
{ "Joystick Scale X,0x100,Standard,0x119,+10%,0x133,+20%,"
"0x150,+30%,0xb0,-30%,0xcd,-20%,0xe7,-10%",
KNMP(g_joystick_scale_factor_x), CFGTYPE_INT },
@ -247,41 +270,6 @@ const char **g_kegs_rom_card_list[8] = {
g_kegs_c4rom_names, g_kegs_c5rom_names,
g_kegs_c6rom_names, g_kegs_c7rom_names };
byte g_rom_c600_rom01_diffs[256] = {
0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xe2, 0x00,
0xd0, 0x50, 0x0f, 0x77, 0x5b, 0xb9, 0xc3, 0xb1,
0xb1, 0xf8, 0xcb, 0x4e, 0xb8, 0x60, 0xc7, 0x2e,
0xfc, 0xe0, 0xbf, 0x1f, 0x66, 0x37, 0x4a, 0x70,
0x55, 0x2c, 0x3c, 0xfc, 0xc2, 0xa5, 0x08, 0x29,
0xac, 0x21, 0xcc, 0x09, 0x55, 0x03, 0x17, 0x35,
0x4e, 0xe2, 0x0c, 0xe9, 0x3f, 0x9d, 0xc2, 0x06,
0x18, 0x88, 0x0d, 0x58, 0x57, 0x6d, 0x83, 0x8c,
0x22, 0xd3, 0x4f, 0x0a, 0xe5, 0xb7, 0x9f, 0x7d,
0x2c, 0x3e, 0xae, 0x7f, 0x24, 0x78, 0xfd, 0xd0,
0xb5, 0xd6, 0xe5, 0x26, 0x85, 0x3d, 0x8d, 0xc9,
0x79, 0x0c, 0x75, 0xec, 0x98, 0xcc, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00,
0x00, 0x00, 0x00, 0x39, 0x00, 0x35, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00,
0x6c, 0x44, 0xce, 0x4c, 0x01, 0x08, 0x00, 0x00
};
void
config_init_menus(Cfg_menu *menuptr)
@ -563,17 +551,18 @@ config_parse_bram(char *buf, int pos, int len)
}
}
void
config_load_roms()
x_config_load_roms()
{
struct stat stat_buf;
const char **names_ptr;
int more_than_8mb;
int changed_rom;
int len;
int fd;
int ret;
int i;
g_rom_version = -1;
@ -630,21 +619,14 @@ config_load_roms()
}
close(fd);
memset(&g_rom_cards_ptr[0], 0, 256*16);
}
/* initialize c600 rom to be diffs from the real ROM, to build-in */
/* Apple II compatibility without distributing ROMs */
for(i = 0; i < 256; i++) {
g_rom_cards_ptr[0x600 + i] = g_rom_fc_ff_ptr[0x3c600 + i] ^
g_rom_c600_rom01_diffs[i];
}
if(g_rom_version >= 3) {
/* some patches */
g_rom_cards_ptr[0x61b] ^= 0x40;
g_rom_cards_ptr[0x61c] ^= 0x33;
g_rom_cards_ptr[0x632] ^= 0xc0;
g_rom_cards_ptr[0x633] ^= 0x33;
}
void x_config_load_additional_roms()
{
int i;
const char **names_ptr;
int fd,len;
int ret;
for(i = 1; i < 8; i++) {
names_ptr = g_kegs_rom_card_list[i];
@ -679,94 +661,9 @@ config_load_roms()
close(fd);
}
}
more_than_8mb = (g_mem_size_exp > 0x800000);
/* Only do the patch if users wants more than 8MB of expansion mem */
changed_rom = 0;
if(g_rom_version == 1) {
/* make some patches to ROM 01 */
#if 0
/* 1: Patch ROM selftest to not do speed test */
printf("Patching out speed test failures from ROM 01\n");
g_rom_fc_ff_ptr[0x3785a] = 0x18;
changed_rom = 1;
#endif
#if 0
/* 2: Patch ROM selftests not to do tests 2,4 */
/* 0 = skip, 1 = do it, test 1 is bit 0 of LSByte */
g_rom_fc_ff_ptr[0x371e9] = 0xf5;
g_rom_fc_ff_ptr[0x371ea] = 0xff;
changed_rom = 1;
#endif
if(more_than_8mb) {
/* Geoff Weiss patch to use up to 14MB of RAM */
g_rom_fc_ff_ptr[0x30302] = 0xdf;
g_rom_fc_ff_ptr[0x30314] = 0xdf;
g_rom_fc_ff_ptr[0x3031c] = 0x00;
changed_rom = 1;
}
/* Patch ROM selftest to not do ROM cksum if any changes*/
if(changed_rom) {
g_rom_fc_ff_ptr[0x37a06] = 0x18;
g_rom_fc_ff_ptr[0x37a07] = 0x18;
}
} else if(g_rom_version == 3) {
/* patch ROM 03 */
printf("Patching ROM 03 smartport bug\n");
/* 1: Patch Smartport code to fix a stupid bug */
/* that causes it to write the IWM status reg into c036, */
/* which is the system speed reg...it's "safe" since */
/* IWM status reg bit 4 must be 0 (7MHz)..., otherwise */
/* it might have turned on shadowing in all banks! */
g_rom_fc_ff_ptr[0x357c9] = 0x00;
changed_rom = 1;
#if 0
/* patch ROM 03 to not to speed test */
/* skip fast speed test */
g_rom_fc_ff_ptr[0x36ad7] = 0x18;
g_rom_fc_ff_ptr[0x36ad8] = 0x18;
changed_rom = 1;
#endif
#if 0
/* skip slow speed test */
g_rom_fc_ff_ptr[0x36ae7] = 0x18;
g_rom_fc_ff_ptr[0x36ae8] = 0x6b;
changed_rom = 1;
#endif
#if 0
/* 4: Patch ROM 03 selftests not to do tests 1-4 */
g_rom_fc_ff_ptr[0x364a9] = 0xf0;
g_rom_fc_ff_ptr[0x364aa] = 0xff;
changed_rom = 1;
#endif
/* ROM tests are in ff/6403-642x, where 6403 = addr of */
/* test 1, etc. */
if(more_than_8mb) {
/* Geoff Weiss patch to use up to 14MB of RAM */
g_rom_fc_ff_ptr[0x30b] = 0xdf;
g_rom_fc_ff_ptr[0x31d] = 0xdf;
g_rom_fc_ff_ptr[0x325] = 0x00;
changed_rom = 1;
}
if(changed_rom) {
/* patch ROM 03 selftest to not do ROM cksum */
g_rom_fc_ff_ptr[0x36cb0] = 0x18;
g_rom_fc_ff_ptr[0x36cb1] = 0x18;
}
}
}
void
config_parse_config_kegs_file()
{
@ -933,32 +830,6 @@ config_parse_config_kegs_file()
}
Disk *
cfg_get_dsk_from_slot_drive(int slot, int drive)
{
Disk *dsk;
int max_drive;
/* Get dsk */
max_drive = 2;
switch(slot) {
case 5:
dsk = &(iwm.drive35[drive]);
break;
case 6:
dsk = &(iwm.drive525[drive]);
break;
default:
max_drive = MAX_C7_DISKS;
dsk = &(iwm.smartport[drive]);
}
if(drive >= max_drive) {
dsk -= drive; /* move back to drive 0 effectively */
}
return dsk;
}
void
config_generate_config_kegs_name(char *outstr, int maxlen, Disk *dsk,
@ -986,6 +857,8 @@ config_generate_config_kegs_name(char *outstr, int maxlen, Disk *dsk,
str = &outstr[strlen(outstr)];
}
snprintf(str, maxlen - (str - outstr), "%s", dsk->name_ptr);
}
void
@ -1073,433 +946,6 @@ config_write_config_kegs_file()
g_config_kegs_update_needed = 0;
}
void
insert_disk(int slot, int drive, const char *name, int ejected, int force_size,
const char *partition_name, int part_num)
{
byte buf_2img[512];
Disk *dsk;
char *name_ptr, *uncomp_ptr, *system_str;
char *part_ptr;
int size;
int system_len;
int part_len;
int cmp_o, cmp_p, cmp_dot;
int cmp_b, cmp_i, cmp_n;
int can_write;
int len;
int nibs;
int unix_pos;
int name_len;
int image_identified;
int exp_size;
int save_track;
int ret;
int tmp;
int i;
g_config_kegs_update_needed = 1;
if((slot < 5) || (slot > 7)) {
fatal_printf("Invalid slot for insertiing disk: %d\n", slot);
return;
}
if(drive < 0 || ((slot == 7) && (drive >= MAX_C7_DISKS)) ||
((slot < 7) && (drive > 1))) {
fatal_printf("Invalid drive for inserting disk: %d\n", drive);
return;
}
dsk = cfg_get_dsk_from_slot_drive(slot, drive);
#if 0
printf("Inserting disk %s (%s or %d) in slot %d, drive: %d\n", name,
partition_name, part_num, slot, drive);
#endif
dsk->just_ejected = 0;
dsk->force_size = force_size;
if(dsk->fd >= 0) {
eject_disk(dsk);
}
/* Before opening, make sure no other mounted disk has this name */
/* If so, unmount it */
if(!ejected) {
for(i = 0; i < 2; i++) {
eject_named_disk(&iwm.drive525[i], name,partition_name);
eject_named_disk(&iwm.drive35[i], name, partition_name);
}
for(i = 0; i < MAX_C7_DISKS; i++) {
eject_named_disk(&iwm.smartport[i],name,partition_name);
}
}
if(dsk->name_ptr != 0) {
/* free old name_ptr */
free(dsk->name_ptr);
}
name_len = strlen(name);
name_ptr = (char *)malloc(name_len + 1);
strncpy(name_ptr, name, name_len + 1);
dsk->name_ptr = name_ptr;
dsk->partition_name = 0;
if(partition_name != 0) {
part_len = strlen(partition_name) + 1;
part_ptr = (char *)malloc(part_len);
strncpy(part_ptr, partition_name, part_len);
dsk->partition_name = part_ptr;
}
dsk->partition_num = part_num;
iwm_printf("Opening up disk image named: %s\n", name_ptr);
if(ejected) {
/* just get out of here */
dsk->fd = -1;
return;
}
dsk->fd = -1;
can_write = 1;
if((name_len > 3) && (strcmp(&name_ptr[name_len - 3], ".gz") == 0)) {
/* it's gzip'ed, try to gunzip it, then unlink the */
/* uncompressed file */
can_write = 0;
uncomp_ptr = (char *)malloc(name_len + 1);
strncpy(uncomp_ptr, name_ptr, name_len + 1);
uncomp_ptr[name_len - 3] = 0;
system_len = 2*name_len + 100;
system_str = (char *)malloc(system_len + 1);
snprintf(system_str, system_len,
"set -o noclobber;gunzip -c %c%s%c > %c%s%c",
0x22, name_ptr, 0x22,
0x22, uncomp_ptr, 0x22);
/* 0x22 are " to allow spaces in filenames */
printf("I am uncompressing %s into %s for mounting\n",
name_ptr, uncomp_ptr);
ret = system(system_str);
if(ret == 0) {
/* successfully ran */
dsk->fd = open(uncomp_ptr, O_RDONLY | O_BINARY, 0x1b6);
iwm_printf("Opening .gz file %s is fd: %d\n",
uncomp_ptr, dsk->fd);
/* and, unlink the temporary file */
(void)unlink(uncomp_ptr);
}
free(system_str);
free(uncomp_ptr);
/* Reduce name_len by 3 so that subsequent compares for .po */
/* look at the correct chars */
name_len -= 3;
}
if(dsk->fd < 0 && can_write) {
dsk->fd = open(name_ptr, O_RDWR | O_BINARY, 0x1b6);
}
if(dsk->fd < 0 && can_write) {
printf("Trying to open %s read-only, errno: %d\n", name_ptr,
errno);
dsk->fd = open(name_ptr, O_RDONLY | O_BINARY, 0x1b6);
can_write = 0;
}
iwm_printf("open returned: %d\n", dsk->fd);
if(dsk->fd < 0) {
fatal_printf("Disk image %s does not exist!\n", name_ptr);
return;
}
if(can_write != 0) {
dsk->write_prot = 0;
dsk->write_through_to_unix = 1;
} else {
dsk->write_prot = 1;
dsk->write_through_to_unix = 0;
}
save_track = dsk->cur_qtr_track; /* save arm position */
dsk->image_type = DSK_TYPE_PRODOS;
dsk->image_start = 0;
/* See if it is in 2IMG format */
ret = read(dsk->fd, (char *)&buf_2img[0], 512);
size = force_size;
if(size <= 0) {
size = cfg_get_fd_size(dsk->fd);
}
/* Try to guess that there is a Mac Binary header of 128 bytes */
/* See if image size & 0xfff = 0x080 which indicates extra 128 bytes */
if((size & 0xfff) == 0x080) {
printf("Assuming Mac Binary header on %s\n", dsk->name_ptr);
dsk->image_start += 0x80;
}
image_identified = 0;
if(buf_2img[0] == '2' && buf_2img[1] == 'I' && buf_2img[2] == 'M' &&
buf_2img[3] == 'G') {
/* It's a 2IMG disk */
printf("Image named %s is in 2IMG format\n", dsk->name_ptr);
image_identified = 1;
if(buf_2img[12] == 0) {
printf("2IMG is in DOS 3.3 sector order\n");
dsk->image_type = DSK_TYPE_DOS33;
}
if(buf_2img[19] & 0x80) {
/* disk is locked */
printf("2IMG is write protected\n");
dsk->write_prot = 1;
dsk->write_through_to_unix = 0;
}
if((buf_2img[17] & 1) && (dsk->image_type == DSK_TYPE_DOS33)) {
dsk->vol_num = buf_2img[16];
printf("Setting DOS 3.3 vol num to %d\n", dsk->vol_num);
}
// Some 2IMG archives have the size byte reversed
size = (buf_2img[31] << 24) + (buf_2img[30] << 16) +
(buf_2img[29] << 8) + buf_2img[28];
unix_pos = (buf_2img[27] << 24) + (buf_2img[26] << 16) +
(buf_2img[25] << 8) + buf_2img[24];
if(size == 0x800c00) {
// Byte reversed 0x0c8000
size = 0x0c8000;
}
dsk->image_start = unix_pos;
dsk->image_size = size;
}
exp_size = 800*1024;
if(dsk->disk_525) {
exp_size = 140*1024;
}
if(!image_identified) {
/* See if it might be the Mac diskcopy format */
tmp = (buf_2img[0x40] << 24) + (buf_2img[0x41] << 16) +
(buf_2img[0x42] << 8) + buf_2img[0x43];
if((size >= (exp_size + 0x54)) && (tmp == exp_size)) {
/* It's diskcopy since data size field matches */
printf("Image named %s is in Mac diskcopy format\n",
dsk->name_ptr);
image_identified = 1;
dsk->image_start += 0x54;
dsk->image_size = exp_size;
dsk->image_type = DSK_TYPE_PRODOS; /* ProDOS */
}
}
if(!image_identified) {
/* Assume raw image */
dsk->image_size = size;
dsk->image_type = DSK_TYPE_PRODOS;
if(dsk->disk_525) {
dsk->image_type = DSK_TYPE_DOS33;
if(name_len >= 4) {
cmp_o = dsk->name_ptr[name_len-1];
cmp_p = dsk->name_ptr[name_len-2];
cmp_dot = dsk->name_ptr[name_len-3];
if(cmp_dot == '.' &&
(cmp_p == 'p' || cmp_p == 'P') &&
(cmp_o == 'o' || cmp_o == 'O')) {
dsk->image_type = DSK_TYPE_PRODOS;
}
cmp_b = dsk->name_ptr[name_len-1];
cmp_i = dsk->name_ptr[name_len-2];
cmp_n = dsk->name_ptr[name_len-3];
cmp_dot = dsk->name_ptr[name_len-4];
if(cmp_dot == '.' &&
(cmp_n == 'n' || cmp_n == 'N') &&
(cmp_i == 'i' || cmp_i == 'I') &&
(cmp_b == 'b' || cmp_b == 'B')) {
dsk->image_type = DSK_TYPE_NIB;
dsk->write_prot = 1;
dsk->write_through_to_unix = 0;
}
}
}
}
dsk->disk_dirty = 0;
dsk->nib_pos = 0;
dsk->trks = 0;
if(dsk->smartport) {
g_highest_smartport_unit = MAX(dsk->drive,
g_highest_smartport_unit);
if(partition_name != 0 || part_num >= 0) {
ret = cfg_partition_find_by_name_or_num(dsk->fd,
partition_name, part_num, dsk);
printf("partition %s (num %d) mounted, wr_prot: %d\n",
partition_name, part_num, dsk->write_prot);
if(ret < 0) {
close(dsk->fd);
dsk->fd = -1;
return;
}
}
iwm_printf("adding smartport device[%d], size:%08x, "
"img_sz:%08x\n", dsk->drive, dsk->trks[0].unix_len,
dsk->image_size);
} else if(dsk->disk_525) {
unix_pos = dsk->image_start;
size = dsk->image_size;
disk_set_num_tracks(dsk, 4*35);
len = 0x1000;
nibs = NIB_LEN_525;
if(dsk->image_type == DSK_TYPE_NIB) {
len = dsk->image_size / 35;;
nibs = len;
}
if(size != 35*len) {
fatal_printf("Disk 5.25 error: size is %d, not 140K. "
"Will try to mount anyway\n", size, 35*len);
}
for(i = 0; i < 35; i++) {
iwm_move_to_track(dsk, 4*i);
disk_unix_to_nib(dsk, 4*i, unix_pos, len, nibs);
unix_pos += len;
}
} else {
/* disk_35 */
unix_pos = dsk->image_start;
size = dsk->image_size;
if(size != 800*1024) {
fatal_printf("Disk 3.5 error: size is %d, not 800K. "
"Will try to mount anyway\n", size);
}
disk_set_num_tracks(dsk, 2*80);
for(i = 0; i < 2*80; i++) {
iwm_move_to_track(dsk, i);
len = g_track_bytes_35[i >> 5];
nibs = g_track_nibs_35[i >> 5];
iwm_printf("Trk: %d.%d = unix: %08x, %04x, %04x\n",
i>>1, i & 1, unix_pos, len, nibs);
disk_unix_to_nib(dsk, i, unix_pos, len, nibs);
unix_pos += len;
iwm_printf(" trk_len:%05x\n", dsk->trks[i].track_len);
}
}
iwm_move_to_track(dsk, save_track);
}
void
eject_named_disk(Disk *dsk, const char *name, const char *partition_name)
{
if(dsk->fd < 0) {
return;
}
/* If name matches, eject the disk! */
if(!strcmp(dsk->name_ptr, name)) {
/* It matches, eject it */
if((partition_name != 0) && (dsk->partition_name != 0)) {
/* If both have partitions, and they differ, then */
/* don't eject. Otherwise, eject */
if(strcmp(dsk->partition_name, partition_name) != 0) {
/* Don't eject */
return;
}
}
eject_disk(dsk);
}
}
void
eject_disk_by_num(int slot, int drive)
{
Disk *dsk;
dsk = cfg_get_dsk_from_slot_drive(slot, drive);
eject_disk(dsk);
}
void
eject_disk(Disk *dsk)
{
int motor_on;
int i;
if(dsk->fd < 0) {
return;
}
g_config_kegs_update_needed = 1;
motor_on = iwm.motor_on;
if(g_c031_disk35 & 0x40) {
motor_on = iwm.motor_on35;
}
if(motor_on) {
halt_printf("Try eject dsk:%s, but motor_on!\n", dsk->name_ptr);
}
iwm_flush_disk_to_unix(dsk);
printf("Ejecting disk: %s\n", dsk->name_ptr);
/* Free all memory, close file */
/* free the tracks first */
if(dsk->trks != 0) {
for(i = 0; i < dsk->num_tracks; i++) {
if(dsk->trks[i].nib_area) {
free(dsk->trks[i].nib_area);
}
dsk->trks[i].nib_area = 0;
dsk->trks[i].track_len = 0;
}
free(dsk->trks);
}
dsk->num_tracks = 0;
dsk->trks = 0;
/* close file, clean up dsk struct */
close(dsk->fd);
dsk->image_start = 0;
dsk->image_size = 0;
dsk->nib_pos = 0;
dsk->disk_dirty = 0;
dsk->write_through_to_unix = 0;
dsk->write_prot = 1;
dsk->fd = -1;
dsk->just_ejected = 1;
/* Leave name_ptr valid */
}
int
cfg_get_fd_size(int fd)
{
struct stat stat_buf;
int ret;
ret = fstat(fd, &stat_buf);
if(ret != 0) {
fprintf(stderr,"fstat returned %d on fd %d, errno: %d\n",
ret, fd, errno);
stat_buf.st_size = 0;
}
return stat_buf.st_size;
}
int
cfg_partition_read_block(int fd, void *buf, int blk, int blk_size)
@ -1987,9 +1433,9 @@ cfg_parse_menu(Cfg_menu *menuptr, int menu_pos, int highlight_pos, int change)
defval = -1;
curstr = 0;
if(type == CFGTYPE_INT) {
iptr = menuptr->ptr;
iptr = (int*)menuptr->ptr; // OG Added cast
curval = *iptr;
iptr = menuptr->defptr;
iptr = (int*)menuptr->defptr; // OG Added cast
defval = *iptr;
if(curval == defval) {
g_cfg_opt_buf[3] = 'D'; /* checkmark */
@ -2063,14 +1509,14 @@ cfg_parse_menu(Cfg_menu *menuptr, int menu_pos, int highlight_pos, int change)
} else {
if(type == CFGTYPE_INT) {
str = &(g_cfg_opts_strs[0][0]);
snprintf(str, CFG_OPT_MAXSTR, "%d", curval);
snprintf(str, CFG_OPT_MAXSTR, "%d", curval); // OG
} else if (type == CFGTYPE_DISK) {
str = &(g_cfg_opts_strs[0][0]),
cfg_get_disk_name(str, CFG_OPT_MAXSTR, type_ext, 1);
str = cfg_shorten_filename(str, 68);
} else if (type == CFGTYPE_FILE) {
str = &(g_cfg_opts_strs[0][0]);
snprintf(str, CFG_OPT_MAXSTR, "%s", curstr);
snprintf(str, CFG_OPT_MAXSTR, "%s", curstr); // OG
str = cfg_shorten_filename(str, 68);
} else {
str = "";
@ -2258,10 +1704,10 @@ cfg_file_add_dirent(Cfg_listhdr *listhdrptr, const char *nameptr, int is_dir,
inc_amt = MAX(64, listhdrptr->max);
inc_amt = MIN(inc_amt, 1024);
listhdrptr->max += inc_amt;
listhdrptr->direntptr = realloc(listhdrptr->direntptr,
listhdrptr->direntptr = (Cfg_dirent*)realloc(listhdrptr->direntptr,
listhdrptr->max * sizeof(Cfg_dirent));
}
ptr = malloc(namelen+1+is_dir);
ptr = (char*)malloc(namelen+1+is_dir); // OG Added cast
strncpy(ptr, nameptr, namelen+1);
if(is_dir) {
strcat(ptr, "/");
@ -2288,7 +1734,9 @@ cfg_dirent_sortfn(const void *obj1, const void *obj2)
direntptr1 = (const Cfg_dirent *)obj1;
direntptr2 = (const Cfg_dirent *)obj2;
#if defined(MAC) || defined(_WIN32)
ret = strcasecmp(direntptr1->name, direntptr2->name);
// OG
ret = 0;
// ret = strcasecmp(direntptr1->name, direntptr2->name);
#else
ret = strcmp(direntptr1->name, direntptr2->name);
#endif
@ -2369,7 +1817,7 @@ cfg_file_readdir(const char *pathptr)
if(ret == 0) {
fmt = stat_buf.st_mode & S_IFMT;
if(fmt == S_IFDIR) {
/* it's a directory */
// it's a directory
is_dir = 1;
}
}
@ -2403,7 +1851,7 @@ cfg_file_readdir(const char *pathptr)
if(!strcmp("..", direntptr->d_name)) {
continue;
}
/* Else, see if it is a directory or a file */
// Else, see if it is a directory or a file
snprintf(&g_cfg_tmp_path[0], CFG_PATH_MAX, "%s%s",
&g_cfg_file_cachedreal[0], direntptr->d_name);
ret = cfg_stat(&g_cfg_tmp_path[0], &stat_buf);
@ -2417,12 +1865,12 @@ cfg_file_readdir(const char *pathptr)
printf("stat %s ret %d, errno:%d\n", &g_cfg_tmp_path[0],
ret, errno);
stat_buf.st_size = 0;
continue; /* skip it */
continue; // skip it
} else {
fmt = stat_buf.st_mode & S_IFMT;
size = stat_buf.st_size;
if(fmt == S_IFDIR) {
/* it's a directory */
// it's a directory
is_dir = 1;
} else if((fmt == S_IFREG) && (is_gz == 0)) {
if(g_cfg_slotdrive < 0xfff) {
@ -2677,7 +2125,7 @@ cfg_file_update_ptr(char *str)
int len;
len = strlen(str) + 1;
newstr = malloc(len);
newstr = (char*)malloc(len);
memcpy(newstr, str, len);
if(g_cfg_file_strptr) {
if(*g_cfg_file_strptr) {
@ -2715,7 +2163,7 @@ cfg_file_selected()
return;
}
snprintf(&g_cfg_file_path[0], CFG_PATH_MAX, "%s%s",
snprintf(&g_cfg_file_path[0], CFG_PATH_MAX, "%s%s", //OG
&g_cfg_file_cachedreal[0], str);
} else {
// just use cfg_file_curpath directly
@ -3053,3 +2501,15 @@ config_control_panel()
g_a2_screen_buffer_changed = -1;
}
extern byte g_bram[2][256];
extern byte* g_bram_ptr;
void x_clk_setup_bram_version()
{
if(g_rom_version < 3) {
g_bram_ptr = (&g_bram[0][0]); // ROM 01
} else {
g_bram_ptr = (&g_bram[1][0]); // ROM 03
}
}

View File

@ -14,6 +14,15 @@ const char rcsid_defc_h[] = "@(#)$KmKId: defc.h,v 1.100 2004-11-09 02:02:07-05 k
#include "defcomm.h"
// OG redirect printf to console
#ifdef ACTIVEGS
#include <stdio.h>
extern "C" int outputInfo(const char* format,...);
extern "C" int fOutputInfo(FILE*,const char* format,...);
#define printf outputInfo
#define fprintf fOutputInfo
#endif
#define STRUCT(a) typedef struct _ ## a a; struct _ ## a
typedef unsigned char byte;
@ -60,20 +69,54 @@ void U_STACK_TRACE();
# include <libc.h>
#endif
#ifndef _WIN32
#if !defined( _WIN32) && !defined(UNDER_CE) // OG
# include <unistd.h>
# include <sys/ioctl.h>
# include <sys/wait.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#ifndef UNDER_CE // OG CE SPecific
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
// OG Adding support for open
#ifdef WIN32
#include <io.h>
#endif
#else
extern int errno;
extern int open(const char* name,int,...);
extern int read(int,char*,int);
extern int close(int);
extern int write( int fd, const void *buffer, unsigned int count );
extern int lseek(int,int,int);
struct stat { int st_size; };
extern int stat(const char* name, struct stat*);
extern int fstat(int, struct stat*);
#define O_RDWR 1
#define O_BINARY 2
#define O_RDONLY 4
#define O_WRONLY 8
#define O_CREAT 16
#define O_TRUNC 32
#define EAGAIN 11
#define EINTR 4
#endif
#ifdef HPUX
# include <machine/inline.h> /* for GET_ITIMER */
#endif
@ -82,6 +125,7 @@ void U_STACK_TRACE();
# include <sys/filio.h>
#endif
#ifndef O_BINARY
/* work around some Windows junk */
# define O_BINARY 0
@ -313,3 +357,11 @@ STRUCT(Emustate_word32list) {
#include "iwm.h"
#include "protos.h"
// OG Added define for joystick
#define JOYSTICK_TYPE_KEYPAD 0
#define JOYSTICK_TYPE_MOUSE 1
#define JOYSTICK_TYPE_NATIVE_1 2
#define JOYSTICK_TYPE_NATIVE_2 3
#define JOYSTICK_TYPE_NONE 4 // OG Added Joystick None
#define NB_JOYSTICK_TYPE 5

View File

@ -32,6 +32,8 @@ const char rcsdif_defcomm_h[] = "@(#)$KmKId: defcomm.h,v 1.94 2004-10-13 21:53:4
#define HALT_EVENT 0x10
#define HALT_WANTTOQUIT 0x20 // OG : added WANTTOQUIT event
#define HALT_WANTTOBRK 0x40 // OG : added WANTTOBRK event
#define MAX_BREAK_POINTS 0x20
@ -143,7 +145,10 @@ const char rcsdif_defcomm_h[] = "@(#)$KmKId: defcomm.h,v 1.94 2004-10-13 21:53:4
#define BORDER_WIDTH 32
#define EFF_BORDER_WIDTH (BORDER_WIDTH + (640-560))
//#define EFF_BORDER_WIDTH (BORDER_WIDTH + (640-560))
// OG Eff_border_widht == border side in A2 mode
#define EFF_BORDER_WIDTH (BORDER_WIDTH + (640-560)/2)
/* BASE_MARGIN_BOTTOM+MARGIN_TOP must equal 62. There are 262 scan lines */
/* at 60Hz (15.7KHz line rate) and so we just make 62 border lines */

230
jni/dirent-win32.h Normal file
View File

@ -0,0 +1,230 @@
/*****************************************************************************
* dirent.h - dirent API for Microsoft Visual Studio
*
* Copyright (C) 2006 Toni Ronkko
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* ``Software''), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Dec 15, 2009, John Cunningham
* Added rewinddir member function
*
* Jan 18, 2008, Toni Ronkko
* Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string
* between multi-byte and unicode representations. This makes the
* code simpler and also allows the code to be compiled under MingW. Thanks
* to Azriel Fasten for the suggestion.
*
* Mar 4, 2007, Toni Ronkko
* Bug fix: due to the strncpy_s() function this file only compiled in
* Visual Studio 2005. Using the new string functions only when the
* compiler version allows.
*
* Nov 2, 2006, Toni Ronkko
* Major update: removed support for Watcom C, MS-DOS and Turbo C to
* simplify the file, updated the code to compile cleanly on Visual
* Studio 2005 with both unicode and multi-byte character strings,
* removed rewinddir() as it had a bug.
*
* Aug 20, 2006, Toni Ronkko
* Removed all remarks about MSVC 1.0, which is antiqued now. Simplified
* comments by removing SGML tags.
*
* May 14 2002, Toni Ronkko
* Embedded the function definitions directly to the header so that no
* source modules need to be included in the Visual Studio project. Removed
* all the dependencies to other projects so that this very header can be
* used independently.
*
* May 28 1998, Toni Ronkko
* First version.
*****************************************************************************/
#ifndef DIRENT_H
#define DIRENT_H
#include <windows.h>
#include <string.h>
#include <assert.h>
typedef struct dirent
{
char d_name[MAX_PATH + 1]; /* current dir entry (multi-byte char string) */
WIN32_FIND_DATAA data; /* file attributes */
} dirent;
typedef struct DIR
{
dirent current; /* Current directory entry */
int cached; /* Indicates un-processed entry in memory */
HANDLE search_handle; /* File search handle */
char patt[MAX_PATH + 3]; /* search pattern (3 = pattern + "\\*\0") */
} DIR;
/* Forward declarations */
static DIR *opendir (const char *dirname);
static struct dirent *readdir (DIR *dirp);
static int closedir (DIR *dirp);
static void rewinddir(DIR* dirp);
/* Use the new safe string functions introduced in Visual Studio 2005 */
#if defined(_MSC_VER) && _MSC_VER >= 1400
# define STRNCPY(dest,src,size) strncpy_s((dest),(size),(src),_TRUNCATE)
#else
# define STRNCPY(dest,src,size) strncpy((dest),(src),(size))
#endif
/*****************************************************************************
* Open directory stream DIRNAME for read and return a pointer to the
* internal working area that is used to retrieve individual directory
* entries.
*/
static DIR *opendir(const char *dirname)
{
DIR *dirp;
assert (dirname != NULL);
assert (strlen (dirname) < MAX_PATH);
/* construct new DIR structure */
dirp = (DIR*) malloc (sizeof (struct DIR));
if (dirp != NULL) {
char *p;
/* take directory name... */
STRNCPY (dirp->patt, dirname, sizeof(dirp->patt));
dirp->patt[MAX_PATH] = '\0';
/* ... and append search pattern to it */
p = strchr (dirp->patt, '\0');
if (dirp->patt < p && *(p-1) != '\\' && *(p-1) != ':') {
*p++ = '\\';
}
*p++ = '*';
*p = '\0';
/* open stream and retrieve first file */
dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->current.data);
if (dirp->search_handle == INVALID_HANDLE_VALUE) {
/* invalid search pattern? */
free (dirp);
return NULL;
}
/* there is an un-processed directory entry in memory now */
dirp->cached = 1;
}
return dirp;
}
/*****************************************************************************
* Read a directory entry, and return a pointer to a dirent structure
* containing the name of the entry in d_name field. Individual directory
* entries returned by this very function include regular files,
* sub-directories, pseudo-directories "." and "..", but also volume labels,
* hidden files and system files may be returned.
*/
static struct dirent *readdir(DIR *dirp)
{
assert (dirp != NULL);
if (dirp->search_handle == INVALID_HANDLE_VALUE) {
/* directory stream was opened/rewound incorrectly or ended normally */
return NULL;
}
/* get next directory entry */
if (dirp->cached != 0) {
/* a valid directory entry already in memory */
dirp->cached = 0;
} else {
/* read next directory entry from disk */
if (FindNextFileA (dirp->search_handle, &dirp->current.data) == FALSE) {
/* the very last file has been processed or an error occured */
FindClose (dirp->search_handle);
dirp->search_handle = INVALID_HANDLE_VALUE;
return NULL;
}
}
/* copy as a multibyte character string */
STRNCPY ( dirp->current.d_name,
dirp->current.data.cFileName,
sizeof(dirp->current.d_name) );
dirp->current.d_name[MAX_PATH] = '\0';
return &dirp->current;
}
/*****************************************************************************
* Close directory stream opened by opendir() function. Close of the
* directory stream invalidates the DIR structure as well as any previously
* read directory entry.
*/
static int closedir(DIR *dirp)
{
assert (dirp != NULL);
/* release search handle */
if (dirp->search_handle != INVALID_HANDLE_VALUE) {
FindClose (dirp->search_handle);
dirp->search_handle = INVALID_HANDLE_VALUE;
}
/* release directory handle */
free (dirp);
return 0;
}
/*****************************************************************************
* Resets the position of the directory stream to which dirp refers to the
* beginning of the directory. It also causes the directory stream to refer
* to the current state of the corresponding directory, as a call to opendir()
* would have done. If dirp does not refer to a directory stream, the effect
* is undefined.
*/
static void rewinddir(DIR* dirp)
{
/* release search handle */
if (dirp->search_handle != INVALID_HANDLE_VALUE) {
FindClose (dirp->search_handle);
dirp->search_handle = INVALID_HANDLE_VALUE;
}
/* open new search handle and retrieve first file */
dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->current.data);
if (dirp->search_handle == INVALID_HANDLE_VALUE) {
/* invalid search pattern? */
free (dirp);
return;
}
/* there is an un-processed directory entry in memory now */
dirp->cached = 1;
}
#endif /*DIRENT_H*/

View File

@ -14,8 +14,6 @@ const char rcsid_dis_c[] = "@(#)$KmKId: dis.c,v 1.103 2004-11-24 16:41:41-05 ken
#include "defc.h"
#include <stdarg.h>
#include <android/log.h>
#include "disas.h"
#define LINE_SIZE 160
@ -54,7 +52,8 @@ char *line_ptr;
int mode,old_mode;
int got_num;
int g_quit_sim_now = 0;
// OG replaced by HALT_WANTTOQUIT
//int g_quit_sim_now = 0;
int
get_num()
@ -169,10 +168,13 @@ do_debug_intfc()
g_fullscreen = 0;
x_full_screen(0);
if(g_quit_sim_now) {
// OG use HALT_WANTTOQUIT instead of g_quit_sim_now
if (halt_sim&HALT_WANTTOQUIT)
{
printf("Exiting immediately\n");
return;
}
printf("Type 'h' for help\n");
@ -586,6 +588,7 @@ do_blank()
void
do_go()
{
/* also called by do_step */
g_config_control_panel = 0;
@ -849,15 +852,15 @@ do_debug_unix()
}
if(load) {
if(a1bank >= 0xe0 && a1bank < 0xe2) {
ret = read(fd,&g_slow_memory_ptr[((a1bank & 1)<<16)+a1],len);
ret = read(fd,(char*)&g_slow_memory_ptr[((a1bank & 1)<<16)+a1],len);
} else {
ret = read(fd,&g_memory_ptr[(a1bank << 16) + a1],len);
ret = read(fd,(char*)&g_memory_ptr[(a1bank << 16) + a1],len);
}
} else {
if(a1bank >= 0xe0 && a1bank < 0xe2) {
ret = write(fd,&g_slow_memory_ptr[((a1bank & 1)<<16)+a1],len);
ret = write(fd,(char*)&g_slow_memory_ptr[((a1bank & 1)<<16)+a1],len);
} else {
ret = write(fd,&g_memory_ptr[(a1bank << 16) + a1],len);
ret = write(fd,(char*)&g_memory_ptr[(a1bank << 16) + a1],len);
}
}
printf("Read/write: addr %06x for %04x bytes, ret: %x bytes\n",
@ -1172,9 +1175,8 @@ halt_printf(const char *fmt, ...)
va_list args;
va_start(args, fmt);
__android_log_vprint(ANDROID_LOG_ERROR,"libkegs",fmt,args);
vprintf(fmt, args);
va_end(args);
while(1) { sleep(600); } // sleep forever
set_halt(1);
}

View File

@ -37,12 +37,21 @@ extern int g_irq_pending;
extern int g_testing;
extern int g_num_brk;
extern int g_num_cop;
extern byte *g_slow_memory_ptr;
extern byte *g_memory_ptr;
extern byte *g_rom_fc_ff_ptr;
extern byte *g_rom_cards_ptr;
extern byte *g_dummy_memory1_ptr;
// OG Need allocated memory
extern byte *g_slow_memory_ptr_allocated;
extern byte *g_memory_ptr_allocated;
extern byte *g_rom_fc_ff_ptr_allocated;
extern byte *g_rom_cards_ptr_allocated;
extern byte *g_dummy_memory1_ptr_allocated;
extern int g_num_breakpoints;
extern word32 g_breakpts[];
@ -563,8 +572,8 @@ get_memory16_c(word32 addr, int cycs)
double fcycs;
fcycs = 0;
return get_memory_c(addr, fcycs) +
(get_memory_c(addr+1, fcycs) << 8);
return get_memory_c(addr, (int)fcycs) +
(get_memory_c(addr+1, (int)fcycs) << 8);
}
word32
@ -573,9 +582,9 @@ get_memory24_c(word32 addr, int cycs)
double fcycs;
fcycs = 0;
return get_memory_c(addr, fcycs) +
(get_memory_c(addr+1, fcycs) << 8) +
(get_memory_c(addr+2, fcycs) << 16);
return get_memory_c(addr, (int)fcycs) +
(get_memory_c(addr+1, (int)fcycs) << 8) +
(get_memory_c(addr+2, (int)fcycs) << 16);
}
void
@ -729,10 +738,11 @@ fixed_memory_ptrs_init()
/* set g_slow_memory_ptr, g_rom_fc_ff_ptr, g_dummy_memory1_ptr, */
/* and rom_cards_ptr */
g_slow_memory_ptr = memalloc_align(128*1024, 0, 0);
g_dummy_memory1_ptr = memalloc_align(256, 1024, 0);
g_rom_fc_ff_ptr = memalloc_align(256*1024, 512, 0);
g_rom_cards_ptr = memalloc_align(16*256, 256, 0);
// OG Filled allocated ptr parameter to free the memory
g_slow_memory_ptr = memalloc_align(128*1024, 0, (void**)&g_slow_memory_ptr_allocated);
g_dummy_memory1_ptr = memalloc_align(256, 1024, (void**)&g_dummy_memory1_ptr_allocated);
g_rom_fc_ff_ptr = memalloc_align(256*1024, 512, (void**)&g_rom_fc_ff_ptr_allocated);
g_rom_cards_ptr = memalloc_align(16*256, 256, (void**)&g_rom_cards_ptr_allocated);
#if 0
printf("g_memory_ptr: %08x, dummy_mem: %08x, slow_mem_ptr: %08x\n",
@ -746,6 +756,21 @@ fixed_memory_ptrs_init()
#endif
}
// OG added fixed_memory_ptrs_shut
void fixed_memory_ptrs_shut()
{
free(g_slow_memory_ptr_allocated);
free(g_dummy_memory1_ptr_allocated);
free(g_rom_fc_ff_ptr_allocated);
free(g_rom_cards_ptr_allocated);
g_slow_memory_ptr=g_slow_memory_ptr_allocated= NULL;
g_dummy_memory1_ptr = g_dummy_memory1_ptr_allocated = NULL;
g_rom_fc_ff_ptr = g_rom_fc_ff_ptr_allocated = NULL;
g_rom_cards_ptr = g_rom_cards_ptr = NULL;
}
word32
get_itimer()
{
@ -890,6 +915,7 @@ get_remaining_operands(word32 addr, word32 opcode, word32 psr, Fplus *fplus_ptr)
arg_ptr[3] = arg >> 16; \
}
int
enter_engine(Engine_reg *engine_ptr)
{

File diff suppressed because it is too large Load Diff

19
jni/info.nib generated
View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>152 85 356 240 0 0 1280 832 </string>
<key>IBEditorPositions</key>
<dict>
<key>29</key>
<string>69 252 182 44 0 0 1280 832 </string>
</dict>
<key>IBFramework Version</key>
<string>291.0</string>
<key>IBSystem Version</key>
<string>6R73</string>
<key>targetFramework</key>
<string>IBCarbonFramework</string>
</dict>
</plist>

View File

@ -13,7 +13,7 @@ const char rcsid_iwm_c[] = "@(#)$KmKId: iwm.c,v 1.119 2004-11-21 17:44:14-05 ken
#include "defc.h"
extern int Verbose;
extern int g_vbl_count;
extern word32 g_vbl_count; // OG change int to word32
extern int g_c036_val_speed;
const byte phys_to_dos_sec[] = {
@ -166,6 +166,24 @@ iwm_init()
iwm_reset();
}
// OG Added shut function to IWM
// Free the memory, and more important free the open handle onto the disk
void
iwm_shut()
{
int i;
for(i = 0; i < 2; i++) {
eject_disk(&iwm.drive525[i]);
eject_disk(&iwm.drive35[i]);
}
for(i = 0; i < MAX_C7_DISKS; i++) {
eject_disk(&iwm.smartport[i]);
}
from_disk_byte_valid = 0;
}
void
iwm_reset()
{
@ -208,6 +226,19 @@ draw_iwm_status(int line, char *buf)
flag[apple35_sel][iwm.drive_select] = "*";
}
#ifdef ACTIVEGS // OG Pass monitoring info
{
extern void ki_loading(int _motorOn,int _slot,int _drive, int _curtrack);
int curtrack=0;
if (apple35_sel)
curtrack = iwm.drive35[iwm.drive_select].cur_qtr_track ;
else
curtrack = iwm.drive525[iwm.drive_select].cur_qtr_track >> 2 ;
ki_loading(g_iwm_motor_on,apple35_sel?5:6,iwm.drive_select+1,curtrack);
}
#endif
sprintf(buf, "s6d1:%2d%s s6d2:%2d%s s5d1:%2d/%d%s "
"s5d2:%2d/%d%s fast_disk_emul:%d,%d c036:%02x",
iwm.drive525[0].cur_qtr_track >> 2, flag[0][0],
@ -302,7 +333,7 @@ iwm_vbl_update(int doit_3_persec)
int i;
if(iwm.motor_on && iwm.motor_off) {
if(iwm.motor_off_vbl_count <= g_vbl_count) {
if((word32)iwm.motor_off_vbl_count <= g_vbl_count) {
printf("Disk timer expired, drive off: %08x\n",
g_vbl_count);
iwm.motor_on = 0;
@ -715,6 +746,12 @@ iwm_do_action35(double dcycs)
break;
case 0x0d: /* eject disk */
eject_disk(dsk);
#ifdef ACTIVEGS // OG : pass eject info to the COntrol (ActiveX specific)
{
extern void ejectDisk(int slot,int disk);
ejectDisk(dsk->disk_525?6:5,dsk->drive+1);
}
#endif
break;
case 0x02:
case 0x07:
@ -1625,8 +1662,25 @@ disk_track_to_unix(Disk *dsk, int qtr_track, byte *outbuf)
return -1;
}
if(disk_525) {
return iwm_denib_track525(dsk, trk, qtr_track, outbuf);
if(disk_525)
{
// OG
// Add support for .nib file
if (dsk->image_type!=DSK_TYPE_NIB)
return iwm_denib_track525(dsk, trk, qtr_track, outbuf);
else
{
int len = trk->track_len;
int i;
byte* trk_ptr = trk->nib_area+1;
byte* nib_ptr = outbuf;
for(i = 0; i < len; i += 2)
{
*nib_ptr++ = *trk_ptr;
trk_ptr+=2;
}
return 1;
}
} else {
return iwm_denib_track35(dsk, trk, qtr_track, outbuf);
}
@ -1726,7 +1780,7 @@ disk_unix_to_nib(Disk *dsk, int qtr_track, int unix_pos, int unix_len,
must_clear_track = 1;
}
len = read(dsk->fd, track_buf, unix_len);
len = read(dsk->fd, (char*)track_buf, unix_len);
if(len != unix_len) {
printf("read of disk %s q_trk %d ret: %d, errno: %d\n",
dsk->name_ptr, qtr_track, ret, errno);

View File

@ -312,7 +312,7 @@ IWM_WRITE_ROUT (Disk *dsk, word32 val, int fast_disk_emul, double dcycs)
bits_read, val, prev_val, prev_bits);
}
sdiff = dcycs - dcycs_last_read;
sdiff = (int)( dcycs - dcycs_last_read );
if(sdiff < (dcycs_this_nib) || (sdiff > (2*dcycs_this_nib)) ) {
dsk->dcycs_last_read = dcycs;
} else {

52
jni/joystick_dummy.c Normal file
View File

@ -0,0 +1,52 @@
/************************************************************************/
/* KEGS: Apple //gs Emulator */
/* Copyright 2002 by Kent Dickey */
/* */
/* This code is covered by the GNU GPL */
/* */
/* The KEGS web page is kegs.sourceforge.net */
/* You may contact the author at: kadickey@alumni.princeton.edu */
/************************************************************************/
const char rcsid_joystick_driver_c[] = "@(#)$KmKId: joystick_driver.c,v 1.12 2004-10-17 21:28:48-04 kentd Exp $";
#include "defc.h"
#ifndef _MSC_VER // OG Unknown MSFT header
#include <sys/time.h>
#endif
extern int g_joystick_native_type1; /* in paddles.c */
extern int g_joystick_native_type2; /* in paddles.c */
extern int g_joystick_native_type; /* in paddles.c */
extern int g_paddle_buttons;
extern int g_paddle_val[];
void
joystick_init()
{
g_joystick_native_type1 = -1;
g_joystick_native_type2 = -1;
g_joystick_native_type = -1;
}
void
joystick_update(double dcycs)
{
int i;
for(i = 0; i < 4; i++) {
g_paddle_val[i] = 32767;
}
g_paddle_buttons = 0xc;
}
void
joystick_update_buttons()
{
}
// OG
void joystick_shut()
{
}

125
jni/joystick_linux.c Normal file
View File

@ -0,0 +1,125 @@
/************************************************************************/
/* KEGS: Apple //gs Emulator */
/* Copyright 2002 by Kent Dickey */
/* */
/* This code is covered by the GNU GPL */
/* */
/* The KEGS web page is kegs.sourceforge.net */
/* You may contact the author at: kadickey@alumni.princeton.edu */
/************************************************************************/
const char rcsid_joystick_driver_c[] = "@(#)$KmKId: joystick_driver.c,v 1.12 2004-10-17 21:28:48-04 kentd Exp $";
#include "defc.h"
#include <sys/time.h>
# include <linux/joystick.h>
extern int g_joystick_native_type1; /* in paddles.c */
extern int g_joystick_native_type2; /* in paddles.c */
extern int g_joystick_native_type; /* in paddles.c */
extern int g_paddle_buttons;
extern int g_paddle_val[];
const char *g_joystick_dev = "/dev/js0"; /* default joystick dev file */
#define MAX_JOY_NAME 128
int g_joystick_native_fd = -1;
int g_joystick_num_axes = 0;
int g_joystick_num_buttons = 0;
void
joystick_init()
{
char joy_name[MAX_JOY_NAME];
int version;
int fd;
int i;
fd = open(g_joystick_dev, O_RDONLY | O_NONBLOCK);
if(fd < 0) {
printf("Unable to open joystick dev file: %s, errno: %d\n",
g_joystick_dev, errno);
printf("Defaulting to mouse joystick\n");
return;
}
strcpy(&joy_name[0], "Unknown Joystick");
version = 0x800;
ioctl(fd, JSIOCGNAME(MAX_JOY_NAME), &joy_name[0]);
ioctl(fd, JSIOCGAXES, &g_joystick_num_axes);
ioctl(fd, JSIOCGBUTTONS, &g_joystick_num_buttons);
ioctl(fd, JSIOCGVERSION, &version);
printf("Detected joystick: %s [%d axes, %d buttons vers: %08x]\n",
joy_name, g_joystick_num_axes, g_joystick_num_buttons,
version);
g_joystick_native_type1 = 1;
g_joystick_native_type2 = -1;
g_joystick_native_fd = fd;
for(i = 0; i < 4; i++) {
g_paddle_val[i] = 32767;
}
g_paddle_buttons = 0xc;
joystick_update(0.0);
}
/* joystick_update_linux() called from paddles.c. Update g_paddle_val[] */
/* and g_paddle_buttons with current information */
void
joystick_update(double dcycs)
{
struct js_event js; /* the linux joystick event record */
int mask;
int val;
int num;
int type;
int ret;
int len;
int i;
/* suck up to 20 events, then give up */
len = sizeof(struct js_event);
for(i = 0; i < 20; i++) {
ret = read(g_joystick_native_fd, &js, len);
if(ret != len) {
/* just get out */
break;
}
type = js.type & ~JS_EVENT_INIT;
val = js.value;
num = js.number & 3; /* clamp to 0-3 */
switch(type) {
case JS_EVENT_BUTTON:
mask = 1 << num;
if(val) {
val = mask;
}
g_paddle_buttons = (g_paddle_buttons & ~mask) | val;
break;
case JS_EVENT_AXIS:
/* val is -32767 to +32767 */
g_paddle_val[num] = val;
break;
}
}
if(i > 0) {
paddle_update_trigger_dcycs(dcycs);
}
}
void
joystick_update_buttons()
{
}
// OG
void joystick_shut()
{
}

View File

@ -11,18 +11,9 @@
const char rcsid_joystick_driver_c[] = "@(#)$KmKId: joystick_driver.c,v 1.12 2004-10-17 21:28:48-04 kentd Exp $";
#include "defc.h"
#include <sys/time.h>
#ifndef __ANDROID__
#ifdef __linux__
# include <linux/joystick.h>
#endif
#endif
#ifdef _WIN32
# include <windows.h>
# include <mmsystem.h>
#endif
extern int g_joystick_native_type1; /* in paddles.c */
extern int g_joystick_native_type2; /* in paddles.c */
@ -30,113 +21,16 @@ extern int g_joystick_native_type; /* in paddles.c */
extern int g_paddle_buttons;
extern int g_paddle_val[];
const char *g_joystick_dev = "/dev/js0"; /* default joystick dev file */
/*
const char *g_joystick_dev = "/dev/js0"; // default joystick dev file
#define MAX_JOY_NAME 128
int g_joystick_native_fd = -1;
int g_joystick_num_axes = 0;
int g_joystick_num_buttons = 0;
*/
#ifndef __ANDROID__
#ifdef __linux__
# define JOYSTICK_DEFINED
void
joystick_init()
{
char joy_name[MAX_JOY_NAME];
int version;
int fd;
int i;
fd = open(g_joystick_dev, O_RDONLY | O_NONBLOCK);
if(fd < 0) {
printf("Unable to open joystick dev file: %s, errno: %d\n",
g_joystick_dev, errno);
printf("Defaulting to mouse joystick\n");
return;
}
strcpy(&joy_name[0], "Unknown Joystick");
version = 0x800;
ioctl(fd, JSIOCGNAME(MAX_JOY_NAME), &joy_name[0]);
ioctl(fd, JSIOCGAXES, &g_joystick_num_axes);
ioctl(fd, JSIOCGBUTTONS, &g_joystick_num_buttons);
ioctl(fd, JSIOCGVERSION, &version);
printf("Detected joystick: %s [%d axes, %d buttons vers: %08x]\n",
joy_name, g_joystick_num_axes, g_joystick_num_buttons,
version);
g_joystick_native_type1 = 1;
g_joystick_native_type2 = -1;
g_joystick_native_fd = fd;
for(i = 0; i < 4; i++) {
g_paddle_val[i] = 32767;
}
g_paddle_buttons = 0xc;
joystick_update(0.0);
}
/* joystick_update_linux() called from paddles.c. Update g_paddle_val[] */
/* and g_paddle_buttons with current information */
void
joystick_update(double dcycs)
{
struct js_event js; /* the linux joystick event record */
int mask;
int val;
int num;
int type;
int ret;
int len;
int i;
/* suck up to 20 events, then give up */
len = sizeof(struct js_event);
for(i = 0; i < 20; i++) {
ret = read(g_joystick_native_fd, &js, len);
if(ret != len) {
/* just get out */
break;
}
type = js.type & ~JS_EVENT_INIT;
val = js.value;
num = js.number & 3; /* clamp to 0-3 */
switch(type) {
case JS_EVENT_BUTTON:
mask = 1 << num;
if(val) {
val = mask;
}
g_paddle_buttons = (g_paddle_buttons & ~mask) | val;
break;
case JS_EVENT_AXIS:
/* val is -32767 to +32767 */
g_paddle_val[num] = val;
break;
}
}
if(i > 0) {
paddle_update_trigger_dcycs(dcycs);
}
}
void
joystick_update_buttons()
{
}
#endif /* LINUX */
#endif
#ifdef _WIN32
# define JOYSTICK_DEFINED
void
joystick_init()
void joystick_init()
{
JOYINFO info;
JOYCAPS joycap;
@ -234,31 +128,8 @@ joystick_update_buttons()
}
}
}
#endif
#ifndef JOYSTICK_DEFINED
/* stubs for the routines */
void
joystick_init()
{
g_joystick_native_type1 = -1;
g_joystick_native_type2 = -1;
g_joystick_native_type = -1;
}
void
joystick_update(double dcycs)
{
int i;
for(i = 0; i < 4; i++) {
g_paddle_val[i] = 32767;
}
g_paddle_buttons = 0xc;
}
void
joystick_update_buttons()
// OG
void joystick_shut()
{
}
#endif

Binary file not shown.

File diff suppressed because it is too large Load Diff

501
jni/macdriver_generic.c Normal file
View File

@ -0,0 +1,501 @@
/************************************************************************/
/* KEGS: Apple //gs Emulator */
/* Copyright 2002-2004 by Kent Dickey */
/* */
/* This code is covered by the GNU GPL */
/* */
/* The KEGS web page is kegs.sourceforge.net */
/* You may contact the author at: kadickey@alumni.princeton.edu */
/************************************************************************/
const char rcsid_macdriver_c[] = "@(#)$KmKId: macdriver.c,v 1.24 2004-11-14 10:23:29-05 kentd Exp $";
#ifdef ACTIVEIPHONE
#include <CoreGraphics/CGContext.h>
#include <CoreGraphics/CGBitmapContext.h>
#include <CoreFoundation/CFURL.h>
#else
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include <Carbon/Carbon.h>
#define ENABLEQD
#endif
#include "defc.h"
#include "protos_macdriver.h"
word32 g_mac_shift_control_state = 0;
int macUsingCoreGraphics=0;
// Coregraphics context
CGContextRef offscreenContext = NULL;
char * bitmapData=NULL;
int bitmapByteCount;
int bitmapBytesPerRow;
#ifdef ENABLEQD
WindowRef g_main_window;
CGrafPtr mac_window_port;
#endif
extern Kimage g_mainwin_kimage;
int g_use_shmem = 0;
extern int Verbose;
extern int g_video_act_width;
extern int g_video_act_height;
extern int g_video_act_margin_left;
extern int g_video_act_margin_right;
extern int g_video_act_margin_top;
extern int g_video_act_margin_bottom;
extern int g_screen_depth;
extern int g_force_depth;
int g_screen_mdepth = 0;
extern int g_send_sound_to_file;
//extern int g_quit_sim_now; // OG Not need anymore
extern int g_config_control_panel;
int g_auto_repeat_on = -1;
int g_x_shift_control_state = 0;
extern int Max_color_size;
extern word32 g_palette_8to1624[256];
extern word32 g_a2palette_8to1624[256];
int g_alt_left_up = 1;
int g_alt_right_up = 1;
extern word32 g_full_refresh_needed;
extern int g_border_sides_refresh_needed;
extern int g_border_special_refresh_needed;
extern int g_status_refresh_needed;
extern int g_lores_colors[];
extern int g_a2vid_palette;
extern int g_installed_full_superhires_colormap;
extern int g_screen_redraw_skip_amt;
extern word32 g_a2_screen_buffer_changed;
int g_upd_count = 0;
void
update_window(void)
{
// OG Not needed
/*
SetPortWindowPort(g_main_window);
PenNormal();
*/
g_full_refresh_needed = -1;
g_a2_screen_buffer_changed = -1;
g_status_refresh_needed = 1;
g_border_sides_refresh_needed = 1;
g_border_special_refresh_needed = 1;
g_upd_count++;
if(g_upd_count > 250) {
g_upd_count = 0;
}
}
void
mac_update_modifiers(word32 state)
{
#ifndef ACTIVEIPHONE
word32 state_xor;
int is_up;
state = state & (
cmdKey | controlKey |
shiftKey | alphaLock | optionKey
);
state_xor = g_mac_shift_control_state ^ state;
is_up = 0;
if(state_xor & controlKey) {
is_up = ((state & controlKey) == 0);
adb_physical_key_update(0x36, is_up);
}
if(state_xor & alphaLock) {
is_up = ((state & alphaLock) == 0);
adb_physical_key_update(0x39, is_up);
}
if(state_xor & shiftKey) {
is_up = ((state & shiftKey) == 0);
adb_physical_key_update(0x38, is_up);
}
if(state_xor & cmdKey) {
is_up = ((state & cmdKey) == 0);
adb_physical_key_update(0x37, is_up);
}
if(state_xor & optionKey) {
is_up = ((state & optionKey) == 0);
adb_physical_key_update(0x3a, is_up);
}
#endif
g_mac_shift_control_state = state;
}
void
x_update_color(int col_num, int red, int green, int blue, word32 rgb)
{
}
void
x_update_physical_colormap()
{
}
void
show_xcolor_array()
{
int i;
for(i = 0; i < 256; i++) {
printf("%02x: %08x\n", i, g_palette_8to1624[i]);
}
}
void
x_get_kimage(Kimage *kimage_ptr)
{
#ifdef ENABLEQD
PixMapHandle pixmap_handle;
GWorldPtr world;
Rect world_rect;
OSStatus err;
#endif
word32 *wptr;
byte *ptr;
int row_bytes;
int width;
int height;
int depth, mdepth;
int size;
width = kimage_ptr->width_req;
height = kimage_ptr->height;
depth = kimage_ptr->depth;
mdepth = kimage_ptr->mdepth;
size = 0;
if(depth == g_screen_depth)
{
if (!macUsingCoreGraphics)
{
#ifdef ENABLEQD
SetRect(&world_rect, 0, 0, width, height);
err = NewGWorld( &world, 0, &world_rect, NULL, NULL, 0);
pixmap_handle = GetGWorldPixMap(world);
err = LockPixels(pixmap_handle);
ptr = (byte *)GetPixBaseAddr(pixmap_handle);
row_bytes = ((*pixmap_handle)->rowBytes & 0x3fff);
kimage_ptr->width_act = row_bytes / (mdepth >> 3);
mac_printf("Got depth: %d, bitmap_ptr: %p, width: %d\n", depth, ptr, kimage_ptr->width_act);
mac_printf("pixmap->base: %08x, rowbytes: %08x, pixType:%08x\n",(int)(*pixmap_handle)->baseAddr,(*pixmap_handle)->rowBytes,(*pixmap_handle)->pixelType);
wptr = (word32 *)(*pixmap_handle);
mac_printf("wptr: %p=%08x %08x %08x %08x %08x %08x %08x %08x\n",wptr,wptr[0], wptr[1], wptr[2], wptr[3],wptr[4], wptr[5], wptr[6], wptr[7]);
kimage_ptr->dev_handle = pixmap_handle;
kimage_ptr->data_ptr = ptr;
#endif
}
else
{
kimage_ptr->width_act = width ;
size = height* kimage_ptr->width_act * mdepth >> 3;
ptr = (byte *)malloc(size);
if(ptr == 0) {
mac_printf("malloc for data fail, mdepth:%d\n", mdepth);
exit(2);
}
kimage_ptr->data_ptr = ptr;
kimage_ptr->dev_handle = (void *)-1;
}
}
else {
/* allocate buffers for video.c to draw into */
kimage_ptr->width_act = width ;
size = height* kimage_ptr->width_act * mdepth >> 3 ;
ptr = (byte *)malloc(size);
if(ptr == 0) {
mac_printf("malloc for data fail, mdepth:%d\n", mdepth);
exit(2);
}
kimage_ptr->data_ptr = ptr;
kimage_ptr->dev_handle = (void *)-1;
}
mac_printf("kim: %p, dev:%p data: %p, size: %08x\n", kimage_ptr,
kimage_ptr->dev_handle, kimage_ptr->data_ptr, size);
}
#ifdef ENABLEQD
PixMapHandle pixmap_backbuffer=NULL;
GWorldPtr backbuffer=NULL;
#endif
void
dev_video_init()
{
int lores_col;
int i;
printf("Preparing graphics system\n");
// OG Create backbuffer
if (!macUsingCoreGraphics)
{
#ifdef ENABLEQD
Rect r;
SetRect(&r, 0, 0, 704, 462);
QDErr err = NewGWorld( &backbuffer, 0, &r, NULL, NULL, 0);
pixmap_backbuffer = GetGWorldPixMap(backbuffer);
#endif
}
else
{
CGColorSpaceRef colorSpace;
int pixelsWide = 704;
int pixelsHigh = 462;
bitmapBytesPerRow = (pixelsWide * 4);// 1
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);// 2
bitmapData = (char*)malloc( bitmapByteCount );// 3
if (bitmapData == NULL)
{
fprintf (stderr, "Memory not allocated!");
return ;
}
offscreenContext = CGBitmapContextCreate (bitmapData,// 4
pixelsWide,
pixelsHigh,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaNoneSkipLast);
if (offscreenContext== NULL)
{
free (bitmapData);// 5
fprintf (stderr, "Context not created!");
return ;
}
CGContextSetRGBFillColor (offscreenContext, 1, 0.5, 0.5, 1);
CGContextFillRect (offscreenContext, CGRectMake (0,0, 704, 462 ));
CGColorSpaceRelease( colorSpace );// 6
}
video_get_kimages();
if(g_screen_depth != 8) {
// Get g_mainwin_kimage
video_get_kimage(&g_mainwin_kimage, 0, g_screen_depth,
g_screen_mdepth);
}
for(i = 0; i < 256; i++) {
lores_col = g_lores_colors[i & 0xf];
video_update_color_raw(i, lores_col);
g_a2palette_8to1624[i] = g_palette_8to1624[i];
}
g_installed_full_superhires_colormap = 1;
fflush(stdout);
}
void
x_push_kimage(Kimage *kimage_ptr, int destx, int desty, int srcx, int srcy,
int width, int height)
{
if (!macUsingCoreGraphics)
{
#ifdef ENABLEQD
PixMapHandle pixmap_handle;
Rect src_rect, dest_rect;
CGrafPtr window_port;
pixmap_handle = (PixMapHandle)kimage_ptr->dev_handle;
SetRect(&src_rect, srcx, srcy, srcx + width, srcy + height);
SetRect(&dest_rect, destx, desty, destx + width, desty + height);
#ifndef ACTIVEGSPLUGIN
SetPortWindowPort(g_main_window);
window_port = GetWindowPort(g_main_window);
CopyBits( (BitMap *)(*pixmap_handle),
GetPortBitMapForCopyBits(window_port), &src_rect, &dest_rect,
srcCopy, NULL);
#else // !ACTIVEGSPLUGIN
// OG Write to the back buffer instead of the display window
window_port = mac_window_port ;
SetGWorld(backbuffer,NULL);
CopyBits( (BitMap *)(*pixmap_handle),
GetPortBitMapForCopyBits(backbuffer), &src_rect, &dest_rect,
srcCopy, NULL);
#endif // ACTIVEGSPLUGIN
#endif
}
else
{
int wd = kimage_ptr->width_act * kimage_ptr->mdepth>>3;
int w = width *4;
char* ptrdest = bitmapData + bitmapBytesPerRow*desty + destx*4;
char* srcdest = (char*)kimage_ptr->data_ptr + wd*srcy + srcx*4;
for(int i=0;i<height;i+=1)
{
memcpy(ptrdest,srcdest,w);
ptrdest += bitmapBytesPerRow;
srcdest += wd;
}
}
}
void
x_auto_repeat_on(int must)
{
}
void
x_auto_repeat_off(int must)
{
}
void
x_hide_pointer(int do_hide)
{
#ifdef ENABLEQD
if(do_hide) {
HideCursor();
} else {
ShowCursor();
}
#endif
}
void
update_main_window_size()
{
#ifdef ENABLEQD
Rect win_rect;
int width, height;
int left, excess_height;
int top, bottom;
GetPortBounds(GetWindowPort(g_main_window), &win_rect);
width = win_rect.right - win_rect.left;
height = win_rect.bottom - win_rect.top;
g_video_act_width = width;
g_video_act_height = height;
left = MAX(0, (width - A2_WINDOW_WIDTH) / 2);
left = MIN(left, BASE_MARGIN_LEFT);
g_video_act_margin_left = left;
g_video_act_margin_right = left;
excess_height = (height - A2_WINDOW_HEIGHT) / 2;
bottom = MAX(0, excess_height / 2); // No less than 0
bottom = MIN(BASE_MARGIN_BOTTOM, bottom); // No more than 30
g_video_act_margin_bottom = bottom;
excess_height -= bottom;
top = MAX(0, excess_height);
top = MIN(BASE_MARGIN_TOP, top);
g_video_act_margin_top = top;
#endif
}
// OG Adding release
void x_release_kimage(Kimage* kimage_ptr)
{
if (kimage_ptr->dev_handle == (void*)-1)
{
free(kimage_ptr->data_ptr);
kimage_ptr->data_ptr = NULL;
}
else
{
if (!macUsingCoreGraphics)
{
#ifdef ENABLEQD
UnlockPixels((PixMapHandle)kimage_ptr->dev_handle);
kimage_ptr->dev_handle = NULL;
DisposeGWorld((GWorldPtr)kimage_ptr->dev_handle2);
kimage_ptr->dev_handle2 = NULL;
#endif
}
}
}
// OG Addding ratio
int x_calc_ratio(float&x,float&y)
{
return 1;
}

834
jni/macdriver_kegs.c Normal file
View File

@ -0,0 +1,834 @@
#include "defc.h"
#include "protos_macdriver.h"
pascal OSStatus quit_event_handler(EventHandlerCallRef call_ref, EventRef event, void *ignore);
pascal OSStatus my_cmd_handler(EventHandlerCallRef handlerRef, EventRef event, void *userdata);
pascal OSStatus my_win_handler(EventHandlerCallRef handlerRef, EventRef event, void *userdata);
pascal OSStatus dummy_event_handler(EventHandlerCallRef call_ref, EventRef in_event, void *ignore);
int g_quit_seen = 0;
#define MAX_STATUS_LINES 7
#define X_LINE_LENGTH 88
#define MAX_MAC_ARGS 128
int g_mac_argc = 0;
char *g_mac_argv[MAX_MAC_ARGS];
extern char g_argv0_path[];
extern char *g_status_ptrs[MAX_STATUS_LINES];
extern const char g_kegs_version_str[];
extern int g_warp_pointer;
extern WindowRef g_main_window;
WindowRef g_main_window_saved;
EventHandlerUPP g_quit_handler_UPP;
EventHandlerUPP g_dummy_event_handler_UPP;
RgnHandle g_event_rgnhandle = 0;
FMFontFamily g_status_font_family;
extern word32 g_red_mask;
extern word32 g_green_mask;
extern word32 g_blue_mask;
extern int g_red_left_shift;
extern int g_green_left_shift;
extern int g_blue_left_shift;
extern int g_red_right_shift;
extern int g_green_right_shift;
extern int g_blue_right_shift;
int g_ignore_next_click = 0;
int g_mainwin_active = 0;
int g_mac_mouse_x = 0;
int g_mac_mouse_y = 0;
extern int g_video_act_width;
extern int g_video_act_height;
extern int g_video_act_margin_left;
extern int g_video_act_margin_right;
extern int g_video_act_margin_top;
extern int g_video_act_margin_bottom;
extern int g_screen_depth;
extern int g_force_depth;
extern int g_screen_mdepth;
Ptr g_mac_fullscreen_state = 0;
Rect g_main_window_saved_rect;
extern char *g_fatal_log_strs[];
extern int g_fatal_log;
int
x_show_alert(int is_fatal, const char *str)
{
DialogRef alert;
DialogItemIndex out_item_hit;
CFStringRef cfstrref, cfstrref2;
CFStringRef okstrref;
AlertStdCFStringAlertParamRec alert_param;
OSStatus osstat;
char *bufptr, *buf2ptr;
int sum, len;
int i;
/* The dialog eats all events--including key-up events */
/* Call adb_all_keys_up() to prevent annoying key-repeat problems */
/* for instance, a key-down causes a dialog to appear--and the */
/* eats the key-up event...then as soon as the dialog goes, adb.c */
/* auto-repeat will repeat the key, and the dialog re-appears...*/
adb_all_keys_up();
sum = 20;
for(i = 0; i < g_fatal_log; i++) {
sum += strlen(g_fatal_log_strs[i]);
}
bufptr = (char*)malloc(sum);
buf2ptr = bufptr;
for(i = 0; i < g_fatal_log; i++) {
len = strlen(g_fatal_log_strs[i]);
len = MIN(len, sum);
len = MAX(len, 0);
memcpy(bufptr, g_fatal_log_strs[i], MIN(len, sum));
bufptr += len;
bufptr[0] = 0;
sum = sum - len;
}
cfstrref = CFStringCreateWithCString(NULL, buf2ptr,
kCFStringEncodingMacRoman);
printf("buf2ptr: :%s:\n", buf2ptr);
osstat = GetStandardAlertDefaultParams(&alert_param,
kStdCFStringAlertVersionOne);
if(str) {
// Provide an extra option--create a file
cfstrref2 = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
CFSTR("Create ~/Library/KEGS/%s"), str);
alert_param.otherText = cfstrref2;
}
okstrref = CFSTR("Click OK to continue");
if(is_fatal) {
okstrref = CFSTR("Clock OK to exit KEGS");
}
CreateStandardAlert(kAlertStopAlert, cfstrref, okstrref,
&alert_param, &alert);
out_item_hit = -1;
RunStandardAlert(alert, NULL, &out_item_hit);
printf("out_item_hit: %d\n", out_item_hit);
free(buf2ptr);
clear_fatal_logs(); /* free the fatal_log string memory */
return (out_item_hit >= 3);
}
pascal OSStatus
quit_event_handler(EventHandlerCallRef call_ref, EventRef event, void *ignore)
{
OSStatus err;
err = CallNextEventHandler(call_ref, event);
if(err == noErr) {
g_quit_seen = 1;
}
return err;
}
void
show_simple_alert(char *str1, char *str2, char *str3, int num)
{
char buf[256];
g_fatal_log_strs[0] = kegs_malloc_str(str1);
g_fatal_log_strs[1] = kegs_malloc_str(str2);
g_fatal_log_strs[2] = kegs_malloc_str(str3);
g_fatal_log = 3;
if(num != 0) {
snprintf(buf, 250, ": %d", num);
g_fatal_log_strs[g_fatal_log++] = kegs_malloc_str(buf);
}
x_show_alert(0, 0);
}
void
x_dialog_create_kegs_conf(const char *str)
{
char *path;
char tmp_buf[512];
int ret;
ret = x_show_alert(1, str);
if(ret) {
// Create empty file
path = "~/Library/KEGS";
snprintf(tmp_buf, 500, "mkdir -p %s", path);
system(tmp_buf);
snprintf(tmp_buf, 500, "touch %s/%s", path, str);
system(tmp_buf);
}
}
pascal OSStatus
my_cmd_handler( EventHandlerCallRef handlerRef, EventRef event, void *userdata)
{
OSStatus osresult;
HICommand command;
word32 command_id;
osresult = eventNotHandledErr;
GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL,
sizeof(HICommand), NULL, &command);
command_id = (word32)command.commandID;
switch(command_id) {
case 'Kbep':
SysBeep(10);
osresult = noErr;
break;
case 'abou':
show_simple_alert("KEGSMAC v", (char *)g_kegs_version_str,
", Copyright 2004 Kent Dickey\n"
"Latest version at http://kegs.sourceforge.net/\n", 0);
osresult = noErr;
break;
case 'KCFG':
#ifdef ACTIVEGS
#else
cfg_toggle_config_panel();
#endif
osresult = noErr;
break;
case 'quit':
break;
case 'swin':
/* not sure what this is, but Panther sends it */
break;
default:
printf("commandID %08x unknown\n", command_id);
SysBeep(90);
break;
}
return osresult;
}
pascal OSStatus
my_win_handler(EventHandlerCallRef handlerRef, EventRef event, void *userdata)
{
OSStatus os_result;
UInt32 event_kind;
os_result = eventNotHandledErr;
// SysBeep(1);
event_kind = GetEventKind(event);
// show_alert("win handler", event_kind);
if(event_kind == kEventWindowDrawContent)
{
update_window();
} if(event_kind == kEventWindowClose) {
// OG Use HALT_WANTTOQUIT pardigme
//g_quit_sim_now = 1;
set_halt_act(HALT_WANTTOQUIT);
#ifndef ACTIVEGS
g_quit_seen = 1;
my_exit(0);
#endif
} else {
//show_event(GetEventClass(event), event_kind, 0);
update_window();
}
return os_result;
}
pascal OSStatus
dummy_event_handler(EventHandlerCallRef call_ref, EventRef in_event,
void *ignore)
{
OSStatus err;
EventHandlerRef installed_handler;
EventTypeSpec event_spec = { kEventClassApplication, kEventAppQuit };
// From http://developer.apple.com/qa/qa2001/qa1061.html
// Trick to move main event queue to use ReceiveNextEvent in an event
// handler called by RunApplicationEventLoop
err = InstallApplicationEventHandler(g_quit_handler_UPP, 1, &event_spec,
NULL, &installed_handler);
kegsmain(g_mac_argc, g_mac_argv);
return noErr;
}
void
check_input_events()
{
OSStatus err;
EventTargetRef target;
EventRef event;
UInt32 event_class, event_kind;
byte mac_keycode;
UInt32 keycode;
UInt32 modifiers;
Point mouse_point, mouse_delta_point;
WindowRef window_ref;
int button, button_state;
EventMouseButton mouse_button;
int handled;
int mouse_events;
int is_up;
int in_win;
int ignore;
if(g_quit_seen) {
exit(0);
}
SetPortWindowPort(g_main_window);
mouse_events = 0;
target = GetEventDispatcherTarget();
while(1) {
err = ReceiveNextEvent(0, NULL, kEventDurationNoWait,
true, &event);
if(err == eventLoopTimedOutErr) {
break;
}
if(err != noErr) {
printf("ReceiveNextEvent err: %d\n", (int)err);
break;
}
event_class = GetEventClass(event);
event_kind = GetEventKind(event);
handled = 0;
switch(event_class) {
case kEventClassKeyboard:
handled = 1;
keycode = 0;
modifiers = 0;
GetEventParameter(event, kEventParamKeyMacCharCodes,
typeChar, NULL, sizeof(byte), NULL,
&mac_keycode);
GetEventParameter(event, kEventParamKeyCode,
typeUInt32, NULL, sizeof(UInt32), NULL,
&keycode);
GetEventParameter(event, kEventParamKeyModifiers,
typeUInt32, NULL, sizeof(UInt32), NULL,
&modifiers);
mac_update_modifiers((word32)modifiers);
// Key up/down event
is_up = -1;
switch(event_kind) {
case kEventRawKeyDown:
is_up = 0;
//printf("key down: %02x, %08x\n",
// (int)mac_keycode, (int)keycode);
break;
case kEventRawKeyUp:
is_up = 1;
//printf("key up: %02x, %08x\n",
// (int)mac_keycode, (int)keycode);
break;
case kEventRawKeyModifiersChanged:
is_up = -1;
//printf("key xxx: %08x\n", (int)modifiers);
break;
}
if(is_up >= 0) {
adb_physical_key_update((int)keycode, is_up);
}
break;
case kEventClassMouse:
handled = 2;
mouse_events++;
GetEventParameter(event, kEventParamMouseLocation,
typeQDPoint, NULL, sizeof(Point), NULL,
&mouse_point);
GetWindowRegion(g_main_window, kWindowContentRgn,
g_event_rgnhandle);
in_win = PtInRgn(mouse_point, g_event_rgnhandle);
// in_win = 1 if it was in the contect region of window
err = GetEventParameter(event, kEventParamMouseDelta,
typeQDPoint, NULL, sizeof(Point), NULL,
&mouse_delta_point);
button = 0;
button_state = -1;
switch(event_kind) {
case kEventMouseDown:
button_state = 7;
handled = 3;
break;
case kEventMouseUp:
button_state = 0;
handled = 3;
break;
}
if(button_state >= 0) {
GetEventParameter(event, kEventParamMouseButton,
typeMouseButton, NULL,
sizeof(EventMouseButton), NULL,
&mouse_button);
button = mouse_button;
if(button > 1) {
button = 4 - button;
button = 1 << button;
}
ignore = (button_state != 0) &&
(!in_win || g_ignore_next_click);
ignore = ignore || !g_mainwin_active;
if(ignore) {
// Outside of A2 window, ignore clicks
button = 0;
}
if(button_state == 0) {
g_ignore_next_click = 0;
}
}
GlobalToLocal(&mouse_point);
if(g_warp_pointer) {
if(err == 0) {
g_mac_mouse_x += mouse_delta_point.h;
g_mac_mouse_y += mouse_delta_point.v;
}
mac_warp_mouse();
} else {
g_mac_mouse_x = mouse_point.h -
g_video_act_margin_left;
g_mac_mouse_y = mouse_point.v -
g_video_act_margin_top;
}
#if 0
printf("Mouse %d at: %d,%d button:%d, button_st:%d\n",
mouse_events, g_mac_mouse_x, g_mac_mouse_y,
button, button_state);
printf("Mouse deltas: err:%d, %d,%d\n", (int)err,
mouse_delta_point.h, mouse_delta_point.v);
#endif
update_mouse(g_mac_mouse_x, g_mac_mouse_y,
button_state, button & 7);
if(g_warp_pointer) {
g_mac_mouse_x = A2_WINDOW_WIDTH/2;
g_mac_mouse_y = A2_WINDOW_HEIGHT/2;
update_mouse(g_mac_mouse_x, g_mac_mouse_y,0,-1);
}
break;
case kEventClassApplication:
switch(event_kind) {
case kEventAppActivated:
handled = 1;
g_mainwin_active = 1;
window_ref = 0;
GetEventParameter(event, kEventParamWindowRef,
typeWindowRef, NULL, sizeof(WindowRef),
NULL, &window_ref);
if(window_ref == g_main_window) {
g_ignore_next_click = 1;
}
break;
case kEventAppDeactivated:
handled = 1;
g_mainwin_active = 0;
g_ignore_next_click = 1;
break;
}
break;
}
// show_event(event_class, event_kind, handled);
if(handled != 1) {
(void)SendEventToEventTarget(event, target);
}
ReleaseEvent(event);
}
return;
}
void
temp_run_application_event_loop(void)
{
OSStatus err;
EventRef dummy_event;
EventHandlerRef install_handler;
EventTypeSpec event_spec = { 'KWIN', 'KWIN' };
// Create UPP for dummy_event_handler and for quit_event_handler
err = noErr;
dummy_event = 0;
g_dummy_event_handler_UPP = NewEventHandlerUPP(dummy_event_handler);
g_quit_handler_UPP = NewEventHandlerUPP(quit_event_handler);
if((g_dummy_event_handler_UPP == 0) || (g_quit_handler_UPP == 0)) {
err = memFullErr;
}
if(err == noErr) {
err = InstallApplicationEventHandler(g_dummy_event_handler_UPP,
1, &event_spec, 0, &install_handler);
if(err == noErr) {
err = MacCreateEvent(NULL, 'KWIN', 'KWIN',
GetCurrentEventTime(), kEventAttributeNone,
&dummy_event);
if(err == noErr) {
err = PostEventToQueue(GetMainEventQueue(),
dummy_event, kEventPriorityHigh);
}
if(err == noErr) {
RunApplicationEventLoop();
}
(void)RemoveEventHandler(install_handler);
}
}
if(dummy_event != NULL) {
ReleaseEvent(dummy_event);
}
}
int
#ifdef ACTIVEGS
macmain
#else
main
#endif
(int argc, char* argv[])
{
ProcessSerialNumber my_psn;
IBNibRef nibRef;
EventHandlerUPP handlerUPP;
EventTypeSpec cmd_event[3];
GDHandle g_gdhandle ;
Rect win_rect;
OSStatus err;
char *argptr;
int slash_cnt;
int i;
#ifndef ACTIVEGS
/* Prepare argv0 */
slash_cnt = 0;
argptr = argv[0];
for(i = strlen(argptr); i >= 0; i--) {
if(argptr[i] == '/') {
slash_cnt++;
if(slash_cnt == 3) {
strncpy(&(g_argv0_path[0]), argptr, i);
g_argv0_path[i] = 0;
}
}
}
printf("g_argv0_path is %s\n", g_argv0_path);
g_mac_argv[0] = argv[0];
g_mac_argc = 1;
i = 1;
while((i < argc) && (g_mac_argc < MAX_MAC_ARGS)) {
if(!strncmp(argv[i], "-psn", 4)) {
/* skip this argument */
} else {
g_mac_argv[g_mac_argc++] = argv[i];
}
i++;
}
#endif
InitCursor();
g_event_rgnhandle = NewRgn();
g_status_font_family = FMGetFontFamilyFromName("\pCourier");
SetRect(&win_rect, 0, 0, X_A2_WINDOW_WIDTH, X_A2_WINDOW_HEIGHT
// OG Remove status line from ActiveGS window
#ifndef ACTIVEGS
+ MAX_STATUS_LINES*16 + 8
#endif
);
OffsetRect(&win_rect, 64, 50);
// Create a Nib reference passing the name of the nib file
// CreateNibReference only searches into the application bundle.
err = CreateNibReference(CFSTR("main"), &nibRef);
require_noerr( err, CantGetNibRef );
// Once the nib reference is created, set the menu bar.
err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
require_noerr( err, CantSetMenuBar );
#ifndef ACTIVEGS
err = CreateNewWindow(kDocumentWindowClass,
kWindowStandardDocumentAttributes |
kWindowStandardHandlerAttribute,
&win_rect, &g_main_window);
err = SetWindowTitleWithCFString(g_main_window, CFSTR("KEGSMAC"));
#else
err = CreateNewWindow(kDocumentWindowClass,
(kWindowCloseBoxAttribute /*| kWindowFullZoomAttribute */| kWindowCollapseBoxAttribute /*| kWindowResizableAttribute*/) /*kWindowStandardDocumentAttributes*/ |
kWindowStandardHandlerAttribute,
&win_rect, &g_main_window);
extern CFStringRef activeGSversionSTR;
err = SetWindowTitleWithCFString(g_main_window, activeGSversionSTR);
#endif
//printf("CreateNewWindow ret: %d, g_main_window: %p\n", (int)err, g_main_window);
// We don't need the nib reference anymore.
DisposeNibReference(nibRef);
SysBeep(120);
handlerUPP = NewEventHandlerUPP( my_cmd_handler );
cmd_event[0].eventClass = kEventClassCommand;
cmd_event[0].eventKind = kEventProcessCommand;
InstallWindowEventHandler(g_main_window, handlerUPP, 1, &cmd_event[0],
(void *)g_main_window, NULL);
handlerUPP = NewEventHandlerUPP(my_win_handler);
cmd_event[0].eventClass = kEventClassWindow;
cmd_event[0].eventKind = kEventWindowDrawContent;
cmd_event[1].eventClass = kEventClassWindow;
cmd_event[1].eventKind = kEventWindowUpdate;
cmd_event[2].eventClass = kEventClassWindow;
cmd_event[2].eventKind = kEventWindowClose;
err = InstallWindowEventHandler(g_main_window, handlerUPP, 3,
&cmd_event[0], (void *)g_main_window, NULL);
require_noerr(err, CantCreateWindow);
// Get screen depth
g_gdhandle = GetGDevice();
g_screen_mdepth = (**((**g_gdhandle).gdPMap)).pixelSize;
g_screen_depth = g_screen_mdepth;
if(g_screen_depth > 16) {
/* 32-bit display */
g_red_mask = 0xff;
g_green_mask = 0xff;
g_blue_mask = 0xff;
/*
if (macUsingCoreGraphics)
{
g_red_left_shift = 0;
g_green_left_shift = 8;
g_blue_left_shift = 16;
}
else
*/
{
g_red_left_shift = 16;
g_green_left_shift = 8;
g_blue_left_shift = 0;
}
g_red_right_shift = 0;
g_green_right_shift = 0;
g_blue_right_shift = 0;
} else if(g_screen_depth > 8) {
/* 16-bit display */
g_red_mask = 0x1f;
g_green_mask = 0x1f;
g_blue_mask = 0x1f;
g_red_left_shift = 10;
g_green_left_shift = 5;
g_blue_left_shift = 0;
g_red_right_shift = 3;
g_green_right_shift = 3;
g_blue_right_shift = 3;
}
// show_alert("About to show window", (int)g_main_window);
update_main_window_size();
update_window();
// The window was created hidden so show it.
ShowWindow( g_main_window );
BringToFront( g_main_window );
update_window();
// Make us pop to the front a different way
err = GetCurrentProcess(&my_psn);
if(err == noErr) {
(void)SetFrontProcess(&my_psn);
}
// Call the event loop
temp_run_application_event_loop();
CantCreateWindow:
CantSetMenuBar:
CantGetNibRef:
show_simple_alert("ending", "", "error code", err);
return err;
}
void
xdriver_end()
{
printf("xdriver_end\n");
if(g_fatal_log >= 0) {
x_show_alert(1, 0);
}
}
void
x_redraw_status_lines()
{
// OG Disable status line
#ifndef ACTIVEGS
Rect rect;
Pattern white_pattern;
char tmp_buf[256];
char *buf;
int len;
int line;
int height;
int margin;
SetPortWindowPort(g_main_window);
PenNormal();
height = 16;
margin = 0;
TextFont(g_status_font_family);
TextFace(normal);
TextSize(12);
SetRect(&rect, 0, X_A2_WINDOW_HEIGHT + margin, X_A2_WINDOW_WIDTH,
X_A2_WINDOW_HEIGHT + margin + MAX_STATUS_LINES*height);
GetQDGlobalsWhite(&white_pattern);
FillRect(&rect, &white_pattern);
for(line = 0; line < MAX_STATUS_LINES; line++) {
buf = g_status_ptrs[line];
if(buf == 0) {
/* skip it */
continue;
}
MoveTo(10, X_A2_WINDOW_HEIGHT + height*line + margin + height);
len = MIN(250, strlen(buf));
strncpy(&tmp_buf[1], buf, len);
tmp_buf[0] = len;
DrawString((const unsigned char*)&tmp_buf[0]);
}
#endif
}
void
x_full_screen(int do_full)
{
#if 0
WindowRef new_window;
short width, height;
OSErr ret;
width = 640;
height = 480;
if(do_full && (g_mac_fullscreen_state == 0)) {
g_main_window_saved = g_main_window;
GetWindowBounds(g_main_window, kWindowContentRgn,
&g_main_window_saved_rect);
ret = BeginFullScreen(&g_mac_fullscreen_state, 0,
&width, &height, &new_window, 0, 0);
printf("Ret beginfullscreen: %d\n", (int)ret);
printf("New width: %d, new height: %d\n", width, height);
if(ret == noErr) {
g_main_window = new_window;
} else {
g_mac_fullscreen_state = 0;
}
} else if(!do_full && (g_mac_fullscreen_state != 0)) {
ret = EndFullScreen(g_mac_fullscreen_state, 0);
printf("ret endfullscreen: %d\n", (int)ret);
g_main_window = g_main_window_saved;
g_mac_fullscreen_state = 0;
//InitCursor();
SetWindowBounds(g_main_window, kWindowContentRgn,
&g_main_window_saved_rect);
}
update_main_window_size();
ShowWindow(g_main_window);
BringToFront(g_main_window);
update_window();
#endif
}
void
x_push_done()
{
CGrafPtr window_port;
SetPortWindowPort(g_main_window);
window_port = GetWindowPort(g_main_window);
QDFlushPortBuffer(window_port, 0);
}
void
mac_warp_mouse()
{
#ifndef ACTIVEGS
Rect port_rect;
Point win_origin_pt;
CGPoint cgpoint;
CGDisplayErr cg_err;
GetPortBounds(GetWindowPort(g_main_window), &port_rect);
SetPt(&win_origin_pt, port_rect.left, port_rect.top);
LocalToGlobal(&win_origin_pt);
cgpoint = CGPointMake( (float)(win_origin_pt.h + X_A2_WINDOW_WIDTH/2),
(float)(win_origin_pt.v + X_A2_WINDOW_HEIGHT/2));
cg_err = CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
#endif
}

View File

@ -11,9 +11,17 @@
const char rcsid_macsnd_driver_c[] = "@(#)$KmKId: macsnd_driver.c,v 1.4 2003-10-17 15:57:40-04 kentd Exp $";
#include "defc.h"
#include "sound.h"
#ifdef ACTIVEIPHONE
void child_sound_init_mac() {}
void macsnd_init(word32 *shmaddr) {}
int mac_send_audio(byte *ptr, int in_size) {}
#else
#include <Carbon/Carbon.h>
#include "sound.h"
#include <unistd.h>
#define MACSND_REBUF_SIZE (64*1024)
@ -32,6 +40,7 @@ extern word32 *g_sound_shm_addr;
extern int g_sound_size;
SndChannelPtr g_snd_channel_ptr;
ExtSoundHeader g_snd_hdr;
SndCommand g_snd_cmd;
@ -58,7 +67,7 @@ mac_snd_callback(SndChannelPtr snd_chan_ptr, SndCommand *in_sndcmd)
g_macsnd_playing = 1;
g_snd_hdr.numFrames = samps;
g_snd_hdr.loopEnd = samps;
g_snd_hdr.samplePtr = (byte *)g_macsnd_rebuf_cur;
g_snd_hdr.samplePtr = (char *)g_macsnd_rebuf_cur; // OG Cast from byte* to ,char*
g_snd_cmd.cmd = bufferCmd;
g_snd_cmd.param1 = 0;
@ -152,3 +161,4 @@ macsnd_init(word32 *shmaddr)
mac_printf("macsnd_init called\n");
child_sound_loop(-1, -1, shmaddr);
}
#endif

View File

@ -1,31 +0,0 @@
#!/usr/local/bin/perl -w
# $KmKId: make_inst,v 1.5 2002-11-07 08:18:16-08 kadickey Exp $
$is_c = shift;
$repl = shift;
$count = 0;
while(<>) {
$line = $_;
if(/^inst(..)_SYM(.*)$/) {
if($is_c eq "c") {
if($count > 0) {
printf("\tbreak;\n");
}
print "case 0x$1: $2\n";
$count++;
} else {
print "\t.align\t8\n";
print "inst" . "$1" . "_$repl" . "$2\n";
}
} elsif(/^(.*)_SYM(.*)$/) {
print "$1" . "_$repl" . "$2\n";
} else {
print $line;
}
}
# if(/^inst(..)_SYM (.*)$/) {
# print "OPCODE($1) /* $2 */\n";
# } else if(/^(

View File

@ -1,30 +0,0 @@
#!/usr/local/bin/perl -w
# $KmKId: make_size,v 1.3 2002-11-07 08:18:16-08 kadickey Exp $
$repl = shift;
while(<>) {
$line = $_;
if(/\.word inst(..)_SYM\+(.)(.*)$/) {
if($repl eq "c") {
print "\t0x$2, /* $1 */ $3\n";
} elsif($repl eq "s") {
print "\t.byte 0x$2, /* $1 */ $3\n";
} else {
print "\t.word\tinst$1" . "_$repl" . "\t/*$2*/ $3\n";
}
} elsif (/\.block.*$/) {
if($repl eq "c") {
print "\n";
} elsif($repl eq "s") {
print "\n";
} else {
print $line;
}
} else {
print $line;
}
}
# if(/^inst(..)_SYM (.*)$/) {
# print "OPCODE($1) /* $2 */\n";
# } else if(/^(

View File

@ -1,4 +0,0 @@
#!/bin/sh
export PATH="/mingw/bin:${PATH}"
make

View File

@ -12,7 +12,7 @@ const char rcsid_moremem_c[] = "@(#)$KmKId: moremem.c,v 1.251 2004-11-19 01:55:5
#include "defc.h"
extern char g_kegs_version_str[];
extern const char* g_kegs_version_str;
extern byte *g_memory_ptr;
extern byte *g_dummy_memory1_ptr;
@ -45,6 +45,8 @@ int g_paddle_buttons = 0;
int g_irq_pending = 0;
int g_c023_val = 0;
//int g_delayed_c023_val = 0; // OG Added delayed c023
int g_c029_val_some = 0x41;
int g_c02b_val = 0x08;
int g_c02d_int_crom = 0;
@ -129,6 +131,109 @@ Emustate_word32list g_emustate_word32list[] = {
halt_printf("UNIMP WRITE to addr %08x, val: %04x\n", loc, val); \
return;
//#ifdef _WINDOWS
// OG Added Transwarp ROM
#define TRANSWARP
int transwarp_low_val = 0;
#ifdef _WIN32
__declspec(align(256))
#endif
unsigned char transwarpcode[][32]
#ifndef _WIN32
__attribute__ ((aligned(256)))
#endif
={
{
/*0xBCFF00*/ 'T','W','G','S',0,0,0,0,0,0,0,0,0,0,0,0,
/*0xBCFF10*/ 0x5C,0x40,0xFF,0xBC, // JMP GetMaxSpeed
/*0xBCFF14*/ 0x5C,0x60,0xFF,0xBC, // JMP GetNumISpeed
/*0xBCFF18*/ 0x6B,0x00,0x00,0x00, // ???
/*0xBCFF1C*/ 0x6B,0x00,0x00,0x00 // ???
},
{
/*0xBCFF20*/ 0x5C,0x80,0xFF,0xBC, // JMP GetCurSpeed
/*0xBCFF24*/ 0x5C,0xA0,0xFF,0xBC, // JMP SetCurSpeed
/*0xBCFF28*/ 0x5C,0xC0,0xFF,0xBC, // JMP GetCurISpeed
/*0xBCFF2C*/ 0x5C,0xE0,0xFF,0xBC, // JMP SetCurISpeed
/*0xBCFF30*/ 0x6B,0x00,0x00,0x00, // ???
/*0xBCFF34*/ 0x6B,0x00,0x00,0x00, // ???
/*0xBCFF38*/ 0x6B,0x00,0x00,0x00, // ???
/*0xBCFF3C*/ 0x6B,0x00,0x00,0x00 // GetTWConfig
},
{
/* 0xBCFF40*/ // GetMaxSpeed
#define ZIP_SPEED 8000
0xA9, ZIP_SPEED & 0xFF, (ZIP_SPEED >> 8) &0xFF, // LDA 0x1F40 // Max Speed = 8.0Mhz
0x6B, // RTL
0x00,0x00,0x00,0x00, //4
0x00,0x00,0x00,0x00, //8
0x6B,0x00,0x00,0x00, //C Space Shark calls this address ???
},
{
/* 0xBCFF60*/ //GetNumISpeed
0xA9,0x02,0x00, // LDA 0x0002 // 0=slow, 1=normal, 2=warp
0x6B, // RTL
},
{
/* 0xBCFF80*/ //GetCurSpeed
0xAF, 0x6A, 0xC0, 0x00, // LDA 0xC06A (/6B)
0x6B, // RTL
},
{
/* 0xBCFFA0*/ //SetCurSpeed
0x8F, 0x6A, 0xC0, 0x00, // STA 0xC06A (/6B)
0x6B, // RTL
},
{
/* 0xBCFFC0*/ //GetCurISpeed
0x48, // PHA
0xAF, 0x6C, 0xC0, 0x00, // LDA 0xC06C (/6D)
0xAA, // TAX
0x68, // PLA
0x6B, // RTL
},
{
/* 0xBCFFE0*/ //SetCurISpeed
0x48, // PHA
0x8A, // TXA
0x8F, 0x6C, 0xC0, 0x00, // STA 0xC06C (/6D)
0x68, // PLA
0x6B, // RTL
}
}
;
// OG Added moremem_init()
void moremem_init()
{
g_em_emubyte_cnt = 0;
g_paddle_buttons = 0;
g_irq_pending = 0;
g_c023_val = 0;
g_c029_val_some = 0x41;
g_c02b_val = 0x08;
g_c02d_int_crom = 0;
g_c031_disk35 = 0;
g_c034_val = 0;
g_c035_shadow_reg = 0x08;
g_c036_val_speed = 0x80;
g_c03ef_doc_ptr = 0;
g_c041_val = 0; /* C041_EN_25SEC_INTS, C041_EN_MOVE_INTS */
g_c046_val = 0;
g_c05x_annuncs = 0;
g_c068_statereg = 0;
g_c08x_wrdefram = 0;
g_zipgs_unlock = 0;
g_zipgs_reg_c059 = 0x5f;
g_zipgs_reg_c05a = 0x0f;
g_zipgs_reg_c05b = 0x40;
g_zipgs_reg_c05c = 0x00;
}
void
fixup_brks()
{
@ -670,55 +775,55 @@ fixup_rdrom()
void
set_statereg(double dcycs, int val)
{
int xor;
int _xor; // OG renamed xor to _xor
xor = val ^ g_c068_statereg;
_xor = val ^ g_c068_statereg;
g_c068_statereg = val;
if(xor == 0) {
if(_xor == 0) {
return;
}
if(xor & 0x80) {
if(_xor & 0x80) {
/* altzp */
fixup_altzp();
}
if(xor & 0x40) {
if(_xor & 0x40) {
/* page2 */
g_cur_a2_stat = (g_cur_a2_stat & ~ALL_STAT_PAGE2) |
(val & ALL_STAT_PAGE2);
fixup_page2(dcycs);
}
if(xor & 0x20) {
if(_xor & 0x20) {
/* RAMRD */
fixup_ramrd();
}
if(xor & 0x10) {
if(_xor & 0x10) {
/* RAMWRT */
fixup_ramwrt();
}
if(xor & 0x08) {
if(_xor & 0x08) {
/* RDROM */
fixup_rdrom();
}
if(xor & 0x04) {
if(_xor & 0x04) {
/* LCBANK2 */
fixup_lcbank2();
}
if(xor & 0x02) {
if(_xor & 0x02) {
/* ROMBANK */
halt_printf("Just set rombank = %d\n", ROMB);
}
if(xor & 0x01) {
if(_xor & 0x01) {
fixup_intcx();
}
if(xor) {
if(_xor) {
fixup_brks();
}
}
@ -888,42 +993,42 @@ fixup_shadow_iolc()
void
update_shadow_reg(int val)
{
int xor;
int _xor;
if(g_c035_shadow_reg == val) {
return;
}
xor = g_c035_shadow_reg ^ val;
_xor = g_c035_shadow_reg ^ val;
g_c035_shadow_reg = val;
if(xor & 8) {
if(_xor & 8) {
fixup_shadow_hires1();
fixup_shadow_hires2();
fixup_shadow_shr();
xor = xor & (~0x16);
_xor = _xor & (~0x16);
}
if(xor & 0x10) {
if(_xor & 0x10) {
fixup_shadow_hires1();
fixup_shadow_hires2();
xor = xor & (~0x6);
_xor = _xor & (~0x6);
}
if(xor & 2) {
if(_xor & 2) {
fixup_shadow_hires1();
}
if(xor & 4) {
if(_xor & 4) {
fixup_shadow_hires2();
}
if(xor & 1) {
if(_xor & 1) {
fixup_shadow_txt1();
}
if((xor & 0x20) && ((g_rom_version >= 3) || g_user_page2_shadow)) {
if((_xor & 0x20) && ((g_rom_version >= 3) || g_user_page2_shadow)) {
fixup_shadow_txt2();
}
if(xor & 0x40) {
if(_xor & 0x40) {
fixup_shadow_iolc();
}
if(xor) {
if(_xor) {
fixup_brks();
}
}
@ -1014,6 +1119,10 @@ setup_pageinfo()
fixup_shadow_shr();
fixup_shadow_iolc();
fixup_brks();
#ifdef TRANSWARP // OG adding Transwarp code
SET_PAGE_INFO_RD(0xBCFF,transwarpcode);
#endif
}
void
@ -1151,7 +1260,14 @@ io_read(word32 loc, double *cyc_ptr)
case 0x22: /* 0xc022 */
return (g_cur_a2_stat >> BIT_ALL_STAT_BG_COLOR) & 0xff;
case 0x23: /* 0xc023 */
return g_c023_val;
/*
{
extern Engine_reg engine;
// printf("c023=%X (%X)\n",g_c023_val,engine.kpc);
if (engine.kpc==0xB7D84) __asm int 3;
}
*/
return g_c023_val;
case 0x24: /* 0xc024 */
return mouse_read_c024(dcycs);
case 0x25: /* 0xc025 */
@ -1398,9 +1514,31 @@ io_read(word32 loc, double *cyc_ptr)
case 0x69: /* 0xc069 */
/* Reserved reg, return 0 */
return 0;
// OG Transwarp Read Interface
#ifdef TRANSWARP
case 0x6a: /* 0xc06a */
{
extern double g_zip_pmhz;
return (int)(g_zip_pmhz*1000)&0xFF;
}
case 0x6b: /* 0xc06b */
{
extern double g_zip_pmhz;
return (((int)(g_zip_pmhz*1000))>>8)&0xFF;
}
case 0x6c: /* 0xc06c */
{
extern double g_zip_pmhz;
if (g_zip_pmhz==1.0) return 0; // slow
else if (g_zip_pmhz>=2.6) return 2; // warp
else return 1; // zip
}
#else
case 0x6a: /* 0xc06a */
case 0x6b: /* 0xc06b */
case 0x6c: /* 0xc06c */
#endif
case 0x6d: /* 0xc06d */
case 0x6e: /* 0xc06e */
case 0x6f: /* 0xc06f */
@ -1670,9 +1808,11 @@ io_write(word32 loc, int val, double *cyc_ptr)
}
tmp = (g_c023_val & 0x70) | (val & 0x0f);
if((tmp & 0x22) == 0x22) {
//printf("adding scanline irq\n");
add_irq(IRQ_PENDING_C023_SCAN);
}
if(!(tmp & 2)) {
//printf("remove scanline irq\n");
remove_irq(IRQ_PENDING_C023_SCAN);
}
if((tmp & 0x44) == 0x44) {
@ -1686,6 +1826,8 @@ io_write(word32 loc, int val, double *cyc_ptr)
IRQ_PENDING_C023_1SEC)) {
tmp |= 0x80;
}
//printf("old c023: %X new: %X\n",g_c023_val,tmp);
g_c023_val = tmp;
return;
case 0x24: /* 0xc024 */
@ -1763,16 +1905,39 @@ io_write(word32 loc, int val, double *cyc_ptr)
/* clear 1 sec int */
remove_irq(IRQ_PENDING_C023_1SEC);
tmp &= 0xbf;
//printf("c032 (1s) old: %X new: %X\n",g_c023_val,tmp & 0xbf);
g_c023_val = tmp;
}
if( (val & 0x20) == 0 && !(tmp & 0x20) )
{
irq_printf("no scan int irq to clear\n");
}
else
if(((val & 0x20) == 0) && (tmp & 0x20)) {
/* clear scan line int */
remove_irq(IRQ_PENDING_C023_SCAN);
#if 0
// OG delayed write C023 (wait end of line before clearing value)
{
extern word32 kpc;
printf("(%X) delayed clearing scanline irq old: %X new: %X\n",kpc,g_c023_val,tmp & 0xdf);
// add_event_entry(dcycs+ (DCYCS_IN_16MS/262.0)/2, 8 /*EV_DELAY_WRITE_C023*/ );
g_delayed_c023_val = 1;
}
#else
//printf("clearing g_c023_val\n");
g_c023_val = tmp & 0xdf;
check_for_new_scan_int(dcycs);
#endif
}
if(g_irq_pending & (IRQ_PENDING_C023_1SEC |
IRQ_PENDING_C023_SCAN)) {
irq_printf("c032 pending: %X\n",g_c023_val);
g_c023_val |= 0x80;
}
if((val & 0x9f) != 0x9f) {
@ -2032,9 +2197,53 @@ io_write(word32 loc, int val, double *cyc_ptr)
case 0x69: /* 0xc069 */
/* just ignore, someone writing c068 with m=0 */
return;
#ifdef TRANSWARP
// OG writeTranswarp pseudo-register
case 0x6a: /* 0xc06a */
transwarp_low_val = val;
return ;
case 0x6b: /* 0xc06b */
val = (val<<8) + transwarp_low_val;
if ((val==2600) || (val==0x0028)) // Bug for demo ...
{
printf("Disabling Transwarp!\n");
g_zipgs_reg_c05b |= 0x10; // disable
set_halt(HALT_EVENT);
}
else if (val==8000)
{
printf("Enabling Transwarp!\n");
g_zipgs_reg_c05b &= ~0x10; // enable
set_halt(HALT_EVENT);
}
else
printf("unknown twgs speed:%d\n",val);
return;
case 0x6c: /* 0xc06c */
if (val==0)
; // set slow ?
else if (val==1)
{
// disable zip
g_zipgs_reg_c05b |= 0x10; // disable
set_halt(HALT_EVENT);
}
else if (val==2)
{
// enable zip
g_zipgs_reg_c05b &= ~0x10; // enable
set_halt(HALT_EVENT);
}
else
printf("unknown twgs index:%d\n",val);
return ;
#else
case 0x6a: /* 0xc06a */
case 0x6b: /* 0xc06b */
case 0x6c: /* 0xc06c */
#endif
case 0x6d: /* 0xc06d */
case 0x6e: /* 0xc06e */
case 0x6f: /* 0xc06f */

View File

@ -1,169 +0,0 @@
<?xml version="1.0" standalone="yes"?>
<object class="NSIBObjectData">
<string name="targetFramework">IBCarbonFramework</string>
<object name="rootObject" class="NSCustomObject" id="1">
<string name="customClass">NSApplication</string>
</object>
<array count="18" name="allObjects">
<object class="IBCarbonMenu" id="29">
<string name="title">main</string>
<array count="3" name="items">
<object class="IBCarbonMenuItem" id="185">
<string name="title">KEGSMAC</string>
<object name="submenu" class="IBCarbonMenu" id="184">
<string name="title">KEGSMAC</string>
<array count="3" name="items">
<object class="IBCarbonMenuItem" id="187">
<string name="title">About KEGSMAC</string>
<int name="keyEquivalentModifier">0</int>
<ostype name="command">abou</ostype>
</object>
<object class="IBCarbonMenuItem" id="199">
<boolean name="separator">TRUE</boolean>
</object>
<object class="IBCarbonMenuItem" id="198">
<string name="title">Quit</string>
<int name="keyEquivalentModifier">0</int>
<ostype name="command">quit</ostype>
</object>
</array>
<string name="name">_NSAppleMenu</string>
</object>
</object>
<object class="IBCarbonMenuItem" id="127">
<string name="title">File</string>
<object name="submenu" class="IBCarbonMenu" id="131">
<string name="title">File</string>
<array count="1" name="items">
<object class="IBCarbonMenuItem" id="200">
<string name="title">Configuration F4</string>
<int name="keyEquivalentModifier">0</int>
<ostype name="command">KCFG</ostype>
<string name="helpTagText">Enter KEGS Configuration Panel</string>
</object>
</array>
</object>
</object>
<object class="IBCarbonMenuItem" id="192">
<string name="title">Window</string>
<object name="submenu" class="IBCarbonMenu" id="195">
<string name="title">Window</string>
<array count="6" name="items">
<object class="IBCarbonMenuItem" id="197">
<string name="title">Zoom Window</string>
<ostype name="command">zoom</ostype>
</object>
<object class="IBCarbonMenuItem" id="190">
<boolean name="dynamic">TRUE</boolean>
<string name="title">Minimize Window</string>
<int name="keyEquivalentModifier">0</int>
<ostype name="command">mini</ostype>
</object>
<object class="IBCarbonMenuItem" id="191">
<boolean name="dynamic">TRUE</boolean>
<string name="title">Minimize All Windows</string>
<int name="keyEquivalentModifier">0</int>
<ostype name="command">mina</ostype>
</object>
<object class="IBCarbonMenuItem" id="194">
<boolean name="separator">TRUE</boolean>
</object>
<object class="IBCarbonMenuItem" id="196">
<boolean name="dynamic">TRUE</boolean>
<string name="title">Bring All to Front</string>
<ostype name="command">bfrt</ostype>
</object>
<object class="IBCarbonMenuItem" id="193">
<boolean name="dynamic">TRUE</boolean>
<string name="title">Arrange in Front</string>
<int name="keyEquivalentModifier">1572864</int>
<ostype name="command">frnt</ostype>
</object>
</array>
<string name="name">_NSWindowsMenu</string>
</object>
</object>
</array>
<string name="name">_NSMainMenu</string>
</object>
<reference idRef="127"/>
<reference idRef="131"/>
<object class="IBCarbonMenuItem" id="153">
<string name="title">Window</string>
<object name="submenu" class="IBCarbonMenu">
<string name="title">Window</string>
<array count="5" name="items">
<object class="IBCarbonMenuItem">
<boolean name="dynamic">TRUE</boolean>
<string name="title">Minimize Window</string>
<string name="keyEquivalent">m</string>
<ostype name="command">mini</ostype>
</object>
<object class="IBCarbonMenuItem">
<boolean name="dynamic">TRUE</boolean>
<string name="title">Minimize All Windows</string>
<string name="keyEquivalent">m</string>
<int name="keyEquivalentModifier">1572864</int>
<ostype name="command">mini</ostype>
</object>
<object class="IBCarbonMenuItem">
<boolean name="separator">TRUE</boolean>
</object>
<object class="IBCarbonMenuItem">
<boolean name="dynamic">TRUE</boolean>
<string name="title">Bring All to Front</string>
<ostype name="command">frnt</ostype>
</object>
<object class="IBCarbonMenuItem">
<boolean name="dynamic">TRUE</boolean>
<string name="title">Bring in Front</string>
<int name="keyEquivalentModifier">1572864</int>
<ostype name="command">frnt</ostype>
</object>
</array>
<string name="name">_NSWindowsMenu</string>
</object>
</object>
<reference idRef="184"/>
<reference idRef="185"/>
<reference idRef="187"/>
<reference idRef="190"/>
<reference idRef="191"/>
<reference idRef="192"/>
<reference idRef="193"/>
<reference idRef="194"/>
<reference idRef="195"/>
<reference idRef="196"/>
<reference idRef="197"/>
<reference idRef="198"/>
<reference idRef="199"/>
<reference idRef="200"/>
</array>
<array count="18" name="allParents">
<reference idRef="1"/>
<reference idRef="29"/>
<reference idRef="127"/>
<reference idRef="29"/>
<reference idRef="185"/>
<reference idRef="29"/>
<reference idRef="184"/>
<reference idRef="195"/>
<reference idRef="195"/>
<reference idRef="29"/>
<reference idRef="195"/>
<reference idRef="195"/>
<reference idRef="192"/>
<reference idRef="195"/>
<reference idRef="195"/>
<reference idRef="184"/>
<reference idRef="184"/>
<reference idRef="131"/>
</array>
<dictionary count="2" name="nameTable">
<string>Files Owner</string>
<reference idRef="1"/>
<string>MenuBar</string>
<reference idRef="29"/>
</dictionary>
<unsigned_int name="nextObjectID">201</unsigned_int>
</object>

View File

@ -23,7 +23,7 @@ int g_joystick_scale_factor_y = 0x100;
int g_joystick_trim_amount_x = 0;
int g_joystick_trim_amount_y = 0;
int g_joystick_type = 0; /* 0 = Keypad Joystick */
int g_joystick_type = JOYSTICK_TYPE_NATIVE_1; // OG Trying to set native joystick as default
int g_joystick_native_type1 = -1;
int g_joystick_native_type2 = -1;
int g_joystick_native_type = -1;
@ -37,20 +37,23 @@ double g_paddle_dcycs[4] = { 0.0, 0.0, 0.0, 0.0 };
/* g_paddle_dcycs are the dcycs the paddle goes to 0 */
void
paddle_fixup_joystick_type()
{
/* If g_joystick_type points to an illegal value, change it */
if(g_joystick_type == 2) {
if(g_joystick_type == JOYSTICK_TYPE_NATIVE_1) {
g_joystick_native_type = g_joystick_native_type1;
if(g_joystick_native_type1 < 0) {
g_joystick_type = 0;
g_joystick_type = JOYSTICK_TYPE_KEYPAD;
printf("no joy 1 --- switching to keypad\n");
}
}
if(g_joystick_type == 3) {
if(g_joystick_type == JOYSTICK_TYPE_NATIVE_2) {
g_joystick_native_type = g_joystick_native_type2;
if(g_joystick_native_type2 < 0) {
g_joystick_type = 0;
g_joystick_type = JOYSTICK_TYPE_KEYPAD;
printf("no joy 2 --- switching to keypad\n");
}
}
}
@ -65,10 +68,13 @@ paddle_trigger(double dcycs)
paddle_fixup_joystick_type();
switch(g_joystick_type) {
case 0: /* Keypad Joystick */
case JOYSTICK_TYPE_KEYPAD: /* Keypad Joystick */
paddle_trigger_keypad(dcycs);
break;
case 1: /* Mouse Joystick */
case JOYSTICK_TYPE_MOUSE: /* Mouse Joystick */
paddle_trigger_mouse(dcycs);
break;
case JOYSTICK_TYPE_NONE: /* Mouse Joystick */
paddle_trigger_mouse(dcycs);
break;
default:

0
jni/partls.c Executable file → Normal file
View File

0
jni/prodos.h Executable file → Normal file
View File

0
jni/prodos_protos.h Executable file → Normal file
View File

View File

@ -42,6 +42,7 @@ void do_gen_test(int got_num, int base_seed);
/* engine.s and engine_c.c */
void fixed_memory_ptrs_init();
void fixed_memory_ptrs_shut(); // OG Added shut to smoothly free up allocated memory
word32 get_itimer(void);
word32 get_memory_c(word32 addr, int cycs);
@ -84,6 +85,7 @@ void joystick_update_buttons(void);
/* adb.c */
void adb_init(void);
void adb_shut(); // OG Added adb_shut()
void adb_reset(void);
void adb_log(word32 addr, int val);
void show_adb_log(void);
@ -284,6 +286,7 @@ void scc_socket_do_answer(int port, double dcycs);
void iwm_init_drive(Disk *dsk, int smartport, int drive, int disk_525);
void disk_set_num_tracks(Disk *dsk, int num_tracks);
void iwm_init(void);
void iwm_shut(void); //OG
void iwm_reset(void);
void draw_iwm_status(int line, char *buf);
void iwm_flush_disk_to_unix(Disk *dsk);
@ -324,6 +327,7 @@ void iwm_show_a_track(Trk *trk);
/* moremem.c */
void moremem_init(); // OG Added moremem_init()
void fixup_brks(void);
void fixup_hires_on(void);
void fixup_bank0_2000_4000(void);
@ -382,8 +386,10 @@ void do_reset(void);
void check_engine_asm_defines(void);
byte *memalloc_align(int size, int skip_amt, void **alloc_ptr);
void memory_ptr_init(void);
void memory_ptr_shut(void); // OG Added shut
int kegsmain(int argc, char **argv);
void load_roms_init_memory(void);
void load_roms_shut_memory(void); // OG Added shut
void kegs_expand_path(char *out_ptr, const char *in_ptr, int maxlen);
void setup_kegs_file(char *outname, int maxlen, int ok_if_missing, int can_create_file, const char **name_ptr);
void initialize_events(void);

View File

@ -13,15 +13,11 @@ const char rcsid_protos_mac_h[] = "@(#)$KmKId: protos_macdriver.h,v 1.11 2004-11
/* END_HDR */
/* macdriver.c */
pascal OSStatus quit_event_handler(EventHandlerCallRef call_ref, EventRef event, void *ignore);
void show_simple_alert(char *str1, char *str2, char *str3, int num);
void x_dialog_create_kegs_conf(const char *str);
int x_show_alert(int is_fatal, const char *str);
pascal OSStatus my_cmd_handler(EventHandlerCallRef handlerRef, EventRef event, void *userdata);
void update_window(void);
void show_event(UInt32 event_class, UInt32 event_kind, int handled);
pascal OSStatus my_win_handler(EventHandlerCallRef handlerRef, EventRef event, void *userdata);
pascal OSStatus dummy_event_handler(EventHandlerCallRef call_ref, EventRef in_event, void *ignore);
int x_show_alert(int is_fatal, const char *str);void update_window(void);
void mac_update_modifiers(word32 state);
void mac_warp_mouse(void);
void check_input_events(void);

View File

@ -14,7 +14,7 @@
/* windriver.c */
int win_update_mouse(int x, int y, int button_states, int buttons_valid);
void win_event_mouse(WPARAM wParam, LPARAM lParam);
void win_event_mouse(int umsg,WPARAM wParam, LPARAM lParam);
void win_event_key(HWND hwnd, UINT raw_vk, BOOL down, int repeat, UINT flags);
void win_event_quit(HWND hwnd);
void win_event_redraw(void);

View File

@ -12,6 +12,10 @@ const char rcsid_scc_c[] = "@(#)$KmKId: scc.c,v 1.44 2004-12-03 17:33:40-05 kent
#include "defc.h"
#ifdef UNDER_CE
#define vsnprintf _vsnprintf
#endif
extern int Verbose;
extern int g_code_yellow;
extern double g_cur_dcycs;
@ -1113,7 +1117,7 @@ scc_add_to_readbufv(int port, double dcycs, const char *fmt, ...)
int i;
va_start(ap, fmt);
bufptr = malloc(4096);
bufptr = (char*)malloc(4096); // OG cast added
bufptr[0] = 0;
ret = vsnprintf(bufptr, 4090, fmt, ap);
len = strlen(bufptr);

View File

@ -23,8 +23,10 @@ const char rcsid_scc_h[] = "@(#)$KmKId: scc.h,v 1.17 2004-12-03 14:03:12-05 kent
#endif
#if defined(HPUX) || defined(__linux__) || defined(SOLARIS) || defined(MAC) || defined(__MACH__) || defined(_WIN32)
#ifndef __ANDROID__
# define SCC_SOCKETS
#endif
#endif
/* my scc port 0 == channel A, port 1 = channel B */

View File

@ -70,7 +70,7 @@ scc_serial_mac_change_params(int port)
scc_ptr = &(scc_stat[port]);
fd = (int)scc_ptr->host_handle;
fd = (intptr_t)scc_ptr->host_handle;
printf("scc_serial_mac_change_parms port: %d, fd: %d\n", port, fd);
if(fd <= 0) {
return;
@ -140,7 +140,7 @@ scc_serial_mac_fill_readbuf(int port, int space_left, double dcycs)
scc_ptr = &(scc_stat[port]);
fd = (int)scc_ptr->host_handle;
fd = (intptr_t)scc_ptr->host_handle;
if(fd <= 0) {
return;
}
@ -170,7 +170,7 @@ scc_serial_mac_empty_writebuf(int port)
scc_ptr = &(scc_stat[port]);
fd = (int)scc_ptr->host_handle;
fd = (intptr_t)scc_ptr->host_handle;
if(fd <= 0) {
return;
}

View File

@ -14,12 +14,17 @@ const char rcsid_scc_socket_driver_c[] = "@(#)$KmKId: scc_socket_driver.c,v 1.11
#include "defc.h"
#include "scc.h"
#ifndef UNDER_CE //OG
#include <signal.h>
#endif
extern Scc scc_stat[2];
extern int g_serial_modem[];
#ifndef _MSC_VER //OG
extern int h_errno;
#else
#define socklen_t int
#endif
int g_wsastartup_called = 0;
/* Usage: scc_socket_init() called to init socket mode */
@ -186,7 +191,7 @@ scc_socket_open_outgoing(int port, double dcycs)
memset(&sa_in, 0, sizeof(sa_in));
sa_in.sin_family = AF_INET;
sa_in.sin_port = htons(23);
hostentptr = gethostbyname(&scc_ptr->modem_cmd_str[0]);
hostentptr = gethostbyname((const char*)&scc_ptr->modem_cmd_str[0]); // OG Added Cast
if(hostentptr == 0) {
#ifdef _WIN32
fatal_printf("Lookup host %s failed\n",
@ -343,8 +348,8 @@ scc_accept_socket(int port, double dcycs)
return; /* just give up */
}
if(scc_ptr->rdwrfd == -1) {
rdwrfd = accept(scc_ptr->sockfd, scc_ptr->host_handle,
&(scc_ptr->host_aux1));
rdwrfd = accept(scc_ptr->sockfd, (sockaddr*)scc_ptr->host_handle,
(socklen_t*)&(scc_ptr->host_aux1));
if(rdwrfd < 0) {
return;
}
@ -439,7 +444,7 @@ scc_socket_fill_readbuf(int port, int space_left, double dcycs)
/* Try reading some bytes */
space_left = MIN(space_left, 256);
ret = recv(rdwrfd, tmp_buf, space_left, 0);
ret = recv(rdwrfd, (char*)tmp_buf, space_left, 0); // OG Added cast
if(ret > 0) {
for(i = 0; i < ret; i++) {
if(tmp_buf[i] == 0) {
@ -731,7 +736,7 @@ scc_socket_empty_writebuf(int port, double dcycs)
}
# ifdef _WIN32
ret = send(rdwrfd, &(scc_ptr->out_buf[rdptr]), len, 0);
ret = send(rdwrfd, (const char*)&(scc_ptr->out_buf[rdptr]), len, 0); // OG Added Cast
# else
/* ignore SIGPIPE around writes to the socket, so we */
/* can catch a closed socket and prepare to accept */
@ -791,7 +796,7 @@ scc_socket_modem_write(int port, int c, double dcycs)
}
modem_mode = scc_ptr->modem_mode;
str = &(scc_ptr->modem_cmd_str[0]);
str = (char*)&(scc_ptr->modem_cmd_str[0]); // OG Added Cast
#if 0
printf("M: %02x\n", c);
@ -855,7 +860,7 @@ scc_socket_do_cmd_str(int port, double dcycs)
scc_ptr = &(scc_stat[port]);
str = &(scc_ptr->modem_cmd_str[0]);
str = (char*)&(scc_ptr->modem_cmd_str[0]); // OG Added cast
printf("Got modem string :%s:=%02x %02x %02x\n", str, str[0], str[1],
str[2]);
@ -1093,7 +1098,7 @@ scc_socket_modem_do_ring(int port, double dcycs)
num_rings = 0;
}
scc_ptr->socket_num_rings = num_rings;
scc_ptr->socket_last_ring_dcycs = dcycs;
scc_ptr->socket_last_ring_dcycs = (int)dcycs;
if(num_rings <= 0) {
/* decide on answering */
if(scc_ptr->modem_s0_val || (g_serial_modem[port]==0)) {

View File

@ -15,6 +15,10 @@ const char rcsid_scc_windriver_c[] = "@(#)$KmKId: scc_windriver.c,v 1.4 2004-11-
#include "defc.h"
#include "scc.h"
#ifdef UNDER_CE
#define vsnprintf _vsnprintf
#endif
extern Scc scc_stat[2];
extern word32 g_c025_val;
@ -23,7 +27,7 @@ int
scc_serial_win_init(int port)
{
COMMTIMEOUTS commtimeouts;
char str_buf[8];
TCHAR str_buf[8];
Scc *scc_ptr;
HANDLE host_handle;
int state;
@ -33,8 +37,11 @@ scc_serial_win_init(int port)
scc_ptr->state = 0; /* mark as failed */
#ifdef UNICODE
wsprintf(&str_buf[0], _T("COM%d"), port+1);
#else
sprintf(&str_buf[0], "COM%d", port+1);
#endif
host_handle = CreateFile(&str_buf[0], GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
@ -79,7 +86,7 @@ scc_serial_win_change_params(int port)
scc_ptr = &(scc_stat[port]);
host_handle = scc_ptr->host_handle;
dcbptr = scc_ptr->host_handle2;
dcbptr = (DCB*)scc_ptr->host_handle2; // OG Added cast
if(host_handle == 0) {
return;
}
@ -157,7 +164,7 @@ scc_serial_win_fill_readbuf(int port, int space_left, double dcycs)
Scc *scc_ptr;
HANDLE host_handle;
DWORD bytes_read;
int i;
DWORD i;
int ret;
scc_ptr = &(scc_stat[port]);

View File

@ -16,8 +16,16 @@ const char rcsid_sim65816_c[] = "@(#)$KmKId: sim65816.c,v 1.367 2004-11-22 02:39
#include "defc.h"
#undef INCLUDE_RCSID_C
#ifdef UNDER_CE
#define vsnprintf _vsnprintf
#endif
#define PC_LOG_LEN (8*1024)
int g_speed_fast ; // OG Expose fast parameter
int g_initialized = 0; // OG To know if the emulator has finalized its initialization
int g_accept_events = 0; // OG To know if the emulator is ready to accept external events
char g_argv0_path[256] = "./";
@ -27,7 +35,7 @@ const char *g_kegs_default_paths[] = { "", "./", "/mnt/sdcard/KEGS/",
"/mnt/sdcard/kegs/",
"/sdcard/kegs/",
"/storage/sdcard0/kegs/",
"${0}/", 0 };
"${0}/", 0 };
#define MAX_EVENTS 64
@ -40,6 +48,7 @@ const char *g_kegs_default_paths[] = { "", "./", "/mnt/sdcard/KEGS/",
#define EV_VBL_INT 5
#define EV_SCC 6
#define EV_VID_UPD 7
//#define EV_DELAY_WRITE_C023 8
extern int g_stepping;
@ -102,7 +111,9 @@ int g_serial_out_masking = 0;
int g_serial_modem[2] = { 0, 1 };
int g_config_iwm_vbl_count = 0;
const char g_kegs_version_str[] = "0.91";
const char* g_kegs_version_str = "0.91";
int g_pause=0; // OG Added pause
#define START_DCYCS (0.0)
@ -159,6 +170,13 @@ byte *g_dummy_memory1_ptr = 0;
byte *g_rom_fc_ff_ptr = 0;
byte *g_rom_cards_ptr = 0;
// OG Added allocated pointers
byte *g_slow_memory_ptr_allocated = 0;
byte *g_memory_ptr_allocated = 0;
byte *g_dummy_memory1_ptr_allocated = 0;
byte *g_rom_fc_ff_ptr_allocated = 0;
byte *g_rom_cards_ptr_allocated = 0;
void *g_memory_alloc_ptr = 0; /* for freeing memory area */
Page_info page_info_rd_wr[2*65536 + PAGE_INFO_PAD_SIZE];
@ -174,6 +192,69 @@ Data_log *g_log_data_ptr = &(g_data_log_array[0]);
Data_log *g_log_data_start_ptr = &(g_data_log_array[0]);
Data_log *g_log_data_end_ptr = &(g_data_log_array[PC_LOG_LEN]);
// OG Added sim65816_initglobals()
void sim65816_initglobals()
{
g_fcycles_stop = 0.0;
halt_sim = 0;
enter_debug = 0;
g_rom_version = -1;
g_user_halt_bad = 0;
g_halt_on_bad_read = 0;
g_ignore_bad_acc = 1;
g_ignore_halts = 1;
g_code_red = 0;
g_code_yellow = 0;
g_use_alib = 0;
g_raw_serial = 1;
g_iw2_emul = 0;
g_serial_out_masking = 0;
//g_serial_modem[2] = { 0, 1 };
g_config_iwm_vbl_count = 0;
g_pause=0;
g_last_vbl_dcycs = START_DCYCS;
g_cur_dcycs = START_DCYCS;
g_last_vbl_dadjcycs = 0.0;
g_dadjcycs = 0.0;
g_wait_pending = 0;
g_stp_pending = 0;
g_num_irq = 0;
g_num_brk = 0;
g_num_cop = 0;
g_num_enter_engine = 0;
g_io_amt = 0;
g_engine_action = 0;
g_engine_halt_event = 0;
g_engine_scan_int = 0;
g_engine_doc_int = 0;
g_testing = 0;
g_testing_enabled = 0;
g_debug_file_fd = -1;
g_fatal_log = -1;
g_25sec_cntr = 0;
g_1sec_cntr = 0;
g_dnatcycs_1sec = 0.0;
g_natcycs_lastvbl = 0;
Verbose = 0;
Halt_on = 0;
g_mem_size_base = 256*1024; /* size of motherboard memory */
g_mem_size_exp = 8*1024*1024; /* size of expansion RAM card */
g_mem_size_total = 256*1024; /* Total contiguous RAM from 0 */
}
void
show_pc_log()
@ -303,7 +384,7 @@ toolbox_debug_c(word32 xreg, word32 stack, double *cyc_ptr)
pos = g_toolbox_log_pos;
stack += 9;
g_toolbox_log_array[pos][0] = g_last_vbl_dcycs + *cyc_ptr;
g_toolbox_log_array[pos][0] = (word32)(g_last_vbl_dcycs + *cyc_ptr);
g_toolbox_log_array[pos][1] = stack+1;
g_toolbox_log_array[pos][2] = xreg;
g_toolbox_log_array[pos][3] = toolbox_debug_4byte(stack+1);
@ -596,12 +677,28 @@ show_regs()
show_regs_act(&engine);
}
void
my_exit(int ret)
//OG for regular exit, use quitEmulator()
void quitEmulator()
{
printf("set_halt(HALT_WANTTOQUIT)\n");
set_halt(HALT_WANTTOQUIT);
}
//OG change exit to fatal_exit()
#ifndef ACTIVEGS
// use standard exit function
#define fatalExit exit
#else
extern void fatalExit(int);
#endif
void my_exit(int ret)
{
end_screen();
printf("exiting\n");
exit(ret);
printf("exiting (ret=%d)\n",ret);
fatalExit(ret);
}
@ -641,6 +738,46 @@ do_reset()
g_stepping = 0;
// OG Cleared remaining IRQS on RESET
{
extern int g_irq_pending;
extern int g_scan_int_events ;
extern int g_c023_val;
/*
#define REMOVEIRQ(ADR) { extern int ADR; if (ADR) { remove_irq(); ADR=0; } }
#define CLEARIRQ(ADR) { extern int ADR; ADR=0; }
REMOVEIRQ(g_adb_kbd_srq_sent);
REMOVEIRQ(g_adb_data_int_sent);
REMOVEIRQ(g_adb_mouse_int_sent);
REMOVEIRQ(c046_vbl_irq_pending);
REMOVEIRQ(c046_25sec_irq_pend);
REMOVEIRQ(c023_scan_int_irq_pending);
REMOVEIRQ(c023_1sec_int_irq_pending);
REMOVEIRQ(c046_vbl_irq_pending);
CLEARIRQ(c041_en_25sec_ints);
CLEARIRQ(c041_en_vbl_ints);
CLEARIRQ(c041_en_switch_ints);
CLEARIRQ(c041_en_move_ints);
CLEARIRQ(c041_en_mouse);
g_scan_int_events = 0;
initialize_events();
*/
if (g_irq_pending)
halt_printf("*** irq remainings...\n");
/*
g_irq_pending = 0;
// reinitiliase zip speed (not sure)???
// g_zipgs_reg_c05a = 0x80;
*/
}
}
#define CHECK(start, var, value, var1, var2) \
@ -695,6 +832,7 @@ check_engine_asm_defines()
CHECK(fplusptr, fplusptr->plus_x_minus_1, FPLUS_PLUS_X_M1, val1, val2);
}
byte *
memalloc_align(int size, int skip_amt, void **alloc_ptr)
{
@ -703,7 +841,7 @@ memalloc_align(int size, int skip_amt, void **alloc_ptr)
word32 offset;
skip_amt = MAX(256, skip_amt);
bptr = calloc(size + skip_amt, 1);
bptr = (byte*)calloc(size + skip_amt + 256, 1); // OG Added cast
if(alloc_ptr) {
/* Save allocation address */
*alloc_ptr = bptr;
@ -728,16 +866,35 @@ memory_ptr_init()
/* changes this will be called */
mem_size = MIN(0xdf0000, g_mem_size_base + g_mem_size_exp);
g_mem_size_total = mem_size;
// OG using memory_ptr_shut() instead
memory_ptr_shut();
/*
if(g_memory_alloc_ptr) {
free(g_memory_alloc_ptr);
g_memory_alloc_ptr = 0;
}
*/
g_memory_ptr = memalloc_align(mem_size, 256, &g_memory_alloc_ptr);
printf("RAM size is 0 - %06x (%.2fMB)\n", mem_size,
(double)mem_size/(1024.0*1024.0));
}
// OG Added memory_ptr_shut
void
memory_ptr_shut()
{
if(g_memory_alloc_ptr)
{
free(g_memory_alloc_ptr);
g_memory_alloc_ptr = 0;
}
g_memory_ptr = 0;
}
extern int g_screen_redraw_skip_amt;
extern int g_use_shmem;
extern int g_use_dhr140;
@ -747,12 +904,19 @@ char g_display_env[512];
int g_force_depth = -1;
int g_screen_depth = 8;
int
kegsmain(int argc, char **argv)
{
int skip_amt;
int diff;
// OG Restoring globals
sim65816_initglobals();
moremem_init();
//OG Disabling argument parsing
#ifndef ACTIVEGS
int skip_amt;
int tmp1;
int i;
@ -857,6 +1021,7 @@ kegsmain(int argc, char **argv)
exit(3);
}
}
#endif
check_engine_asm_defines();
fixed_memory_ptrs_init();
@ -913,12 +1078,33 @@ kegsmain(int argc, char **argv)
do_reset();
g_stepping = 0;
// OG Notify emulator has been initialized and ready to accept external events
g_initialized = 1;
g_accept_events = 1;
do_go();
/* If we get here, we hit a breakpoint, call debug intfc */
do_debug_intfc();
my_exit(0);
// OG Notify emulator is being closed, and cannot accept events anymore
g_accept_events = 0;
sound_shutdown();
// OG Cleaning up
adb_shut();
iwm_shut();
fixed_memory_ptrs_shut();
load_roms_shut_memory();
clear_fatal_logs();
// OG Not needed anymore : the emulator will quit gently
//my_exit(0);
end_screen();
return 0;
}
@ -943,6 +1129,14 @@ load_roms_init_memory()
set_memory16_c(0xe115fe, 0, 0);
}
// OG Added load_roms_shut_memory
void load_roms_shut_memory()
{
memory_ptr_shut();
}
#ifndef ACTIVEGS
void
kegs_expand_path(char *out_ptr, const char *in_ptr, int maxlen)
{
@ -1080,6 +1274,8 @@ setup_kegs_file(char *outname, int maxlen, int ok_if_missing,
my_exit(2);
}
#endif
Event g_event_list[MAX_EVENTS];
Event g_event_free;
Event g_event_start;
@ -1412,10 +1608,13 @@ run_prog()
while(1) {
fflush(stdout);
// OG Disabling control panel
#ifndef ACTIVEGS
if(g_config_control_panel) {
config_control_panel();
}
#endif
if(g_irq_pending && !(engine.psr & 0x4)) {
irq_printf("taking an irq!\n");
take_irq(0);
@ -1429,7 +1628,8 @@ run_prog()
zip_follow_cps = ((g_zipgs_reg_c059 & 0x8) != 0);
zip_speed_0tof_new = g_zipgs_reg_c05a & 0xf0;
fast = (g_c036_val_speed & 0x80) || (zip_en && !zip_follow_cps);
// OG Make fast parameter public
g_speed_fast = fast;
if(zip_speed_0tof_new != zip_speed_0tof) {
zip_speed_0tof = zip_speed_0tof_new;
setup_zip_speeds();
@ -1444,7 +1644,11 @@ run_prog()
zip_speed = faster_than_28 &&
((zip_speed_0tof != 0) || (limit_speed == 3) ||
(g_zipgs_unlock >= 4) );
unl_speed = faster_than_28 && !zip_speed;
// OG unlimited speed should not be affected by zip.
// unl_speed = faster_than_28 && !zip_speed;
unl_speed = (limit_speed == 0) && faster_than_28;
if(unl_speed) {
/* use unlimited speed */
fspeed_mult = g_projected_pmhz;
@ -1563,6 +1767,16 @@ run_prog()
case EV_VID_UPD:
video_update_event_line(type >> 8);
break;
/*
// OG Added DelayWriteC023 Event
case EV_DELAY_WRITE_C023:
{
extern int g_c023_val;
printf("clearing c023 for line(%d)\n",type>>8);
g_c023_val = g_c023_val & 0xDF & 0x7F;
}
break;
*/
default:
printf("Unknown event: %d!\n", type);
exit(3);
@ -1854,6 +2068,13 @@ update_60hz(double dcycs, double dtime_now)
default: sp_str = "Unlimited"; break;
}
// OG Pass speed info to the control (ActiveX specific)
#ifdef ACTIVEGS
{
extern void updateInfo(const char* target,const char *speed);
updateInfo(sp_str,total_mhz_ptr);
}
#endif
sprintf(status_buf, "dcycs:%9.1f sim MHz:%s "
"Eff MHz:%s, sec:%1.3f vol:%02x pal:%x, Limit:%s",
dcycs/(1000.0*1000.0), sim_mhz_ptr, total_mhz_ptr,
@ -2066,9 +2287,22 @@ update_60hz(double dcycs, double dtime_now)
irq_printf("Setting c023 to %02x irq_pend: %d\n",
tmp, g_irq_pending);
}
irq_printf("1s irq: %X new: %X\n",g_c023_val,tmp);
g_c023_val = tmp;
}
/*
{
extern int g_delayed_c023_val;
if (g_delayed_c023_val)
{
g_c023_val = g_c023_val & 0xDF;
g_delayed_c023_val = 0;
printf("clearing c023 val\n");
}
}
*/
if(!g_scan_int_events) {
check_scan_line_int(dcycs, 0);
}
@ -2082,7 +2316,17 @@ update_60hz(double dcycs, double dtime_now)
}
iwm_vbl_update(doit_3_persec);
// OG Disabling config update
#ifndef ACTIVEGS
config_vbl_update(doit_3_persec);
#else
// OG Added disk update
{
extern void checkImages();
checkImages();
}
#endif
video_update();
sound_update(dcycs);
@ -2121,9 +2365,9 @@ do_scan_int(double dcycs, int line)
c023_val |= 0xa0; /* vgc_int and scan_int */
if(c023_val & 0x02) {
add_irq(IRQ_PENDING_C023_SCAN);
irq_printf("Setting c023 to %02x, irq_pend: %d\n",
c023_val, g_irq_pending);
irq_printf("Setting c023 to %02x, irq_pend: %d\n", c023_val, g_irq_pending);
}
g_c023_val = c023_val;
HALT_ON(HALT_ON_SCAN_INT, "In do_scan_int\n");
} else {
@ -2167,10 +2411,11 @@ check_scan_line_int(double dcycs, int cur_video_line)
i = 0;
}
if(g_slow_memory_ptr[0x19d00+i] & 0x40) {
irq_printf("Adding scan_int for line %d\n", i);
delay = (DCYCS_IN_16MS/262.0) * ((double)line);
//printf("Adding scan_int for line %d\n", i);
delay = (int)( (DCYCS_IN_16MS/262.0) * ((double)line) );
add_event_entry(g_last_vbl_dcycs + delay, EV_SCAN_INT +
(line << 8));
//add_event_entry(g_last_vbl_dcycs + delay + (DCYCS_IN_16MS/262.0)*4/5 , EV_DELAY_WRITE_C023+ (line << 8));
g_scan_int_events = 1;
check_for_one_event_type(EV_SCAN_INT);
break;
@ -2384,12 +2629,15 @@ kegs_vprintf(const char *fmt, va_list ap)
int len;
int ret;
bufptr = malloc(4096);
bufptr = (char*)malloc(4096); // OG Added Cast
ret = vsnprintf(bufptr, 4090, fmt, ap);
// OG Display warning
printf("Warning:%s",bufptr);
len = strlen(bufptr);
if(g_fatal_log >= 0 && g_fatal_log < MAX_FATAL_LOGS) {
buf2ptr = malloc(len+1);
buf2ptr = (char*)malloc(len+1); // OG Added Cast
memcpy(buf2ptr, bufptr, len+1);
g_fatal_log_strs[g_fatal_log++] = buf2ptr;
}
@ -2437,7 +2685,7 @@ kegs_malloc_str(char *in_str)
int len;
len = strlen(in_str) + 1;
str = malloc(len);
str = (char*)malloc(len); // OG Added cast
memcpy(str, in_str, len);
return str;

View File

@ -18,7 +18,7 @@ extern int g_rom_version;
extern int g_io_amt;
extern int g_highest_smartport_unit;
int g_cycs_in_io_read = 0;
word32 g_cycs_in_io_read = 0; // OG Changed int to word32
extern Engine_reg engine;
@ -566,7 +566,7 @@ do_read_c7(int unit_num, word32 buf, int blk)
return 0x27;
}
len = read(fd, &local_buf[0], 0x200);
len = read(fd, (char*)&local_buf[0], 0x200);
if(len != 0x200) {
printf("read returned %08x, errno:%d, blk:%04x, unit: %02x\n",
len, errno, blk, unit_num);

View File

@ -230,6 +230,31 @@ sound_init()
rptr->last_samp_val = 0;
}
// OG sound globals initialization
g_num_c030_fsamps = 0;
g_sound_shm_pos = 0;
g_queued_samps = 0;
g_queued_nonsamps = 0;
doc_sound_ctl = 0;
doc_saved_val = 0;
g_doc_num_osc_en = 1;
g_dcycs_per_doc_update = 1.0;
g_dupd_per_dcyc = 1.0;
g_drecip_osc_en_plus_2 = 1.0 / (double)(1 + 2);
doc_reg_e0 = 0xff;
g_audio_rate = 0;
g_daudio_rate = 0.0;
g_drecip_audio_rate = 0.0;
g_dsamps_per_dcyc = 0.0;
g_dcycs_per_samp = 0.0;
g_fsamps_per_dcyc = 0.0;
g_doc_vol = 2;
g_last_sound_play_dsamp = 0.0;
sound_init_general();
}
@ -287,7 +312,7 @@ sound_init_general()
}
#else
/* windows and mac */
shmaddr = malloc(size);
shmaddr = (word32*)malloc(size);
memset(shmaddr, 0, size);
#endif
@ -346,13 +371,13 @@ sound_init_general()
parent_sound_get_sample_rate(g_pipe2_fd[0]);
#endif
#ifdef MAC
macsnd_init(shmaddr);
macsnd_init(shmaddr);
#endif
#ifdef __ANDROID__
android_snd_init(shmaddr);
#endif
#ifdef _WIN32
win32snd_init(shmaddr);
win32snd_init(shmaddr);
#endif
}
@ -363,7 +388,7 @@ parent_sound_get_sample_rate(int read_fd)
word32 tmp;
int ret;
ret = read(read_fd, &tmp, 4);
ret = read(read_fd, (char*)&tmp, 4);
if(ret != 4) {
printf("parent dying, could not get sample rate from child\n");
printf("ret: %d, fd: %d errno:%d\n", ret, read_fd, errno);
@ -394,7 +419,7 @@ sound_reset(double dcycs)
dsamps = dcycs * g_dsamps_per_dcyc;
for(i = 0; i < 32; i++) {
doc_write_ctl_reg(i, g_doc_regs[i].ctl | 1, dsamps);
doc_reg_e0 = 0xff;
doc_reg_e0 = 0xff; // OG : Don't understand????
if(g_doc_regs[i].has_irq_pending) {
halt_printf("reset: has_irq[%02x] = %d\n", i,
g_doc_regs[i].has_irq_pending);
@ -406,13 +431,19 @@ sound_reset(double dcycs)
}
g_num_osc_interrupting = 0;
// OG No reason to reset the number of active oscillo on reset : this should only be done on startup.
/*
g_doc_num_osc_en = 1;
UPDATE_G_DCYCS_PER_DOC_UPDATE(1);
*/
}
void
sound_shutdown()
{
// OG stop sound and free memory on sound_shutdown
sound_reset(g_cur_dcycs);
#ifdef _WIN32
win32snd_shutdown();
#else
@ -420,6 +451,14 @@ sound_shutdown()
close(g_pipe_fd[1]);
}
#endif
// OG Free up allocated memory
if (g_sound_shm_addr)
{
free(g_sound_shm_addr);
g_sound_shm_addr = NULL;
}
}
@ -814,7 +853,7 @@ sound_play(double dsamps)
if(c030_state) {
/* add in fractional time */
ftmp = (int)(fsampnum + (float)1.0);
ftmp = (float)(int)(fsampnum + 1.0f); //OG added cast
fpercent += (ftmp - fsampnum);
}
@ -1543,12 +1582,10 @@ doc_write_ctl_reg(int osc, int val, double dsamps)
if(old_halt != 0) {
/* start sound */
DOC_LOG("ctl_sound_play", osc, eff_dsamps, val);
#ifdef __ANDROID__
// OG If the sound_play is executed, it may restart a oscillo we thought was stopped at time,
// hence crashing the start_sound function
#else
sound_play(eff_dsamps);
#endif
// OG If the sound_play is executed, it may restart a oscillo we thought was stopped at time,
// hence crashing the start_sound function (cf. game Arrgh!)
//sound_play(eff_dsamps);
g_doc_regs[osc].ctl = val;
start_sound(osc, eff_dsamps, dsamps);
@ -1597,7 +1634,8 @@ doc_recalc_sound_parms(int osc, double eff_dcycs, double dsamps)
res = wave_size & 7;
shifted_size = size << SND_PTR_SHIFT;
cur_start = (rptr->waveptr << (8 + SND_PTR_SHIFT)) & (-shifted_size);
cur_start = (rptr->waveptr << (8 + SND_PTR_SHIFT)) & (-(int)shifted_size); // OG
dtmp1 = dfreq * (DOC_SCAN_RATE * g_drecip_audio_rate);
dacc = (double)(1 << (20 - (17 - sz + res)));
@ -1899,11 +1937,9 @@ doc_write_c03d(int val, double dcycs)
g_doc_num_osc_en = tmp;
UPDATE_G_DCYCS_PER_DOC_UPDATE(tmp);
#ifdef __ANDROID__
// OG Update any oscs that were running to take care of the new numbers of oscillo
for(i = 0; i<g_doc_num_osc_en; i++)
for(i = 0; i<g_doc_num_osc_en; i++)
doc_recalc_sound_parms(i,0.0,0.0);
#endif
/* Stop any oscs that were running but now */
/* are disabled */

View File

@ -25,8 +25,9 @@ const char rcsid_sound_driver_c[] = "@(#)$KmKId: sound_driver.c,v 1.17 2004-09-2
# include <sys/socket.h>
# include <netinet/in.h>
#endif
#ifndef UNDER_CE
#include <errno.h>
#endif
extern int Verbose;
@ -74,16 +75,16 @@ reliable_buf_write(word32 *shm_addr, int pos, int size)
while(size > 0) {
#ifdef _WIN32
ret = win32_send_audio(ptr, size);
ret = win32_send_audio(ptr, size);
#endif
#ifdef MAC
ret = mac_send_audio(ptr, size);
ret = mac_send_audio(ptr, size);
#endif
#ifdef __ANDROID__
ret = android_send_audio(ptr, size);
ret = android_send_audio(ptr, size);
#endif
#if !defined(_WIN32) && !defined(MAC) && !defined(__ANDROID__)
ret = write(g_audio_socket, ptr, size);
ret = write(g_audio_socket, ptr, size);
#endif
if(ret < 0) {
@ -146,8 +147,8 @@ child_sound_loop(int read_fd, int write_fd, word32 *shm_addr)
return;
#endif
#if defined(__ANDROID__)
child_sound_init_android();
return;
child_sound_init_android();
return;
#endif
tmp = g_audio_rate;
@ -163,7 +164,7 @@ child_sound_loop(int read_fd, int write_fd, word32 *shm_addr)
while(1) {
errno = 0;
ret = read(read_fd, &tmp, 4);
ret = read(read_fd, (char*)&tmp, 4);
if(ret <= 0) {
printf("child dying from ret: %d, errno: %d\n",
ret, errno);

0
jni/to_pro.c Executable file → Normal file
View File

View File

@ -1,20 +0,0 @@
TARGET = xkegs
OBJECTS = $(OBJECTS1) xdriver.o
CC = gcc
CCOPTS = -O
OPTS = -DNDEBUG
SUFFIX =
NAME = xkegs
LDFLAGS =
LDOPTS = -z
LD = $(CC)
EXTRA_LIBS = -lXext -lX11 -lcl -lc
EXTRA_SPECIALS = Alib.h
AS = cc -Ae
PERL = perl
XOPTS = -DHPUX -I/usr/include/X11R5
XLIBS = -L/usr/lib/X11R5 -L/opt/audio/lib

View File

@ -1,20 +0,0 @@
TARGET = xkegs
OBJECTS = engine_s.o $(OBJECTS1) sound_driver.o xdriver.o
CC = cc -Ae +DA1.1
CCOPTS = -O
OPTS = -DNDEBUG
SUFFIX =
NAME = xkegs
LDFLAGS =
LDOPTS = -z
LD = $(CC)
EXTRA_LIBS = -lXext -lX11 -lcl -lc
EXTRA_SPECIALS = 8inst_s 16inst_s 8size 16size size_s Alib.h
AS = cc -Ae
PERL = perl
XOPTS = -DHPUX -I/usr/include/X11R5
XLIBS = -L/usr/lib/X11R5 -L/opt/audio/lib

View File

@ -1,20 +0,0 @@
TARGET = xkegs
OBJECTS = $(OBJECTS1) xdriver.o
CC = cc
CCOPTS = -O
OPTS = -DNDEBUG
SUFFIX =
NAME = xkegs
LDFLAGS =
LDOPTS =
LD = $(CC)
EXTRA_LIBS = -lXext -lX11 -lc
EXTRA_SPECIALS =
AS = cc
PERL = perl
XOPTS = -I/usr/X11R6/include
XLIBS = -L/usr/X11R6/lib

View File

@ -1,10 +0,0 @@
TARGET = kegsmac
OBJECTS = $(OBJECTS1) macsnd_driver.o macdriver.o
CCOPTS = -O2 -DMAC
SUFFIX =
NAME = kegsmac
XOPTS = -Wall -fpascal-strings -mdynamic-no-pic -arch ppc
XLIBS =

View File

@ -1,20 +0,0 @@
TARGET = xkegs
OBJECTS = $(OBJECTS1) xdriver.o
CC = cc
CCOPTS = -O
OPTS = -DNDEBUG -DSOLARIS
SUFFIX =
NAME = xkegs
LDFLAGS =
LDOPTS =
LD = $(CC)
EXTRA_LIBS = -lXext -lX11 -lsocket -lnsl
EXTRA_SPECIALS =
AS = cc
PERL = perl
XOPTS = -I/usr/X/include
XLIBS = -L/usr/X/lib

View File

@ -1,10 +0,0 @@
TARGET = kegswin.exe
OBJECTS = $(OBJECTS1) win32snd_driver.o windriver.o
CCOPTS = -O2 -DKEGS_LITTLE_ENDIAN
SUFFIX = ".exe"
NAME = kegswin
XOPTS = -Wall -fomit-frame-pointer -march=pentium
XLIBS =

View File

@ -1,19 +0,0 @@
TARGET = xkegs
OBJECTS = $(OBJECTS1) xdriver.o
CC = cc
CCOPTS = -O2 -Wall -fomit-frame-pointer -march=pentium
OPTS = -DKEGS_LITTLE_ENDIAN
SUFFIX =
NAME = xkegs
LDFLAGS =
LDOPTS =
LD = $(CC)
EXTRA_LIBS = -lXext
EXTRA_SPECIALS =
AS = cc
PERL = perl
XOPTS = -I/usr/X11R6/include

View File

@ -1,20 +0,0 @@
TARGET = xkegs
OBJECTS = $(OBJECTS1) xdriver.o
CC = gcc
CCOPTS = -O
OPTS = -DNDEBUG -DSOLARIS -DKEGS_LITTLE_ENDIAN -DSOLARISSOUND
SUFFIX =
NAME = xkegs
LDFLAGS =
LDOPTS =
LD = $(CC)
EXTRA_LIBS = -lXext -lX11 -lsocket -lnsl
EXTRA_SPECIALS =
AS = cc
PERL = perl
XOPTS = -I/usr/X/include
XLIBS = -L/usr/X/lib

View File

@ -72,7 +72,7 @@ Kimage g_mainwin_kimage;
extern double g_last_vbl_dcycs;
double g_video_dcycs_check_input = 0.0;
int g_video_extra_check_inputs = 0;
int g_video_extra_check_inputs = 0; // OG Not recommended to use it (or apps might miss mouse changes)
int g_video_act_margin_left = BASE_MARGIN_LEFT;
int g_video_act_margin_right = BASE_MARGIN_RIGHT;
int g_video_act_margin_top = BASE_MARGIN_TOP;
@ -183,7 +183,7 @@ const byte g_dhires_colors_16[] = {
0x0f/* 0xf white */
};
const int g_lores_colors[] = {
int g_lores_colors[] = {
/* rgb */
0x000, /* 0x0 black */
0xd03, /* 0x1 deep red */
@ -302,7 +302,7 @@ const word32 g_hires_convert[64] = {
BIGEND(0x0f0f0f0f), /* 11,1111 = white ,white, white, white */
};
const int g_screen_index[] = {
int g_screen_index[] = {
0x000, 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380,
0x028, 0x0a8, 0x128, 0x1a8, 0x228, 0x2a8, 0x328, 0x3a8,
0x050, 0x0d0, 0x150, 0x1d0, 0x250, 0x2d0, 0x350, 0x3d0
@ -323,10 +323,74 @@ video_init()
int width, height;
int total_bytes;
int i, j;
// OG Reinit globals
g_a2_screen_buffer_changed = (word32)-1;
g_full_refresh_needed = (word32)-1;
g_cycs_in_40col = 0;
g_cycs_in_xredraw = 0;
g_refresh_bytes_xfer = 0;
g_video_dcycs_check_input = 0.0;
//g_video_extra_check_inputs = 0;
g_video_act_margin_left = BASE_MARGIN_LEFT;
g_video_act_margin_right = BASE_MARGIN_RIGHT;
g_video_act_margin_top = BASE_MARGIN_TOP;
g_video_act_margin_bottom = BASE_MARGIN_BOTTOM;
g_video_act_width = X_A2_WINDOW_WIDTH;
g_video_act_height = X_A2_WINDOW_HEIGHT;
g_need_redraw = 1;
g_palette_change_summary = 0;
g_border_sides_refresh_needed = 1;
g_border_special_refresh_needed = 1;
g_border_line24_refresh_needed = 1;
g_status_refresh_needed = 1;
g_vbl_border_color = 0;
g_border_last_vbl_changes = 0;
g_use_dhr140 = 0;
g_use_bw_hires = 0;
g_new_a2_stat_cur_line = 0;
g_vid_update_last_line = 0;
g_cur_a2_stat = ALL_STAT_TEXT | ALL_STAT_ANNUNC3 |(0xf << BIT_ALL_STAT_TEXT_COLOR);
g_a2vid_palette = 0xe;
g_installed_full_superhires_colormap = 0;
Max_color_size = 256;
g_saved_a2vid_palette = -1;
g_cycs_in_refresh_line = 0;
g_cycs_in_refresh_ximage = 0;
g_num_lines_superhires = 0;
g_num_lines_superhires640 = 0;
g_num_lines_prev_superhires = 0;
g_num_lines_prev_superhires640 = 0;
/*
g_red_mask = 0xff;
g_green_mask = 0xff;
g_blue_mask = 0xff;
g_red_left_shift = 16;
g_green_left_shift = 8;
g_blue_left_shift = 0;
g_red_right_shift = 0;
g_green_right_shift = 0;
g_blue_right_shift = 0;
*/
/* Initialize video system */
for(i = 0; i < 200; i++) {
g_a2_line_kimage[i] = (void *)0;
g_a2_line_kimage[i] = (Kimage *)0; // OG Changed from void* to kimage*
g_a2_line_stat[i] = -1;
g_a2_line_left_edge[i] = 0;
g_a2_line_right_edge[i] = 0;
@ -514,10 +578,24 @@ int g_screen_redraw_skip_amt = -1;
word32 g_cycs_in_check_input = 0;
void
video_update()
int g_needfullrefreshfornextframe = 1 ;
void video_update()
{
int did_video;
int did_video;
// OG g_needfullrefreshfornextframe
if (g_needfullrefreshfornextframe)
{
g_full_refresh_needed = -1;
g_a2_screen_buffer_changed = -1;
g_status_refresh_needed = 1;
g_border_sides_refresh_needed = 1;
g_border_special_refresh_needed = 1;
g_needfullrefreshfornextframe = 0;
}
update_border_info();
@ -549,6 +627,15 @@ video_update()
g_vid_update_last_line = 0;
video_update_through_line(0);
}
// OG Notify host that video has been uodated
#if defined(ACTIVEGSPLUGIN) && defined(MAC)
{
extern void x_need2refresh();
x_need2refresh();
}
#endif
}
@ -777,9 +864,11 @@ video_update_all_stat_through_line(int line)
STRUCT(Border_changes) {
float fcycs;
int val;
int val;
};
int g_border_color = 0; // OG Expose border color
Border_changes g_border_changes[MAX_BORDER_CHANGES];
int g_num_border_changes = 0;
@ -787,9 +876,11 @@ void
change_border_color(double dcycs, int val)
{
int pos;
g_border_color = val; // OG Expose border color
pos = g_num_border_changes;
g_border_changes[pos].fcycs = dcycs - g_last_vbl_dcycs;
g_border_changes[pos].fcycs = (float)(dcycs - g_last_vbl_dcycs);
g_border_changes[pos].val = val;
pos++;
@ -801,6 +892,8 @@ change_border_color(double dcycs, int val)
}
}
extern int first;
void
update_border_info()
{
@ -814,6 +907,7 @@ update_border_info()
int color_now;
int i;
/* to get this routine to redraw the border, change */
/* g_vbl_border_color, set g_border_last_vbl_changes = 1 */
/* and change the cur_border_colors[] array */
@ -2647,7 +2741,8 @@ video_update_event_line(int line)
}
if(g_video_extra_check_inputs) {
if(g_video_dcycs_check_input < g_cur_dcycs) {
if(g_video_dcycs_check_input < g_cur_dcycs)
{
video_check_input_events();
}
}
@ -2886,10 +2981,16 @@ refresh_border()
/**ZZZZ***/
}
// OG Added video_release_kimages proto
void video_release_kimages();
void
end_screen()
{
printf("In end_screen\n");
// OG Free up allocated images
video_release_kimages();
xdriver_end();
}
@ -3007,6 +3108,21 @@ video_get_kimages()
g_screen_mdepth);
}
// OG Added video_release_kimages (to match video_get_kimages)
void video_release_kimages()
{
extern void x_release_kimage(Kimage *kimage_ptr);
x_release_kimage(&g_kimage_text[0]);
x_release_kimage(&g_kimage_text[1]);
x_release_kimage(&g_kimage_hires[0]);
x_release_kimage(&g_kimage_hires[1]);
x_release_kimage(&g_kimage_superhires);
x_release_kimage(&g_kimage_border_special);
x_release_kimage(&g_kimage_border_sides);
}
void
video_convert_kimage_depth(Kimage *kim_in, Kimage *kim_out, int startx,
int starty, int width, int height)
@ -3068,6 +3184,14 @@ video_push_lines(Kimage *kimage_ptr, int start_line, int end_line, int left_pix,
{
int mdepth_mismatch;
int srcy;
int center = 0; // OG added variable to center screen
//OG add null pointer check when emulator is restarted
if (!kimage_ptr)
{
printf("warning : video_push_lines(kimage_ptr=null)\n");
return ;
}
if(left_pix >= right_pix || left_pix < 0 || right_pix <= 0) {
halt_printf("video_push_lines: lines %d to %d, pix %d to %d\n",
@ -3089,7 +3213,14 @@ video_push_lines(Kimage *kimage_ptr, int start_line, int end_line, int left_pix,
g_refresh_bytes_xfer += 2*(end_line - start_line) *
(right_pix - left_pix);
x_push_kimage(kimage_ptr, g_video_act_margin_left + left_pix,
// OG Calculating new center
if (g_cur_a2_stat & ALL_STAT_SUPER_HIRES)
center=0;
else
center=EFF_BORDER_WIDTH - BORDER_WIDTH;
// OG shifting image to the center
x_push_kimage(kimage_ptr, g_video_act_margin_left + left_pix + center,
g_video_act_margin_top + srcy, left_pix, srcy,
(right_pix - left_pix), 2*(end_line - start_line));
}
@ -3153,7 +3284,28 @@ video_push_border_sides()
#endif
/* redraw left sides */
video_push_border_sides_lines(0, 0, BORDER_WIDTH, 0, 200);
// OG Left side can alos be "jagged" as a2 screen is now being centered
//video_push_border_sides_lines(0, 0, BORDER_WIDTH, 0, 200);
prev_line = -1;
old_width = -1;
for(i = 0; i < 200; i++) {
mode = (g_a2_line_stat[i] >> 4) & 7;
width = EFF_BORDER_WIDTH;
if(mode == MODE_SUPER_HIRES) {
width = BORDER_WIDTH;
}
if(width != old_width) {
video_push_border_sides_lines(BORDER_WIDTH,
0, old_width,
prev_line, i);
prev_line = i;
old_width = width;
}
}
video_push_border_sides_lines(0/*BORDER_WIDTH*/,
0, old_width, prev_line, 200);
/* right side--can be "jagged" */
prev_line = -1;
@ -3173,7 +3325,7 @@ video_push_border_sides()
}
}
video_push_border_sides_lines(BORDER_WIDTH,
video_push_border_sides_lines(0/*BORDER_WIDTH*/,
X_A2_WINDOW_WIDTH - old_width, old_width, prev_line, 200);
}
@ -3217,6 +3369,9 @@ video_push_border_special()
}
}
// OG Added window ratio support
// extern int x_calc_ratio(float&,float&);
void
video_push_kimages()
{
@ -3245,60 +3400,83 @@ video_push_kimages()
GET_ITIMER(start_time);
start = -1;
last_kim = (Kimage *)-1;
cur_kim = (Kimage *)0;
float ratiox,ratioy;
left_pix = 640;
right_pix = 0;
for(line = 0; line < 200; line++) {
line_div8 = line >> 3;
mask = 1 << (line_div8);
cur_kim = g_a2_line_kimage[line];
if((g_full_refresh_needed & mask) != 0) {
left = 0;
right = 560;
if(cur_kim == &g_kimage_superhires) {
if (x_calc_ratio(ratiox,ratioy))
{
line = 0;
while (1)
{
start = line;
cur_kim = g_a2_line_kimage[line];
while(line < 200 && g_a2_line_kimage[line] == cur_kim) line++;
if (cur_kim == &g_kimage_superhires)
right = 640;
}
} else {
left = g_a2_line_left_edge[line];
right = g_a2_line_right_edge[line];
}
if(!(g_a2_screen_buffer_changed & mask) || (left > right)) {
/* No need to update this line */
/* Refresh previous chunks of lines, if any */
if(start >= 0) {
video_push_lines(last_kim, start, line,
left_pix, right_pix);
start = -1;
left_pix = 640;
right_pix = 0;
}
} else {
/* Need to update this line */
if(start < 0) {
start = line;
last_kim = cur_kim;
}
if(cur_kim != last_kim) {
/* do the refresh */
video_push_lines(last_kim, start, line,
left_pix, right_pix);
last_kim = cur_kim;
start = line;
left_pix = left;
right_pix = right;
}
left_pix = MIN(left, left_pix);
right_pix = MAX(right, right_pix);
else
right = 560;
video_push_lines(cur_kim, start, line,0,right);
if (line==200) break;
}
}
else
{
start = -1;
last_kim = (Kimage *)-1;
cur_kim = (Kimage *)0;
if(start >= 0) {
video_push_lines(last_kim, start, 200, left_pix, right_pix);
left_pix = 640;
right_pix = 0;
for(line = 0; line < 200; line++) {
line_div8 = line >> 3;
mask = 1 << (line_div8);
cur_kim = g_a2_line_kimage[line];
if((g_full_refresh_needed & mask) != 0) {
left = 0;
right = 560;
if(cur_kim == &g_kimage_superhires) {
right = 640;
}
} else {
left = g_a2_line_left_edge[line];
right = g_a2_line_right_edge[line];
}
if(!(g_a2_screen_buffer_changed & mask) || (left > right)) {
/* No need to update this line */
/* Refresh previous chunks of lines, if any */
if(start >= 0) {
video_push_lines(last_kim, start, line,
left_pix, right_pix);
start = -1;
left_pix = 640;
right_pix = 0;
}
} else {
/* Need to update this line */
if(start < 0) {
start = line;
last_kim = cur_kim;
}
if(cur_kim != last_kim) {
/* do the refresh */
video_push_lines(last_kim, start, line,
left_pix, right_pix);
last_kim = cur_kim;
start = line;
left_pix = left;
right_pix = right;
}
left_pix = MIN(left, left_pix);
right_pix = MAX(right, right_pix);
}
}
if(start >= 0) {
video_push_lines(last_kim, start, 200, left_pix, right_pix);
}
}
g_a2_screen_buffer_changed = 0;
@ -3330,9 +3508,13 @@ video_update_color_raw(int col_num, int a2_color)
newgreen = green >> g_green_right_shift;
newblue = blue >> g_blue_right_shift;
tmp = ((newred & g_red_mask) << g_red_left_shift) +
((newgreen & g_green_mask) << g_green_left_shift) +
((newblue & g_blue_mask) << g_blue_left_shift);
g_palette_8to1624[col_num] = tmp;
x_update_color(col_num, red, green, blue, tmp);

View File

@ -1,109 +0,0 @@
#include <windows.h>
#include "winresource.h"
// $Id: $
#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif
IDD_DLG_DISKCONF DIALOGEX 0, 0, 268, 182
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Disk Configuration"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,150,161,50,14
PUSHBUTTON "Cancel",IDCANCEL,203,161,50,14
LTEXT "S5D1",IDC_STATIC,19,46,19,8
EDITTEXT IDC_EDIT_S5D1,43,42,156,14,ES_AUTOHSCROLL,
WS_EX_ACCEPTFILES
PUSHBUTTON "Browse",IDC_BTN_S5D1,203,42,50,14
LTEXT "S5D2",IDC_STATIC,19,62,19,8
EDITTEXT IDC_EDIT_S5D2,43,60,155,14,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_BTN_S5D2,203,60,50,14
LTEXT "S6D1",IDC_STATIC,19,80,19,8
EDITTEXT IDC_EDIT_S6D1,43,77,156,14,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_BTN_S6D1,203,77,50,14
LTEXT "S6D2",IDC_STATIC,19,98,19,8
EDITTEXT IDC_EDIT_S6D2,43,95,156,14,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_BTN_S6D2,203,96,50,14
LTEXT "S7D1",IDC_STATIC,19,118,19,8
EDITTEXT IDC_EDIT_S7D1,43,115,155,14,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_BTN_S7D1,203,115,50,14
LTEXT "S7D2",IDC_STATIC,19,137,19,8
EDITTEXT IDC_EDIT_S7D2,43,135,155,14,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_BTN_S7D2,203,135,50,14
GROUPBOX "Disk settings",IDC_STATIC,7,7,254,148
LTEXT "Configure your disk images for each drive. Disk image formats supported\nare *.2MG,*.PO and *.DSK. ",
IDC_STATIC,19,20,234,16
END
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDC_KEGS32 MENU DISCARDABLE
BEGIN
POPUP "&Emulator"
BEGIN
MENUITEM "&Set Disk Configuration\tALT-F1", ID_FILE_DISK
MENUITEM "Send CTRL Open-Apple Reset\tCTRL-ALT-BREAK",
ID_FILE_SENDRESET
MENUITEM "Toggle &Joystick", ID_FILE_JOYSTICK
MENUITEM "Toggle Debug Statistics", ID_FILE_DEBUGSTAT
MENUITEM SEPARATOR
MENUITEM "E&xit\tALT-F4", ID_FILE_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About", ID_HELP_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDR_TOOLBAR BITMAP DISCARDABLE "wintoolbar.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDR_ACCEL ACCELERATORS DISCARDABLE
BEGIN
VK_F1, ID_FILE_DISK, VIRTKEY, ALT, NOINVERT
VK_F4, ID_FILE_EXIT, VIRTKEY, ALT, NOINVERT
END
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDC_KEGS32 ICON DISCARDABLE "win32.ico"
KEGS32_ICON ICON DISCARDABLE "win32.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUT_DIALOG DIALOG DISCARDABLE 0, 0, 207, 82
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,78,61,50,14
LTEXT "KEGS32: GS Emulator.\nBased on KEGS by Kent Dickey\nWindows Port by Chea Chee Keong\n\nThis software is free for non-commercial use.",
IDC_STATIC,38,7,162,45,NOT WS_GROUP
ICON "KEGS32_ICON",IDC_STATIC,7,7,21,20,0
END

View File

@ -17,7 +17,8 @@ const char rcsid_win32snd_driver_c[] = "@(#)$KmKId: win32snd_driver.c,v 1.5 2002
# include <windows.h>
# include <mmsystem.h>
#endif
#include <unistd.h>
// OG
//#include <unistd.h>
extern int Verbose;
@ -29,7 +30,7 @@ void check_wave_error(int res, char *str);
#define NUM_WAVE_HEADERS 8
#ifndef __CYGWIN__
HWAVEOUT g_wave_handle;
HWAVEOUT g_wave_handle = NULL; // OG Default value must be set
WAVEHDR g_wavehdr[NUM_WAVE_HEADERS];
#endif
@ -48,10 +49,32 @@ win32snd_init(word32 *shmaddr)
return;
}
// OG Added global to free the dedicated win32 sound memory
byte *bptr = NULL;
// OG shut win32 sound resources
void
win32snd_shutdown()
{
/* hmm */
if (g_wave_handle)
{
MMRESULT res = waveOutReset(g_wave_handle);
if (res!=MMSYSERR_NOERROR )
printf("waveOutReset Failed");
res = waveOutClose(g_wave_handle);
if (res!=MMSYSERR_NOERROR )
printf("waveOutClose Failed");
g_wave_handle=NULL;
}
// OG Free dedicated sound memory
if (bptr)
{
free(bptr);
bptr = NULL;
}
}
@ -76,7 +99,7 @@ handle_wav_snd(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1,
void
check_wave_error(int res, char *str)
{
char buf[256];
TCHAR buf[256];
if(res == MMSYSERR_NOERROR) {
return;
@ -92,7 +115,9 @@ child_sound_init_win32()
{
WAVEFORMATEX wavefmt;
WAVEOUTCAPS caps;
byte *bptr;
// OG Moved as global variable (to rename)
// byte *bptr;
int bits_per_sample, channels, block_align;
int blen;
int res;
@ -101,15 +126,23 @@ child_sound_init_win32()
memset(&wavefmt, 0, sizeof(WAVEFORMATEX));
wavefmt.wFormatTag = WAVE_FORMAT_PCM;
#ifndef UNDER_CE
bits_per_sample = 16;
wavefmt.nSamplesPerSec = g_audio_rate;
#else
bits_per_sample = 16;
wavefmt.nSamplesPerSec = 12000;
#endif
channels = 2;
wavefmt.wBitsPerSample = bits_per_sample;
wavefmt.nChannels = channels;
wavefmt.nSamplesPerSec = g_audio_rate;
block_align = channels * (bits_per_sample / 8);
wavefmt.nBlockAlign = block_align;
wavefmt.nAvgBytesPerSec = block_align * g_audio_rate;
res = waveOutOpen(&g_wave_handle, WAVE_MAPPER, &wavefmt, 0, 0,
WAVE_FORMAT_QUERY);
@ -132,7 +165,7 @@ child_sound_init_win32()
blen = (SOUND_SHM_SAMP_SIZE * 4 * 2) / NUM_WAVE_HEADERS;
g_win32snd_buflen = blen;
bptr = malloc(blen * NUM_WAVE_HEADERS);
bptr = (byte*)malloc(blen * NUM_WAVE_HEADERS); // OG Added cast
if(bptr == NULL) {
printf("Unabled to allocate sound buffer\n");
exit(1);
@ -141,7 +174,7 @@ child_sound_init_win32()
for(i = 0; i < NUM_WAVE_HEADERS; i++) {
memset(&g_wavehdr[i], 0, sizeof(WAVEHDR));
g_wavehdr[i].dwUser = FALSE;
g_wavehdr[i].lpData = &(bptr[i*blen]);
g_wavehdr[i].lpData = (LPSTR)&(bptr[i*blen]); // OG Added cast
g_wavehdr[i].dwBufferLength = blen;
g_wavehdr[i].dwFlags = 0;
g_wavehdr[i].dwLoops = 0;

162
jni/win_console.c Normal file
View File

@ -0,0 +1,162 @@
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <winsock.h>
//#include <commctrl.h>
#include "defc.h"
#include "protos_windriver.h"
extern void kegsinit(HWND _hwnd);
extern void kegsshut();
extern HWND g_hwnd_main;
extern char *g_status_ptrs[MAX_STATUS_LINES];
int
win_nonblock_read_stdin(int fd, char *bufptr, int len)
{
HANDLE oshandle;
DWORD dwret;
int ret;
errno = EAGAIN;
oshandle = (HANDLE)_get_osfhandle(fd); // get stdin handle
dwret = WaitForSingleObject(oshandle, 1); // wait 1msec for data
ret = -1;
if(dwret == WAIT_OBJECT_0) {
ret = read(fd, bufptr, len);
}
return ret;
}
void
x_dialog_create_kegs_conf(const char *str)
{
}
int
x_show_alert(int is_fatal, const char *str)
{
return 0;
}
int WINAPI WinMain (
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
return main(0,0);
}
int
main(int argc, char **argv)
{
// InitCommonControls();
WNDCLASS wndclass;
RECT rect;
int height;
wndclass.style = 0;
wndclass.lpfnWndProc = (WNDPROC)win_event_handler;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = GetModuleHandle(NULL);
wndclass.hIcon = LoadIcon((HINSTANCE)NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // OG Added cast
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = "kegswin";
// Register the window
if(!RegisterClass(&wndclass)) {
printf("Registering window failed\n");
exit(1);
}
height = X_A2_WINDOW_HEIGHT + (MAX_STATUS_LINES * 16) + 32;
// g_main_height = height;
HWND hwnd = CreateWindow("kegswin", "KEGSWIN - Apple //gs Emulator",
WS_TILED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT,
X_A2_WINDOW_WIDTH, height,
NULL, NULL, GetModuleHandle(NULL), NULL);
printf("g_hwnd_main = %p, height = %d\n", hwnd, height);
GetWindowRect(hwnd, &rect);
printf("...rect is: %ld, %ld, %ld, %ld\n", rect.left, rect.top,
rect.right, rect.bottom);
kegsinit(hwnd);
int ret = kegsmain(argc, argv);
UnregisterClass(wndclass.lpszClassName,GetModuleHandle(NULL));
kegsshut();
return ret;
}
void
x_check_input_events()
{
MSG msg;
while(PeekMessage(&msg, g_hwnd_main, 0, 0, PM_NOREMOVE)) {
if(GetMessage(&msg, g_hwnd_main, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
printf("GetMessage returned <= 0\n");
my_exit(2);
}
}
}
void
x_redraw_status_lines()
{
COLORREF oldtextcolor, oldbkcolor;
char *buf;
int line;
int len;
int height;
int margin;
height = 16;
margin = 0;
HDC localdc = GetDC(g_hwnd_main); // OG Use on the fly DC
oldtextcolor = SetTextColor(localdc, 0);
oldbkcolor = SetBkColor(localdc, 0xffffff);
for(line = 0; line < MAX_STATUS_LINES; line++) {
buf = g_status_ptrs[line];
if(buf != 0) {
len = strlen(buf);
TextOut(localdc, 10, X_A2_WINDOW_HEIGHT +
height*line + margin, buf, len);
}
}
SetTextColor(localdc, oldtextcolor);
SetBkColor(localdc, oldbkcolor);
ReleaseDC(g_hwnd_main,localdc);
}
int x_calc_ratio(float& ratiox,float& ratioy)
{
return 0; // not stretched
}

View File

@ -20,19 +20,23 @@ const char rcsid_windriver_c[] = "@(#)$KmKId: windriver.c,v 1.11 2004-11-24 16:4
#include <windowsx.h>
#include <mmsystem.h>
#include <winsock.h>
#include <commctrl.h>
//#include <commctrl.h>
#include "defc.h"
#include "protos_windriver.h"
extern int Verbose;
extern int g_pause; // OG Added Pause
extern int g_warp_pointer;
extern int g_screen_depth;
extern int g_force_depth;
int g_screen_mdepth = 0;
extern int g_quit_sim_now;
// OG replaced g_quit_sim_now by quitEmulator
// extern int g_quit_sim_now;
extern void quitEmulator();
int g_use_shmem = 1;
int g_has_focus = 0;
@ -40,9 +44,9 @@ int g_auto_repeat_on = -1;
extern Kimage g_mainwin_kimage;
HDC g_main_dc;
//HDC g_main_dc; // OG dc cannot be a global
HDC g_main_cdc;
int g_main_height = 0;
//int g_main_height = 0;
int g_win_capslock_down = 0;
@ -55,7 +59,7 @@ extern int g_border_sides_refresh_needed;
extern int g_border_special_refresh_needed;
extern int g_status_refresh_needed;
extern int g_lores_colors[];
extern int g_lores_colors[];
extern int g_cur_a2_stat;
extern int g_a2vid_palette;
@ -72,10 +76,11 @@ volatile BITMAPINFOHEADER *g_bmaphdr_ptr = 0;
int g_num_a2_keycodes = 0;
extern char *g_status_ptrs[MAX_STATUS_LINES];
int g_win_button_states = 0;
// OG Added calc_ratio
int x_calc_ratio(float& ratiox,float& ratioy);
/* this table is used to search for the Windows VK_* in col 1 or 2 */
/* flags bit 8 is or'ed into the VK, so we can distinguish keypad keys */
@ -83,7 +88,7 @@ int g_win_button_states = 0;
int g_a2_key_to_wsym[][3] = {
{ 0x35, VK_ESCAPE, 0 },
{ 0x7a, VK_F1, 0 },
{ 0x7b, VK_F2, 0 },
{ 0x78, VK_F2, 0 }, // OG Was 7B but F2 is defined has 0x78 in a2_key_to_ascii
{ 0x63, VK_F3, 0 },
{ 0x76, VK_F4, 0 },
{ 0x60, VK_F5, 0 },
@ -179,7 +184,19 @@ int g_a2_key_to_wsym[][3] = {
{ 0x36, VK_CONTROL, VK_CONTROL+0x100 },
{ 0x3a, VK_SNAPSHOT+0x100, VK_MENU+0x100 },/* Opt=prntscrn or alt-r */
// OG ActiveGS map OA-CA to Win & AltKey
#ifndef ACTIVEGS
{ 0x37, VK_SCROLL, VK_MENU }, /* Command=scr_lock or alt-l */
#else
{ 0x7f, VK_CANCEL, 0 },
{ 0x3A, VK_LWIN+0x100, VK_LWIN },
{ 0x37, VK_MENU, 0 }, /* Command=alt-l */
{ 0x37, VK_LMENU, 0 }, /* Command=alt-l */
{ 0x7F, VK_SCROLL,0 }, /* RESET */
{ 0x36, VK_LCONTROL, 0 }, // CTRL
#endif
{ 0x31, ' ', 0 },
{ 0x3b, VK_LEFT+0x100, 0 },
{ 0x3d, VK_DOWN+0x100, 0 },
@ -190,39 +207,21 @@ int g_a2_key_to_wsym[][3] = {
{ -1, -1, -1 }
};
int
win_nonblock_read_stdin(int fd, char *bufptr, int len)
{
HANDLE oshandle;
DWORD dwret;
int ret;
errno = EAGAIN;
oshandle = (HANDLE)_get_osfhandle(fd); // get stdin handle
dwret = WaitForSingleObject(oshandle, 1); // wait 1msec for data
ret = -1;
if(dwret == WAIT_OBJECT_0) {
ret = read(fd, bufptr, len);
}
return ret;
}
void
x_dialog_create_kegs_conf(const char *str)
{
}
int
x_show_alert(int is_fatal, const char *str)
{
return 0;
}
extern int g_config_control_panel;
int
win_update_mouse(int x, int y, int button_states, int buttons_valid)
{
int buttons_changed;
#ifdef ACTIVEGS
if (g_config_control_panel) // OG ignore input events while in debugger
return 0;
buttons_valid &= 1; // filter out middle & right button
#endif
buttons_changed = ((g_win_button_states & buttons_valid) !=
button_states);
g_win_button_states = (g_win_button_states & ~buttons_valid) |
@ -236,8 +235,90 @@ win_update_mouse(int x, int y, int button_states, int buttons_valid)
return update_mouse(x, y, button_states, buttons_valid & 7);
}
// OG Added asynchronous key & mouse handler
#define ASYNCEVENT
#ifndef ASYNCEVENT
#define WIN_EVENT_MOUSE win_event_mouse
#define WIN_EVENT_KEY win_event_key
#else
extern void add_event_mouse(int umsg,WPARAM wParam, LPARAM lParam);
extern void add_event_key(HWND hwnd, UINT raw_vk, BOOL down, int repeat, UINT flags);
#define WIN_EVENT_MOUSE add_event_mouse
#define WIN_EVENT_KEY add_event_key
#endif
struct win32_mouse
{
int umsg;
int wparam;
int lparam;
};
struct win32_key
{
UINT raw_vk;
BOOL down;
int repeat;
UINT flags;
};
int last_win32_mouse=0;
int next_win32_mouse=0;
int nb_win32_key=0;
#define MAX_EVENT 1024
struct win32_mouse win32_mouses[MAX_EVENT];
struct win32_key win32_keys[MAX_EVENT];
extern int g_config_control_panel; // OG Expose g_config_control_panel
// OG Push Mouse Event
void add_event_mouse(int umsg,WPARAM wParam, LPARAM lParam)
{
#ifdef ACTIVEGS
if (g_config_control_panel) // OG ignore input events while in debugger
return ;
#endif
win32_mouses[next_win32_mouse].umsg = umsg;
win32_mouses[next_win32_mouse].wparam = wParam;
win32_mouses[next_win32_mouse].lparam = lParam;
next_win32_mouse = (next_win32_mouse+1)%MAX_EVENT;
// ASSERT (next_win32_mouse==last_win32_mouse)
}
// OG Push Key Event
void
win_event_mouse(WPARAM wParam, LPARAM lParam)
add_event_key(HWND hwnd, UINT raw_vk, BOOL down, int repeat, UINT flags)
{
#ifdef ACTIVEGS
if (g_config_control_panel) // OG ignore input events while in debugger
return ;
#endif
if (nb_win32_key>=MAX_EVENT)
return ;
win32_keys[nb_win32_key].raw_vk = raw_vk;
win32_keys[nb_win32_key].down = down;
win32_keys[nb_win32_key].repeat = repeat;
win32_keys[nb_win32_key].flags = flags;
nb_win32_key++;
}
void
win_event_mouse(int umsg,WPARAM wParam, LPARAM lParam)
{
POINT pt;
word32 flags;
@ -245,15 +326,28 @@ win_event_mouse(WPARAM wParam, LPARAM lParam)
int x, y;
int motion;
x = LOWORD(lParam);
y = HIWORD(lParam);
// OG Reformat the mouse coordinates
float ratiox,ratioy;
if (!g_warp_pointer && x_calc_ratio(ratiox,ratioy))
{
x = (int)((float)(x)/ratiox);
y = (int)((float)(y)/ratioy);
}
flags = wParam;
x = LOWORD(lParam) - BASE_MARGIN_LEFT;
y = HIWORD(lParam) - BASE_MARGIN_TOP;
x -= BASE_MARGIN_LEFT;
y -= BASE_MARGIN_TOP;
buttons = (flags & 1) +
(((flags >> 1) & 1) << 2) +
(((flags >> 4) & 1) << 1);
#if 0
printf("Mouse at %d, %d fl: %08x, but: %d\n", x, y, flags, buttons);
if (umsg!=WM_MOUSEMOVE)
printf("Mouse at %d, %d fl: %08x, but: %d\n", x, y, flags, buttons);
#endif
motion = win_update_mouse(x, y, buttons, 7);
@ -323,23 +417,31 @@ win_event_key(HWND hwnd, UINT raw_vk, BOOL down, int repeat, UINT flags)
void
win_event_quit(HWND hwnd)
{
g_quit_sim_now = 1;
my_exit(0);
quitEmulator();
}
extern int g_needfullrefreshfornextframe ;
void
win_event_redraw()
{
g_full_refresh_needed = -1;
g_a2_screen_buffer_changed = -1;
g_status_refresh_needed = 1;
g_border_sides_refresh_needed = 1;
g_border_special_refresh_needed = 1;
// outputInfo("win_event_redraw()\n");
g_needfullrefreshfornextframe = 1;
}
LRESULT CALLBACK
win_event_handler(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
{
#if 0
extern int g_nb_vbl ;
if (umsg==WM_LBUTTONDOWN)
outputInfo("WM_LBUTTONDOWN (%d)\n",g_nb_vbl);
if (umsg==WM_LBUTTONUP)
outputInfo("WM_LBUTTONUP (%d)\n",g_nb_vbl);
if (umsg==WM_LBUTTONDBLCLK)
outputInfo("WM_LBUTTONDBLCLK (%d)\n",g_nb_vbl);
#endif
switch(umsg) {
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
@ -348,17 +450,18 @@ win_event_handler(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
case WM_MBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
win_event_mouse(wParam, lParam);
case WM_LBUTTONDBLCLK: // OG Added dblclk as WM_LBUTTONDOWN
WIN_EVENT_MOUSE(umsg,wParam, lParam);
return 0;
case WM_PAINT:
win_event_redraw();
break;
}
switch(umsg) {
HANDLE_MSG(hwnd, WM_KEYUP, win_event_key);
HANDLE_MSG(hwnd, WM_KEYDOWN, win_event_key);
HANDLE_MSG(hwnd, WM_SYSKEYUP, win_event_key);
HANDLE_MSG(hwnd, WM_SYSKEYDOWN, win_event_key);
HANDLE_MSG(hwnd, WM_KEYUP, WIN_EVENT_KEY);
HANDLE_MSG(hwnd, WM_KEYDOWN, WIN_EVENT_KEY);
HANDLE_MSG(hwnd, WM_SYSKEYUP, WIN_EVENT_KEY);
HANDLE_MSG(hwnd, WM_SYSKEYDOWN, WIN_EVENT_KEY);
HANDLE_MSG(hwnd, WM_DESTROY, win_event_quit);
}
@ -386,79 +489,56 @@ win_event_handler(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
return DefWindowProc(hwnd, umsg, wParam, lParam);
}
// OG Added Generic kegsinit/kegsshut functions
int
main(int argc, char **argv)
void kegsinit(HWND _hwnd)
{
WNDCLASS wndclass;
RECT rect;
int height;
g_hwnd_main = _hwnd;
HDC localdc = GetDC(g_hwnd_main);
SetTextColor(localdc, 0);
SetBkColor(localdc, 0xFFFFFF);
InitCommonControls();
g_main_cdc = CreateCompatibleDC(localdc);
ReleaseDC(g_hwnd_main,localdc);
wndclass.style = 0;
wndclass.lpfnWndProc = (WNDPROC)win_event_handler;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = GetModuleHandle(NULL);
wndclass.hIcon = LoadIcon((HINSTANCE)NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);
wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = "kegswin";
// Register the window
if(!RegisterClass(&wndclass)) {
printf("Registering window failed\n");
exit(1);
}
height = X_A2_WINDOW_HEIGHT + (MAX_STATUS_LINES * 16) + 32;
g_main_height = height;
g_hwnd_main = CreateWindow("kegswin", "KEGSWIN - Apple //gs Emulator",
WS_TILED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT,
X_A2_WINDOW_WIDTH, height,
NULL, NULL, GetModuleHandle(NULL), NULL);
printf("g_hwnd_main = %p, height = %d\n", g_hwnd_main, height);
GetWindowRect(g_hwnd_main, &rect);
printf("...rect is: %ld, %ld, %ld, %ld\n", rect.left, rect.top,
rect.right, rect.bottom);
g_main_dc = GetDC(g_hwnd_main);
SetTextColor(g_main_dc, 0);
SetBkColor(g_main_dc, 0xffffff);
g_main_cdc = CreateCompatibleDC(g_main_dc);
g_screen_depth = 24;
g_screen_mdepth = 32;
// Call kegsmain
return kegsmain(argc, argv);
}
void kegsshut()
{
if (g_main_cdc)
{
DeleteDC(g_main_cdc);
g_main_cdc = NULL;
}
g_hwnd_main = NULL;
}
extern void x_check_input_events();
void
check_input_events()
{
MSG msg;
while(PeekMessage(&msg, g_hwnd_main, 0, 0, PM_NOREMOVE)) {
if(GetMessage(&msg, g_hwnd_main, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
printf("GetMessage returned <= 0\n");
my_exit(2);
}
x_check_input_events();
// OG Unstack Mouse Events
int i=last_win32_mouse;
while(i!=next_win32_mouse)
{
win_event_mouse(win32_mouses[i].umsg,win32_mouses[i].wparam,win32_mouses[i].lparam);
int lb = win32_mouses[i].wparam&1;
i = (i+1)%MAX_EVENT;
if (lb != (win32_mouses[i].wparam&1))
break; // don't send up & down event at the same time
}
return;
last_win32_mouse=i;
for(i=0;i<nb_win32_key;i++)
win_event_key(NULL,win32_keys[i].raw_vk ,win32_keys[i].down,win32_keys[i].repeat , win32_keys[i].flags );
nb_win32_key=0;
}
@ -483,10 +563,34 @@ show_xcolor_array()
}
void
xdriver_end()
// OG Add function to clear all get_images loaded (dev dependent)
void x_release_kimage(Kimage *kimage_ptr)
{
printf("xdriver_end\n");
if ((int)kimage_ptr->dev_handle != -1)
{
DeleteObject(kimage_ptr->dev_handle);
kimage_ptr->dev_handle = (void*)-1;
}
else
if (kimage_ptr->data_ptr)
{
free(kimage_ptr->data_ptr);
kimage_ptr->data_ptr = NULL;
}
}
// OG Free video global memory
void
xdriver_end() // Should be renamed to dev_video_shut() ???
{
x_release_kimage(&g_mainwin_kimage);
GlobalFree(g_bmapinfo_ptr); // allocated in dev_video_init
g_bmapinfo_ptr = 0;
printf("win32 video driver end\n");
}
@ -509,9 +613,12 @@ x_get_kimage(Kimage *kimage_ptr)
/* Use g_bmapinfo_ptr, adjusting width, height */
g_bmaphdr_ptr->biWidth = width;
g_bmaphdr_ptr->biHeight = -height;
kimage_ptr->dev_handle = CreateDIBSection(g_main_dc,
HDC localdc = GetDC(g_hwnd_main); // OG Use on the fly DC
kimage_ptr->dev_handle = CreateDIBSection(localdc,
g_bmapinfo_ptr, DIB_RGB_COLORS,
(VOID **)&(kimage_ptr->data_ptr), NULL, 0);
ReleaseDC(g_hwnd_main,localdc);
} else {
/* allocate buffers for video.c to draw into */
@ -540,21 +647,55 @@ dev_video_init()
{
int extra_size;
int lores_col;
int a2code;
int i;
printf("Preparing graphics system\n");
// OG fix g_num_a2_keycodes identification
g_num_a2_keycodes = sizeof(g_a2_key_to_wsym)/3/sizeof(int);
g_num_a2_keycodes--; // last entry=-1
/*
g_num_a2_keycodes = 0;
for(i = 0; i < 0x7f; i++) {
a2code = g_a2_key_to_wsym[i][0];
for(i = 0; i < maxcode; i++) {
int a2code = g_a2_key_to_wsym[i][0];
if(a2code < 0) {
g_num_a2_keycodes = i;
}
}
*/
// OG Forcing 16bits depth for WiNCE
#ifndef UNDER_CE
g_screen_depth = 24;
g_screen_mdepth = 32;
#else
g_screen_depth = 16;
g_screen_mdepth = 16;
extern word32 g_red_mask ;
extern word32 g_green_mask ;
extern word32 g_blue_mask ;
extern int g_red_left_shift;
extern int g_green_left_shift;
extern int g_blue_left_shift ;
extern int g_red_right_shift ;
extern int g_green_right_shift ;
extern int g_blue_right_shift ;
g_red_mask = 0xff;
g_green_mask = 0xff;
g_blue_mask = 0xff;
g_red_left_shift = 10;
g_green_left_shift = 5;
g_blue_left_shift = 0;
g_red_right_shift = 3;
g_green_right_shift = 3;
g_blue_right_shift = 3;
#endif
extra_size = sizeof(RGBQUAD);
if(g_screen_depth == 8) {
@ -588,7 +729,11 @@ dev_video_init()
g_installed_full_superhires_colormap = 1;
#ifndef UNDER_CE
ShowWindow(g_hwnd_main, SW_SHOWDEFAULT);
#else
ShowWindow(g_hwnd_main, SW_SHOW);
#endif
UpdateWindow(g_hwnd_main);
printf("Done with dev_video_init\n");
@ -596,32 +741,7 @@ dev_video_init()
}
void
x_redraw_status_lines()
{
COLORREF oldtextcolor, oldbkcolor;
char *buf;
int line;
int len;
int height;
int margin;
height = 16;
margin = 0;
oldtextcolor = SetTextColor(g_main_dc, 0);
oldbkcolor = SetBkColor(g_main_dc, 0xffffff);
for(line = 0; line < MAX_STATUS_LINES; line++) {
buf = g_status_ptrs[line];
if(buf != 0) {
len = strlen(buf);
TextOut(g_main_dc, 10, X_A2_WINDOW_HEIGHT +
height*line + margin, buf, len);
}
}
SetTextColor(g_main_dc, oldtextcolor);
SetBkColor(g_main_dc, oldbkcolor);
}
void
@ -634,14 +754,32 @@ x_push_kimage(Kimage *kimage_ptr, int destx, int desty, int srcx, int srcy,
point.x = 0;
point.y = 0;
ClientToScreen(g_hwnd_main, &point);
bitm_old = SelectObject(g_main_cdc, kimage_ptr->dev_handle);
BitBlt(g_main_dc, destx, desty, width, height,
g_main_cdc, srcx, srcy, SRCCOPY);
HDC localdc = GetDC(g_hwnd_main);
HDC localcdc = g_main_cdc; //CreateCompatibleDC(g_main_dc);
SelectObject(g_main_cdc, bitm_old);
bitm_old = SelectObject(localcdc, kimage_ptr->dev_handle);
HRGN hrgn=NULL;
float ratiox,ratioy;
int isStretched = x_calc_ratio(ratiox,ratioy);
if (!isStretched)
BitBlt(localdc, destx, desty, width, height, localcdc, srcx, srcy, SRCCOPY);
else
{
float xdest = (destx)*ratiox;
float ydest = (desty)*ratioy;
float wdest = (width)*ratiox;
float hdest = (height)*ratioy;
BOOL err=StretchBlt(localdc,(int)xdest,(int)ydest,(int)wdest,(int)hdest, localcdc, srcx, srcy,width,height, SRCCOPY);
}
SelectObject(localcdc, bitm_old);
ReleaseDC(g_hwnd_main,localdc);
}
void
x_push_done()
{
@ -672,3 +810,4 @@ x_full_screen(int do_full)
{
return;
}

View File

@ -1,42 +1,42 @@
//{{NO_DEPENDENCIES}}
// $Id: $
// Microsoft Developer Studio generated include file.
// Used by win32.rc
//
#define IDD_ABOUT_DIALOG 101
#define IDC_KEGS32 102
#define IDR_TOOLBAR 103
#define IDD_DLG_DISKCONF 104
#define IDR_ACCEL 105
#define ID_TOOLBAR 5000
#define ID_STATUSBAR 5001
#define IDC_EDIT_S5D1 10051
#define IDC_EDIT_S5D2 10052
#define IDC_EDIT_S6D1 10061
#define IDC_EDIT_S6D2 10062
#define IDC_EDIT_S7D1 10071
#define IDC_EDIT_S7D2 10072
#define IDC_BTN_S5D1 11051
#define IDC_BTN_S5D2 11052
#define IDC_BTN_S6D1 11061
#define IDC_BTN_S6D2 11062
#define IDC_BTN_S7D1 11071
#define IDC_BTN_S7D2 11072
#define ID_HELP_ABOUT 40001
#define ID_FILE_EXIT 40002
#define ID_FILE_DISK 40003
#define ID_FILE_SENDRESET 40004
#define ID_FILE_JOYSTICK 40005
#define ID_FILE_DEBUGSTAT 40006
#define ID_FILE_FULLSCREEN 40012
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 111
#define _APS_NEXT_COMMAND_VALUE 40013
#define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
//{{NO_DEPENDENCIES}}
// $Id: $
// Microsoft Developer Studio generated include file.
// Used by win32.rc
//
#define IDD_ABOUT_DIALOG 101
#define IDC_KEGS32 102
#define IDR_TOOLBAR 103
#define IDD_DLG_DISKCONF 104
#define IDR_ACCEL 105
#define ID_TOOLBAR 5000
#define ID_STATUSBAR 5001
#define IDC_EDIT_S5D1 10051
#define IDC_EDIT_S5D2 10052
#define IDC_EDIT_S6D1 10061
#define IDC_EDIT_S6D2 10062
#define IDC_EDIT_S7D1 10071
#define IDC_EDIT_S7D2 10072
#define IDC_BTN_S5D1 11051
#define IDC_BTN_S5D2 11052
#define IDC_BTN_S6D1 11061
#define IDC_BTN_S6D2 11062
#define IDC_BTN_S7D1 11071
#define IDC_BTN_S7D2 11072
#define ID_HELP_ABOUT 40001
#define ID_FILE_EXIT 40002
#define ID_FILE_DISK 40003
#define ID_FILE_SENDRESET 40004
#define ID_FILE_JOYSTICK 40005
#define ID_FILE_DEBUGSTAT 40006
#define ID_FILE_FULLSCREEN 40012
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 111
#define _APS_NEXT_COMMAND_VALUE 40013
#define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -1,53 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainview"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.froop.app.kegs.KegsView
android:id="@+id/kegsview"
android:layout_width="704px"
android:layout_height="462px"/>
<LinearLayout orientation="horiontal" android:layout_width="wrap_content" android:layout_height="wrap_content">
<com.froop.app.kegs.KegsView
android:id="@+id/kegsview"
android:layout_width="704px"
android:layout_height="462px"
android:layout_centerHorizontal="true"
/>
<Button android:id="@+id/key_escape" android:text="Esc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" />
<LinearLayout android:id="@+id/b1" android:layout_below="@id/kegsview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<Button android:id="@+id/key_return" android:text="Return" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" />
<Button android:id="@+id/key_tab" android:text="Tab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" />
<Button android:id="@+id/key_f4" android:text="F4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" />
<Button android:id="@+id/key_escape" android:text="Esc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" android:layout_below="@id/kegsview" />
<Button android:id="@+id/key_return" android:text="Return" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" android:layout_below="@id/kegsview" />
<Button android:id="@+id/key_tab" android:text="Tab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" android:layout_below="@id/kegsview" />
<Button android:id="@+id/key_f4" android:text="F4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" android:layout_below="@id/kegsview" />
<ToggleButton android:id="@+id/key_control"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|bottom"
android:textOn="Ctrl"
android:textOff="Ctrl" />
<ToggleButton android:id="@+id/key_open_apple"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|bottom"
android:textOn="Cmd"
android:textOff="Cmd" />
android:textOff="Ctrl" android:layout_below="@id/kegsview" />
<ToggleButton android:id="@+id/key_closed_apple"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|bottom"
android:textOn="Opt"
android:textOff="Opt" />
android:textOff="Opt" android:layout_below="@id/kegsview" />
<Button android:id="@+id/key_left" android:text="Left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" />
<Button android:id="@+id/key_right" android:text="Right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" />
<Button android:id="@+id/key_up" android:text="Up" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" />
<Button android:id="@+id/key_down" android:text="Down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" />
<ToggleButton android:id="@+id/key_open_apple"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|bottom"
android:textOn="Cmd"
android:textOff="Cmd" android:layout_below="@id/kegsview" />
</LinearLayout>
</FrameLayout>
<LinearLayout android:id="@+id/b2" android:layout_below="@id/b1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<Button android:id="@+id/key_left" android:text="Left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" android:layout_below="@id/kegsview" />
<Button android:id="@+id/key_right" android:text="Right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" android:layout_below="@id/kegsview" />
<Button android:id="@+id/key_up" android:text="Up" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" android:layout_below="@id/kegsview" />
<Button android:id="@+id/key_down" android:text="Down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left|bottom" android:layout_below="@id/kegsview" />
</LinearLayout>
</RelativeLayout>