git @ Cat's Eye Technologies linapple / 3f5cf4d
initial import from http://linapple.sourceforge.net/ Tim O'Brien 9 years ago
86 changed file(s) with 49302 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 For LinApple version 2.0 has been made:
1
2 !! Fixed screen corruption bug for x64 systems
3
4 !! Fixed gcc 4.4 compilation error lacking <strings>
5
6 ++ FTP support. You can load disk images on Slots 6 (1 & 2) and Hard disks images, using FTP server such as apple.asimov.net
7 Press Alt+F3, Alt+Shift+F3 for load disk image through FTP
8
9 ++ Screen sizes are now flexible. You can set any screen size you wish, just be catious - not all screen sizes can work in full screen mode
10
11 ++ .zip images support for FDD 140K (in read-only mode). Just first file in .zip archive will be read and inserted as an image.
12 You can load .zip images directly from your file system (by F3/F4 keypress), or from FTP server (by pressing ALT+F3(F4)).
13
14 -- Sound is still glitched. Needs repairing. Please help!
15
16
17 For LinApple version 1.1 has been added:
18
19 ++ 1. Opening of compressed .gz files - in read-only mode. Works only for FDD 140Kb drives.
20
21 ++ 2. Super quick load-save states (CTRL+0..9 - quick load state, CTRL+SHIFT+0..9 - quick save it) in current states directory.
22
23 ++ 3. Add Mockingboard (but not Phasor??) support, without speech, as I could take it.
24 But Mockingboard works! You may test it in such games as Berzap! (you need to switch Mockingboard on after pressing Ctrl+C in the game), in Willy Byte in the Digital Dimensions, in Pitfall II(tm), in UltimaIV and few others.
25
26 ++ 4. VideoBenchmark added! Run `linapple -b' to see benchmark running and its result in console.
27
28 ++ 5. Parallel Printer file name can be set in linapple.conf (default was Printer.txt in working directory)
0 Linapple - crossplatfom emulator of Apple][ (Apple2, Apple 2) series computer for Linux or other OSes with SDL support.
1
2
3 [INSTALL]
4
5 You need SDL, cURL, zlib and libzip:
6
7 For Debian/Ubuntu their names are:
8
9 libsdl1.2-dev - Simple Direct Media crossplatform library for video,audio, events etc.
10 libcurl4 - openssl-dev - cURL net functions
11 zlib1g-dev - access .gz files
12 libzip-dev - access .zip files
13
14 All these libraries are available for free around the world.
15
16 For example for Debian/Ubuntu to install:
17
18 $sudo apt-get install libsdl1.2-dev libcurl4-openssl-dev zlib1g-dev libzip-dev
19
20
21 After being SDL, zlib, cURL and libzip installed you will be able to compile linapple from sources:
22
23 Untar the package (in .bz2 format):
24
25 $ tar xjf linapple-src_2a.tar.bz2
26
27
28 Then go to src directory and compile.
29
30 $ cd linapple-src_2a/src
31
32 $ make
33
34 If there was no errors, you may install it if you wish:
35
36 $ sudo make install
37
38 It will be install in /usr/local/linapple folder, whre you can find linapple.conf file for changing some linapple settings,
39 and empty `images` and `ftp` folders, where Apple 2 images files and downloaded through FTP images are meant to be in.
40
41 But of course you are free to choose any directories of your choice.
42 Note: you should read/write permissions of these folders, or linapple could not work properly.
43
44 For linaaple ability to unpack .zip and .gz files on the fly (either from local disks or from FTP) you also need read/write access for linapple working
45 folder (which by default is /usr/local/linapple), for linapple unpacks these files as drive0.dsk and drive1.dsk for drive 1 and 2 respectively.
46
47
48 OK.
49 If you installed it, you are able to run emulator from any place, just run it like this:
50
51 $ linapple
52
53
54 If you have chosen not to install it, go to the upper directory then and run the beast:
55
56 $ cd ..
57
58 $ ./linapple
59
60
61 If all files are on their places, you should see an X-Window with splash screen.
62 Press F2 (or F3 before to choose some disk image in drive 1), and go to work.
63
64 Note: linapple needs some files in its current working directory for proper working.
65
66 These files are:
67
68 splash.bmp - splash screen
69 charset40.bmp - charset for Apple][ (Apple 2e, etc.) text modes.
70 font.bmp - font for Help screen and Disk Select screens.
71 icon.bmp - nice icon, logo of Apple][ computer.
72 linapple.conf - configuration file.
73 Master.dsk - disk image with Applesoft(tm) DOS 3.3 inside. See Apple license (on apple.com) for details.
74
75 Essentials are font.bmp and charset40.bmp, others can be omitted peacefully.
76
77 P.S. You may play with some options in Makefile in src directory, if you know what you are to do. :)
78
79 Note: See README file for more detailed instructions on using linapple.
80
81
82 [UNINSTALL]
83
84 To uninstall previously installed linapple (by `sudo make install` command) you may write this:
85
86 $ sudo make uninstall
87
88 This will remove by default entire `/usr/local/linapple` folder and `/usr/local/bin/linapple` script.
89
90
91 Also there is possible command for cleaning compiled binaries in src directory:
92
93 $ make clean
94
95 Note: `linapple` executable in upper directory will remain intact.
96
97
98
99 [CONTACT]
100
101 I will be glad to see your comments, suggestions and so on on my email: beotiger@gmail.com
102
103 Sincerely Yours,
104 Krez beom beotiger, December 2007 AD - March 2012 AD
105
106 beotiger@mail.ru
107 beotiger@gmail.com
108
109 Let Apple 2 live forever!
110
0 GNU GENERAL PUBLIC LICENSE
1 Version 2, June 1991
2
3 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
4 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
5 Everyone is permitted to copy and distribute verbatim copies
6 of this license document, but changing it is not allowed.
7
8 Preamble
9
10 The licenses for most software are designed to take away your
11 freedom to share and change it. By contrast, the GNU General Public
12 License is intended to guarantee your freedom to share and change free
13 software--to make sure the software is free for all its users. This
14 General Public License applies to most of the Free Software
15 Foundation's software and to any other program whose authors commit to
16 using it. (Some other Free Software Foundation software is covered by
17 the GNU Library General Public License instead.) You can apply it to
18 your programs, too.
19
20 When we speak of free software, we are referring to freedom, not
21 price. Our General Public Licenses are designed to make sure that you
22 have the freedom to distribute copies of free software (and charge for
23 this service if you wish), that you receive source code or can get it
24 if you want it, that you can change the software or use pieces of it
25 in new free programs; and that you know you can do these things.
26
27 To protect your rights, we need to make restrictions that forbid
28 anyone to deny you these rights or to ask you to surrender the rights.
29 These restrictions translate to certain responsibilities for you if you
30 distribute copies of the software, or if you modify it.
31
32 For example, if you distribute copies of such a program, whether
33 gratis or for a fee, you must give the recipients all the rights that
34 you have. You must make sure that they, too, receive or can get the
35 source code. And you must show them these terms so they know their
36 rights.
37
38 We protect your rights with two steps: (1) copyright the software, and
39 (2) offer you this license which gives you legal permission to copy,
40 distribute and/or modify the software.
41
42 Also, for each author's protection and ours, we want to make certain
43 that everyone understands that there is no warranty for this free
44 software. If the software is modified by someone else and passed on, we
45 want its recipients to know that what they have is not the original, so
46 that any problems introduced by others will not reflect on the original
47 authors' reputations.
48
49 Finally, any free program is threatened constantly by software
50 patents. We wish to avoid the danger that redistributors of a free
51 program will individually obtain patent licenses, in effect making the
52 program proprietary. To prevent this, we have made it clear that any
53 patent must be licensed for everyone's free use or not licensed at all.
54
55 The precise terms and conditions for copying, distribution and
56 modification follow.
57
58 GNU GENERAL PUBLIC LICENSE
59 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
60
61 0. This License applies to any program or other work which contains
62 a notice placed by the copyright holder saying it may be distributed
63 under the terms of this General Public License. The "Program", below,
64 refers to any such program or work, and a "work based on the Program"
65 means either the Program or any derivative work under copyright law:
66 that is to say, a work containing the Program or a portion of it,
67 either verbatim or with modifications and/or translated into another
68 language. (Hereinafter, translation is included without limitation in
69 the term "modification".) Each licensee is addressed as "you".
70
71 Activities other than copying, distribution and modification are not
72 covered by this License; they are outside its scope. The act of
73 running the Program is not restricted, and the output from the Program
74 is covered only if its contents constitute a work based on the
75 Program (independent of having been made by running the Program).
76 Whether that is true depends on what the Program does.
77
78 1. You may copy and distribute verbatim copies of the Program's
79 source code as you receive it, in any medium, provided that you
80 conspicuously and appropriately publish on each copy an appropriate
81 copyright notice and disclaimer of warranty; keep intact all the
82 notices that refer to this License and to the absence of any warranty;
83 and give any other recipients of the Program a copy of this License
84 along with the Program.
85
86 You may charge a fee for the physical act of transferring a copy, and
87 you may at your option offer warranty protection in exchange for a fee.
88
89 2. You may modify your copy or copies of the Program or any portion
90 of it, thus forming a work based on the Program, and copy and
91 distribute such modifications or work under the terms of Section 1
92 above, provided that you also meet all of these conditions:
93
94 a) You must cause the modified files to carry prominent notices
95 stating that you changed the files and the date of any change.
96
97 b) You must cause any work that you distribute or publish, that in
98 whole or in part contains or is derived from the Program or any
99 part thereof, to be licensed as a whole at no charge to all third
100 parties under the terms of this License.
101
102 c) If the modified program normally reads commands interactively
103 when run, you must cause it, when started running for such
104 interactive use in the most ordinary way, to print or display an
105 announcement including an appropriate copyright notice and a
106 notice that there is no warranty (or else, saying that you provide
107 a warranty) and that users may redistribute the program under
108 these conditions, and telling the user how to view a copy of this
109 License. (Exception: if the Program itself is interactive but
110 does not normally print such an announcement, your work based on
111 the Program is not required to print an announcement.)
112
113 These requirements apply to the modified work as a whole. If
114 identifiable sections of that work are not derived from the Program,
115 and can be reasonably considered independent and separate works in
116 themselves, then this License, and its terms, do not apply to those
117 sections when you distribute them as separate works. But when you
118 distribute the same sections as part of a whole which is a work based
119 on the Program, the distribution of the whole must be on the terms of
120 this License, whose permissions for other licensees extend to the
121 entire whole, and thus to each and every part regardless of who wrote it.
122
123 Thus, it is not the intent of this section to claim rights or contest
124 your rights to work written entirely by you; rather, the intent is to
125 exercise the right to control the distribution of derivative or
126 collective works based on the Program.
127
128 In addition, mere aggregation of another work not based on the Program
129 with the Program (or with a work based on the Program) on a volume of
130 a storage or distribution medium does not bring the other work under
131 the scope of this License.
132
133 3. You may copy and distribute the Program (or a work based on it,
134 under Section 2) in object code or executable form under the terms of
135 Sections 1 and 2 above provided that you also do one of the following:
136
137 a) Accompany it with the complete corresponding machine-readable
138 source code, which must be distributed under the terms of Sections
139 1 and 2 above on a medium customarily used for software interchange; or,
140
141 b) Accompany it with a written offer, valid for at least three
142 years, to give any third party, for a charge no more than your
143 cost of physically performing source distribution, a complete
144 machine-readable copy of the corresponding source code, to be
145 distributed under the terms of Sections 1 and 2 above on a medium
146 customarily used for software interchange; or,
147
148 c) Accompany it with the information you received as to the offer
149 to distribute corresponding source code. (This alternative is
150 allowed only for noncommercial distribution and only if you
151 received the program in object code or executable form with such
152 an offer, in accord with Subsection b above.)
153
154 The source code for a work means the preferred form of the work for
155 making modifications to it. For an executable work, complete source
156 code means all the source code for all modules it contains, plus any
157 associated interface definition files, plus the scripts used to
158 control compilation and installation of the executable. However, as a
159 special exception, the source code distributed need not include
160 anything that is normally distributed (in either source or binary
161 form) with the major components (compiler, kernel, and so on) of the
162 operating system on which the executable runs, unless that component
163 itself accompanies the executable.
164
165 If distribution of executable or object code is made by offering
166 access to copy from a designated place, then offering equivalent
167 access to copy the source code from the same place counts as
168 distribution of the source code, even though third parties are not
169 compelled to copy the source along with the object code.
170
171 4. You may not copy, modify, sublicense, or distribute the Program
172 except as expressly provided under this License. Any attempt
173 otherwise to copy, modify, sublicense or distribute the Program is
174 void, and will automatically terminate your rights under this License.
175 However, parties who have received copies, or rights, from you under
176 this License will not have their licenses terminated so long as such
177 parties remain in full compliance.
178
179 5. You are not required to accept this License, since you have not
180 signed it. However, nothing else grants you permission to modify or
181 distribute the Program or its derivative works. These actions are
182 prohibited by law if you do not accept this License. Therefore, by
183 modifying or distributing the Program (or any work based on the
184 Program), you indicate your acceptance of this License to do so, and
185 all its terms and conditions for copying, distributing or modifying
186 the Program or works based on it.
187
188 6. Each time you redistribute the Program (or any work based on the
189 Program), the recipient automatically receives a license from the
190 original licensor to copy, distribute or modify the Program subject to
191 these terms and conditions. You may not impose any further
192 restrictions on the recipients' exercise of the rights granted herein.
193 You are not responsible for enforcing compliance by third parties to
194 this License.
195
196 7. If, as a consequence of a court judgment or allegation of patent
197 infringement or for any other reason (not limited to patent issues),
198 conditions are imposed on you (whether by court order, agreement or
199 otherwise) that contradict the conditions of this License, they do not
200 excuse you from the conditions of this License. If you cannot
201 distribute so as to satisfy simultaneously your obligations under this
202 License and any other pertinent obligations, then as a consequence you
203 may not distribute the Program at all. For example, if a patent
204 license would not permit royalty-free redistribution of the Program by
205 all those who receive copies directly or indirectly through you, then
206 the only way you could satisfy both it and this License would be to
207 refrain entirely from distribution of the Program.
208
209 If any portion of this section is held invalid or unenforceable under
210 any particular circumstance, the balance of the section is intended to
211 apply and the section as a whole is intended to apply in other
212 circumstances.
213
214 It is not the purpose of this section to induce you to infringe any
215 patents or other property right claims or to contest validity of any
216 such claims; this section has the sole purpose of protecting the
217 integrity of the free software distribution system, which is
218 implemented by public license practices. Many people have made
219 generous contributions to the wide range of software distributed
220 through that system in reliance on consistent application of that
221 system; it is up to the author/donor to decide if he or she is willing
222 to distribute software through any other system and a licensee cannot
223 impose that choice.
224
225 This section is intended to make thoroughly clear what is believed to
226 be a consequence of the rest of this License.
227
228 8. If the distribution and/or use of the Program is restricted in
229 certain countries either by patents or by copyrighted interfaces, the
230 original copyright holder who places the Program under this License
231 may add an explicit geographical distribution limitation excluding
232 those countries, so that distribution is permitted only in or among
233 countries not thus excluded. In such case, this License incorporates
234 the limitation as if written in the body of this License.
235
236 9. The Free Software Foundation may publish revised and/or new versions
237 of the General Public License from time to time. Such new versions will
238 be similar in spirit to the present version, but may differ in detail to
239 address new problems or concerns.
240
241 Each version is given a distinguishing version number. If the Program
242 specifies a version number of this License which applies to it and "any
243 later version", you have the option of following the terms and conditions
244 either of that version or of any later version published by the Free
245 Software Foundation. If the Program does not specify a version number of
246 this License, you may choose any version ever published by the Free Software
247 Foundation.
248
249 10. If you wish to incorporate parts of the Program into other free
250 programs whose distribution conditions are different, write to the author
251 to ask for permission. For software which is copyrighted by the Free
252 Software Foundation, write to the Free Software Foundation; we sometimes
253 make exceptions for this. Our decision will be guided by the two goals
254 of preserving the free status of all derivatives of our free software and
255 of promoting the sharing and reuse of software generally.
256
257 NO WARRANTY
258
259 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
260 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
261 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
262 PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
263 OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
264 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
265 TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
266 PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
267 REPAIR OR CORRECTION.
268
269 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
270 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
271 REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
272 INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
273 OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
274 TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
275 YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
276 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
277 POSSIBILITY OF SUCH DAMAGES.
278
279 END OF TERMS AND CONDITIONS
280
281 How to Apply These Terms to Your New Programs
282
283 If you develop a new program, and you want it to be of the greatest
284 possible use to the public, the best way to achieve this is to make it
285 free software which everyone can redistribute and change under these terms.
286
287 To do so, attach the following notices to the program. It is safest
288 to attach them to the start of each source file to most effectively
289 convey the exclusion of warranty; and each file should have at least
290 the "copyright" line and a pointer to where the full notice is found.
291
292 <one line to give the program's name and a brief idea of what it does.>
293 Copyright (C) <year> <name of author>
294
295 This program is free software; you can redistribute it and/or modify
296 it under the terms of the GNU General Public License as published by
297 the Free Software Foundation; either version 2 of the License, or
298 (at your option) any later version.
299
300 This program is distributed in the hope that it will be useful,
301 but WITHOUT ANY WARRANTY; without even the implied warranty of
302 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
303 GNU General Public License for more details.
304
305 You should have received a copy of the GNU General Public License
306 along with this program; if not, write to the Free Software
307 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
308
309
310 Also add information on how to contact you by electronic and paper mail.
311
312 If the program is interactive, make it output a short notice like this
313 when it starts in an interactive mode:
314
315 Gnomovision version 69, Copyright (C) year name of author
316 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 This is free software, and you are welcome to redistribute it
318 under certain conditions; type `show c' for details.
319
320 The hypothetical commands `show w' and `show c' should show the appropriate
321 parts of the General Public License. Of course, the commands you use may
322 be called something other than `show w' and `show c'; they could even be
323 mouse-clicks or menu items--whatever suits your program.
324
325 You should also get your employer (if you work as a programmer) or your
326 school, if any, to sign a "copyright disclaimer" for the program, if
327 necessary. Here is a sample; alter the names:
328
329 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
332 <signature of Ty Coon>, 1 April 1989
333 Ty Coon, President of Vice
334
335 This General Public License does not permit incorporating your program into
336 proprietary programs. If your program is a subroutine library, you may
337 consider it more useful to permit linking proprietary applications with the
338 library. If this is what you want to do, use the GNU Library General
339 Public License instead of this License.
Binary diff not shown
(New empty file)
0 *** LINAPPLE 2.0***
1
2 [INTRO]
3 What is linapple?
4 It is an emulator of Apple2 (Apple][, Apple 2, Apple 2e etc.) computer series for Linux or other OSes with SDL support.
5
6 (SDL means Simple DirectMedia Layer written by Sam Lantinga and others).
7
8 linapple works out of the box, just make it once and run whenever you wish.
9
10 Why not AppleLin? Yes, at first I think to call it such, but later linapple seemed better to me. And one point!
11
12 This is my work for making it possible to have comprehensive emulator of Apple][ computer series in Linux.
13
14 The original source is from AppleWin (http://applewin.berlios.de) by Tom Charlesworth and others.
15
16 I just adapted it for: video+audio for SDL, other functions for POSIX compliant OS, which Linux is in particularly.
17
18 Later some sort of Windows support had been added, so you may try to compile it under Windows.
19
20
21
22 [INSTALL]
23
24 I will show brief instructions for compiling and installing linapple here.
25
26 Please, see INSTALL file for comprehensive installing tips.
27
28 After SDL1.2, zlib, libcurl and libzip are installed in your system, you can build sources.
29
30 Unpack downloaded linapple archive and go to src directory:
31
32 $ cd src
33
34 Then run:
35
36 $ make
37
38 or
39
40 $ sudo make install
41
42 If there is no errors, run:
43
44 $ linapple
45
46 or without being installed:
47
48 $ cd ..
49 $ ./linapple
50
51 If all files are on their places, you should see an X-Window with splash screen.
52
53 Press F2 (or F3 or Alt+F3) before to choose some disk image in drive 1), and go to work.
54
55 It works as well as AppleWin, although it needs testing and supporting.
56 Where to install? Anywhere you feel fit, just let linapple be with some files it needs for comprehenceive working.
57
58 These files are:
59
60 splash.bmp - splash screen
61 charset40.bmp - charset for Apple][ (Apple 2e, etc.) text modes.
62 font.bmp - font for Help screen and Disk Select screens.
63 icon.bmp - nice icon, logo of Apple][ computer.
64 linapple.conf - configuration file.
65 Master.dsk - disk image with Applesoft(tm) DOS 3.3 inside. See Apple license (on apple.com) for details.
66
67
68 [USING LINAPPLE]
69
70 At first start you should see some nice splashscreen. Press F2 to start emualtion. Master.dsk should load, and you will see an DOS3.3(tm) prompt. By pressing F3 you may select an image file name (usually having extensions .dsk, .do, .po) into Slot 6 Drive 1. After selecting it, you either may reboot anew (by pressing F2 key) and try to boot from the inserted disk, or type any DOS3.3(tm) commands to view disk contents and to run any program located in it. Common DOS commands are `CATALOG' (like `ls' in Linux), `BRUN FILENAME' - running any binary (B) program, or `RUN FILENAME' - running any Basic program (A or I). Usually, most game images have alternative way to run programs in them. You may find a lot of disk images on largest and oldest ftp for Apple][ stuff ftp.apple.asimov.net.
71
72 From version 2 of linapple you are able to download such images directly from FTP! Use Alt+F3 or Alt+F4 for charging drive 1 and drive 2 for slot 6 (if you know what I am about :) ) - they are just common disk sources of Apple 2 computer for reading/writing its files, such as system, games, utilities and so on.
73
74 To quit emualtor peacefully, press F10. F6 toggles fullscreen mode, Scroll Lock toggles fullspeed mode.
75
76 Other possible key commands of linapple are the following:
77
78 F1 - Show help screen
79 F2 - Cold reset
80 Shift+F2 - Reload conf file and restart
81 F3, F4 - Choose an image file name for floppy disk in Slot 6 drive 1 or 2 respectively
82 Shift+F3, Shift+F4 - The same thing for Apple hard disks (in Slot 7)
83 Alt+F3,Alt+F4 - same as F3,F4 using FTP (see linapple.conf about configuring FTP accounts)
84 Alt+Shift+F3, Alt+Shift+F4 - same as Shift+F3, Shift+F4 but using FTP account (see above)
85
86 F5 - Swap drives for Slot 6
87 F6 - Toggle fullscreen mode
88 F7 - Reserved for Debugger!
89 F8 - Save current screen as a .bmp file
90 Shift+F8 - Save settings changable in runtime in conf file
91
92 F9 - Cycle through various video modes
93 F10 - Quit emulator
94
95 F11 - Save current state to file, Alt+F11 - quick save
96 F12 - Reload it from file, Alt+F12 - quick load
97
98 Ctrl+0..9 - fast load state snapshot with corresponding number, saved previously by
99 Ctrl+Shift+0..9 - fast save snapshot to current snapshot directory with corresponding number 0..9
100
101 Ctrl+F12 - Hot reset
102
103 Pause - Pause emulator
104 Scroll Lock - Toggle full speed
105 Num pad keys:
106 Grey + - Speed up emulator
107 Grey - - Speed it down
108 Grey * - Normal speed
109
110 Other powerful way to control behaviour of linapple is to change different settings in linapple.conf file, which should be located in the same directory where linapple is. Please, see linapple.conf contents to know what each setting means.
111
112 Note one point, too. When mouse works as a joystick, or Mouse Interface is on, when you first left-click on the window of emulator, mouse cursor is grabbed for using inside it. To release cursor, you should click left-mouse button again with SHIFT or CTRL key pressed. In fullscreen mode mouse cursor is always grabbed, to release it you may want to switch to windowed mode by pressing F6 key.
113
114 In version 1.1 appeared VideoBenchmark: start linapple with -b command-line key to see its results, like this:
115
116 $ ./linapple -b - run VideoBenchmark and exit emulator. Note: if fullscreen mode is on in linapple.conf, then
117 VideoBenchmark will be runned in fullscreen mode.
118
119
120
121 In version 2 besides FTP support there is also support for changable Window sizes (see at the end of linapple.conf file for details).
122 Just be aware when you are not running emulator on its native mode (560x384) you can suffer slowdown if you are using old box.
123
124
125
126 [SUPPORT]
127 Wanted:
128
129 -- we need to get rid of some SOUND glitches. HELP!
130
131 --DEBUGGER
132 I just owe at 9300 lines of code of AppleWin debugger. Michael Pohoreski, you are he-man, I tell you.
133 Besides Debugger.cpp alone, there are some helper files such as Debugger_Assembler.cpp,
134 Debugger_Console.cpp, Debugger_Display.cpp and so on. Who is able to port it to linapple?
135
136
137 --PHASOR
138 Who knows how does that great thing work? Please, help adopting it to lianpple.
139 All sources for sound support are in Mockingboard.cpp and SoundCore.cpp.
140 SDL Audio used. Speakers are working out in Speaker.cpp. Who may think, heh?
141 From version 1.1 Mockingboard support are done.
142
143
144
145 More testing and debugging needed, of course. I would be grateful for any comment or suggestion regarding linapple, and using it on OSes other than Linux.
146
147
148 [CONTACTS]
149 I am Krez beom beotiger (Kbb), you may contact me at your will by my email beotiger@gmail.com or beotiger@mail.ru
150
151 Web-site: http://linapple.sourceforge.net
152
153
154 Thank you very much.
155 Long Live Linux!
156 And Apple][!
157
158 --
159 24 March 2012 AD
160 beotiger@mail.ru
161
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 #
1 # linapple.conf - config file used by LinApple, Apple][ (Apple2, Apple 2) emulator for Linux and other POSIX systems with SDL support
2 #
3 # for linapple version 2.0 and above
4 #
5 # Please remember - all lines beginning with '#' are considered comments.
6 # All values are CASE SENSITIVE, you should not use, for example, 'joystick 0' instead of 'Joystick 0'.
7 #
8 ####################################################################
9 # First of all let us determine our machine type
10 # that is:
11 # 0 - old Apple][, right out of the hands of Steve Wozniak and Steve Jobs in far 1977? year.
12 # 1 - Apple][+ - same as Apple][ with somewhat enbettered functionality
13 # 2 - Apple//e - Enhanced Apple][ with 80-column mode and other useful additions
14 # 3 - Apple//e enhanced - currently same as Apple//e? Please, ask Tom Charlesworth about it.
15 # Default is 3
16
17 Computer Emulation = 2
18
19 ####################################################################
20 #
21 # Sound Emulation.
22 # Possible values currently are 0 - none, and 1 - use SDL Audio for sounds
23 # Default is 1
24
25 Sound Emulation = 1
26
27 #######################################################################
28 #
29 # Soundcard Type means what do you want to use in Slot7 as a sound card
30 #
31 # 0 - uninit //??
32 # 1 - nothing - disable sound card in Slot 4
33 # 2 - use Mockingboard in Slot 4 (Mockingboard is like SoundBlaster for PC, if you hear about it)
34 # 3 - use Phasor in Slot 4. Phasor is also a sort of ancient sound cards. Ahhh, what sounds they have!!!
35 #
36 # Default value is 2 (use Mockingboard).
37 # But, please, remember, that currently Mockingboard/Phasor support was not done fully in linapple.
38 # I need some help for this to port it from AppleWin. ^_^
39
40 Soundcard Type = 2
41
42 #######################################################################
43 #
44 # Joysticks, those sticks of joy! There may be 2 joysticks at the same time
45 # Possible values are:
46 # 0 - joystick disabled
47 # 1 - use PC joystick #1 or #2, for corresponding joystick
48
49 # 2 - Keyboard standard
50 # 3 - Keyboard centered
51 # When joysticks used as a keyboard, they are stuck to Numpad keys (1-9 - axis movement, 0 - button1, . - button2)
52 # when centered used, axis of joystick will be centered after releasing any cursor (Numpad 1..9) key.
53 # otherwise it assumed to be pressed always
54
55 # 4 - Use mouse as a joystick. Rather interesting thing, try it. Useful in Fantavision(tm)by Broderbund Software
56 # Default values are 2 for Joystick 0, and 0 for Joystick 1
57
58 Joystick 0 = 3
59 Joystick 1 = 0
60
61 ##########################################################################
62 #
63 # Serial Port joins your Apple][ machine to any device through serial ports.
64 # Possible values are 0 - disabled, and 1 to 100 which means device /dev/ttyS0 .. /dev/ttyS99 relatively
65 #
66 # Default is 0, disabled. Needs testing.
67
68 Serial Port = 0
69
70 ##########################################################################
71
72 # Emulation Speed is speed of emulator.
73 # Values are from 0 (lowest speed) till 40 (fastest)
74 # Default value is 10 (normal speed)
75
76 Emulation Speed = 10
77
78 ##########################################################################
79 #
80 # Enhance Disk Speed - if the disk spinning should be as in real computer
81 # Possible values - 0 - yes, the disk spinning speed is like in real Apple][
82 # and 1 - use enhanced disk speed.
83 # Default is 1.
84
85 Enhance Disk Speed = 1
86
87 ##########################################################################
88 #
89 # Video Emulation - a type of video emulation.
90 # Please, remember that you always can change it using F9 key in emulator.
91
92 # Possible values are:
93 # 0 - use monochrome screen with given color as white (see below Monochrome Color section)
94
95 # Color modes, which names speak for themselves.
96 # 1 - Color Standard
97 # 2 - Color Text Optimized
98 # 3 - Color TV emulation
99 # 4 - Color Half-Shift
100
101 # Monochrome modes with predefined monochrome colors
102 # 5 - Monochrome Amber
103 # 6 - Monochrome Green
104 # 7 - Monochrome White
105 #
106 # Default value is 3 - Color TV emulation!
107
108 Video Emulation = 1
109
110 ##########################################################################
111 #
112 # Monochrome Color - define monochrome color that suit you best here.
113 # Color defined as #RRGGBB, where RR - 2 digits for Red color intensity, GG - same for Green color, and BB for Blue.
114 # All digits are in HEX-format, 0-9 and A - F.
115 # Default value is #C0C0C0.
116
117 Monochrome Color = #FFC010
118
119 ##########################################################################
120 #
121 # Mouse in slot 4. Yes, old Apples][ have it! First they saw it in Xerox Development Center.
122 # Possible values are 0 - off, and 1 - on.
123 # Remember, that you can not use Mouse and Mockingboard/Phasor at the same time, for they use same slot (#4).
124 # So, before enabling mouse support in your machine, switch off Mockingboard (see section above).
125
126 # Default is 0.
127
128 Mouse in slot 4 = 0
129
130 ##########################################################################
131 #
132 # Parallel printer allows you to print any DOS3.3 or Applesoft Basic(tm) output to specified file
133 # (after PR#1 at DOS3.3 prompt)
134 #
135 # Default is Printer.txt in working directory (which is set inside linapple bin)
136
137 Parallel Printer Filename =
138
139 ##########################################################################
140 #
141 # HDD - Hard Disk Device for Apple][
142 #
143 # Harddisk Enable. Same as for mouse. 0 means no Harddisk support, and 1 - yes, give that Harddisk!
144 # Remember, that hard disk images for Apple][ are in .HDV format as a rule (with .hdv extensions)
145 # Hard disk uses Slot 7 in Apple][. So, to access it use something like '] PR#7' at Applesoft Basic(tm) prompt.
146 # Default is 0.
147
148 Harddisk Enable = 0
149
150 # HDV Starting Directory is the starting directory for choose HDV disk images
151 # Default: your home directory (if not set)
152
153 HDV Starting Directory =
154
155 # And you may also predefine hard disk images here, for 1 and 2 correspondingly.
156 # Please, use Shift+F3 and Shift+F4 in emulator for change them in real time.
157 # Remember, that values given here will be rewritten if you change them in emulator.
158 # Default - do not use any HDV images
159
160 Harddisk Image 1 =
161 Harddisk Image 2 =
162
163 ##########################################################################
164 #
165 # Slot 6 Directory - starting directory for chosing Apple's disk images in slot 6
166 # (usual slot for FDD 140Kb Apple's disks)
167 #
168 # Default: your home directory (if not set)
169
170 Slot 6 Directory =
171
172 # You may also provide images to be inserted in 1 and 2 drive (D1 or D2) of Slot 6 at startup
173 # Default: do not use, starting with image named Master.dsk in current directory
174
175 # To get access to the disk in second drive(D2), use something like '] CATALOG,D2' at Applesoft DOS(tm) prompt.
176
177 Disk Image 1 =
178 Disk Image 2 =
179
180 # The next parameter defines if you wish to auto-load these disk images in drives at startup!
181 # Default value is 0 (Off), suggested: 1 (On)
182
183 Slot 6 Autoload = 0
184
185 ##########################################################################
186 #
187 # Save State Filename - file name for saving/loading state with keys F11 and F12 in emulator.
188 # Default is none. Note: you can choose it at runtime by pressing F11 (for saving) or F12 (for loading)
189
190 Save State Filename =
191
192 # SaveSate Directory is a directory where current states will be saved by using F11,F12 (or ALT+F11, ALT+F12 keys, or Ctrl+0..9, Ctrl+Shift+0..9)
193 #Default is none, which means your home directory
194
195 Save State Directory =
196
197 # Define if you wish to save state on exit and restore it at startup by the next parameter:
198 # Possible values are 0 - off, and 1 - on. When On, save state will be saved in Save State Filename at exit,
199 # and will be restored at startup
200
201 # Default value is 0.
202
203 Save State On Exit = 0
204
205 ##########################################################################
206 #
207 # Next parameters enables some functions at startup
208 #
209 # Fullscreen - if emulator should startup in Fullscreen mode (0 - no, 1 - yes!)
210 # Boot at startup - if emulator should boot after starting up from Disk1 in SLot 6 (0 - yes, 1 - no)
211 # Booting at startup disables show logo.
212 #
213 # Show Leds 1/0 - show leds while accessing disks (140Kb and HDD) or not, default - 1
214
215 Fullscreen = 0
216 Boot at Startup = 0
217 Show Leds = 1
218
219 ##########################################################################
220 #
221 # FTP Server - full path to default FTP server with Apple2 disk images
222 # FTP UserPass - user:password for accessing this server
223 # FTP Local Dir - path on local disk to store downloaded ftp files,
224
225 # !!! Warning: FTP Local Dir should be existing directory with write access either FTP won't work
226 # Note : FTP Server MUST end with '/' sign either it won't work! FTP Local Dir should not end with '/'
227
228 FTP Server = ftp://ftp.apple.asimov.net/pub/apple_II/images/games/
229 FTP ServerHDD = ftp://ftp.apple.asimov.net/pub/apple_II/images/
230 FTP UserPass = anonymous:my-mail@mail.com
231 FTP Local Dir =
232
233 ##########################################################################
234 #
235 # Screen properties
236 # Note: not all screen sizes can work in full screen mode, so be careful
237 # Also if you are using not default mode, the speed of emulator can become slow,
238 # which can be spotted easily on old machines
239
240 # Use this as screen factor in zooming screen.
241 # Values less than 1.0 will make screen smaller and vice versa!
242 # Suggested values are 0.3 till 3.0?
243
244 # Screen factor = 1.5
245
246 # Note: if you want to use Screen Width and Screen Height directly, comment out `Screen factor` whole option
247 # otherwise they won't take effect
248 # Default Screen Width is 560, Screen Height is 384
249 Screen Width = 800
250 Screen Height = 600
251
0 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1 # !! Note 1: this configuration file is for installed linapple
2
3 # !! If you have edited Makefile (in src directory of linaple package)
4 # !! to change INSTDIR - path where lianpple are to be installed
5 # !! you should consider change some paths for disk images and FTP local directory
6 # !! in order to let linapple find proper way to access needed stuff
7
8
9 # !! Good luck to You! (beotiger: beotiger@mail.ru)
10
11
12 # Note 2: Default install directory (for *nix) is /usr/local/linapple/
13 # (defined in Make file in src directory as INSTDIR variable)
14
15
16 #
17 # linapple.conf - config file used by LinApple, Apple][ (Apple2, Apple 2) emulator for Linux and other systems with SDL support
18 #
19 # Please, note: This file is for linapple version 2.0 and above
20 #
21
22 # Remember - all lines beginning with '#' are considered comments.
23 # All values are CASE SENSITIVE, you should not use, for example, 'joystick 0' instead of 'Joystick 0'.
24 #
25
26
27 ####################################################################
28 # First of all let us determine our machine type
29 # that is:
30 # 0 - old Apple][, right out of the hands of Steve Wozniak and Steve Jobs in far 1977? year.
31 # 1 - Apple][+ - same as Apple][ with somewhat enbettered functionality
32 # 2 - Apple//e - Enhanced Apple][ with 80-column mode and other useful additions
33 # 3 - Apple//e enhanced - currently same as Apple//e? Please, ask Tom Charlesworth about it.
34 # Default is 3
35
36 Computer Emulation = 2
37
38 ####################################################################
39 #
40 # Sound Emulation.
41 # Possible values currently are 0 - none, and 1 - use SDL Audio for sounds
42 # Default is 1
43
44 Sound Emulation = 1
45
46 #######################################################################
47 #
48 # Soundcard Type means what do you want to use in Slot7 as a sound card
49 #
50 # 0 - uninit //??
51 # 1 - nothing - disable sound card in Slot 4
52 # 2 - use Mockingboard in Slot 4 (Mockingboard is like SoundBlaster for PC, if you hear about it)
53 # 3 - use Phasor in Slot 4. Phasor is also a sort of ancient sound cards. Ahhh, what sounds they have!!!
54 #
55 # Default value is 2 (use Mockingboard).
56 # But, please, remember, that currently Mockingboard/Phasor support was not done fully in linapple.
57 # I need some help for this to port it from AppleWin. ^_^
58
59 Soundcard Type = 2
60
61 #######################################################################
62 #
63 # Joysticks, those sticks of joy! There may be 2 joysticks at the same time
64 # Possible values are:
65 # 0 - joystick disabled
66 # 1 - use PC joystick #1 or #2, for corresponding joystick
67
68 # 2 - Keyboard standard
69 # 3 - Keyboard centered
70 # When joysticks used as a keyboard, they are stuck to Numpad keys (1-9 - axis movement, 0 - button1, . - button2)
71 # when centered used, axis of joystick will be centered after releasing any cursor (Numpad 1..9) key.
72 # otherwise it assumed to be pressed always
73
74 # 4 - Use mouse as a joystick. Rather interesting thing, try it. Useful in Fantavision(tm)by Broderbund Software
75 # Default values are 2 for Joystick 0, and 0 for Joystick 1
76
77 Joystick 0 = 3
78 Joystick 1 = 0
79
80 ##########################################################################
81 #
82 # Serial Port joins your Apple][ machine to any device through serial ports.
83 # Possible values are 0 - disabled, and 1 to 100 which means device /dev/ttyS0 .. /dev/ttyS99 relatively
84 #
85 # Default is 0, disabled. Needs testing.
86
87 Serial Port = 0
88
89 ##########################################################################
90
91 # Emulation Speed is speed of emulator.
92 # Values are from 0 (lowest speed) till 40 (fastest)
93 # Default value is 10 (normal speed - 1 MHz)
94
95 Emulation Speed = 10
96
97 ##########################################################################
98 #
99 # Enhance Disk Speed - if the disk spinning should be as in real computer
100 # Possible values - 0 - yes, the disk spinning speed is like in real Apple][
101 # and 1 - use enhanced disk speed.
102 # Default is 1.
103
104 Enhance Disk Speed = 1
105
106 ##########################################################################
107 #
108 # Video Emulation - a type of video emulation.
109 # Please, remember that you always can change it using F9 key in emulator.
110
111 # Possible values are:
112 # 0 - use monochrome screen with given color as white (see below Monochrome Color section)
113
114 # Color modes, which names speak for themselves.
115 # 1 - Color Standard
116 # 2 - Color Text Optimized
117 # 3 - Color TV emulation
118 # 4 - Color Half-Shift
119
120 # Monochrome modes with predefined monochrome colors
121 # 5 - Monochrome Amber
122 # 6 - Monochrome Green
123 # 7 - Monochrome White
124 #
125 # Default value is 3 - Color TV emulation!
126
127 Video Emulation = 1
128
129 ##########################################################################
130 #
131 # Monochrome Color - define monochrome color that suit you best here.
132 # Color defined as #RRGGBB, where RR - 2 digits for Red color intensity, GG - same for Green color, and BB for Blue.
133 # All digits are in HEX-format, 0-9 and A - F.
134 # Default value is #C0C0C0.
135
136 Monochrome Color = #FFC010
137
138 ##########################################################################
139 #
140 # Mouse in slot 4. Yes, old Apples][ have it! First they saw it in Xerox Development Center.
141 # Possible values are 0 - off, and 1 - on.
142 # Remember, that you can not use Mouse and Mockingboard/Phasor at the same time, for they use same slot (#4).
143 # So, before enabling mouse support in your machine, switch off Mockingboard (see section above).
144
145 # Default is 0.
146
147 Mouse in slot 4 = 0
148
149 ##########################################################################
150 #
151 # Parallel printer allows you to print any DOS3.3 or Applesoft Basic(tm) output to specified file
152 # (after PR#1 at DOS3.3 prompt)
153 #
154 # Default is Printer.txt in working directory (which is set inside linapple bin)
155
156 Parallel Printer Filename =
157
158 ##########################################################################
159 #
160 # HDD - Hard Disk Device for Apple][
161 #
162 # Harddisk Enable. Same as for mouse. 0 means no Harddisk support, and 1 - yes, give that Harddisk!
163 # Remember, that hard disk images for Apple][ are in .HDV format as a rule (with .hdv extensions)
164 # Hard disk uses Slot 7 in Apple][. So, to access it use something like '] PR#7' at Applesoft Basic(tm) prompt.
165 # Default is 0.
166
167 Harddisk Enable = 0
168
169 # HDV Starting Directory is the starting directory for choose HDV disk images
170 # Default: your home directory (if not set)
171
172 HDV Starting Directory = /usr/local/linapple/images
173
174 # And you may also predefine hard disk images here, for 1 and 2 correspondingly.
175 # Please, use Shift+F3 and Shift+F4 in emulator for change them in real time.
176 # Remember, that values given here will be rewritten if you change them in emulator.
177 # Default - do not use any HDV images
178
179 Harddisk Image 1 =
180 Harddisk Image 2 =
181
182 ##########################################################################
183 #
184 # Slot 6 Directory - starting directory for chosing Apple's disk images in slot 6
185 # (usual slot for FDD 140Kb Apple's disks)
186 #
187 # Default: your home directory (if not set)
188
189 Slot 6 Directory = /usr/local/linapple/images
190
191 # You may also provide images to be inserted in 1 and 2 drive (D1 or D2) of Slot 6 at startup
192 # Default: do not use, starting with image named Master.dsk in current directory
193
194 # To get access to the disk in second drive(D2), use something like '] CATALOG,D2' at Applesoft DOS(tm) prompt.
195
196 Disk Image 1 =
197 Disk Image 2 =
198
199 # The next parameter defines if you wish to auto-load these disk images in drives at startup!
200 # Default value is 0 (Off), suggested: 1 (On)
201
202 Slot 6 Autoload = 0
203
204 ##########################################################################
205 #
206 # Save State Filename - file name for saving/loading state with keys F11 and F12 in emulator.
207 # Default is none. Note: you can choose it at runtime by pressing F11 (for saving) or F12 (for loading)
208
209 Save State Filename = /usr/local/linapple/images/SaveState1.aws
210
211 # SaveSate Directory is a directory where current states will be saved by using F11,F12 (or ALT+F11, ALT+F12 keys, or Ctrl+0..9, Ctrl+Shift+0..9)
212 #Default is none, which means your home directory
213
214 Save State Directory = /usr/local/linapple/images
215
216 # Define if you wish to save state on exit and restore it at startup by the next parameter:
217 # Possible values are 0 - off, and 1 - on. When On, save state will be saved in Save State Filename at exit,
218 # and will be restored at startup
219
220 # Default value is 0.
221
222 Save State On Exit = 0
223
224 ##########################################################################
225 #
226 # Next parameters enables some functions at startup
227 #
228 # Fullscreen - if emulator should startup in Fullscreen mode (0 - no, 1 - yes!)
229 # Boot at startup - if emulator should boot after starting up from Disk1 in SLot 6 (0 - yes, 1 - no)
230 # Booting at startup disables show logo.
231 #
232 # Show Leds 1/0 - show leds while accessing disks (140Kb and HDD) or not, default - 1
233
234 Fullscreen = 0
235 Boot at Startup = 0
236 Show Leds = 1
237
238 ##########################################################################
239 #
240 # FTP Server - full path to default FTP server with Apple2 disk images
241 # FTP UserPass - user:password for accessing this server
242 # FTP Local Dir - path on local disk to store downloaded ftp files,
243
244 # !!! Warning: FTP Local Dir should be existing directory with write access either FTP won't work
245 # Note : FTP Server MUST end with '/' sign either it won't work! FTP Local Dir should not end with '/'
246 # Note : Also there must be cache directory (e.g. directory named `cache` inside FTP Local Dir
247 # where all downloaded directories are cached for 3 days
248
249 FTP Server = ftp://ftp.apple.asimov.net/pub/apple_II/images/games/
250 FTP ServerHDD = ftp://ftp.apple.asimov.net/pub/apple_II/images/
251 FTP UserPass = anonymous:my-mail@mail.com
252 FTP Local Dir = /usr/local/linapple/ftp
253
254 ##########################################################################
255 #
256 # Screen properties
257 # Note: not all screen sizes can work in full screen mode, so be careful
258 # Also if you are using not default mode, the speed of emulator can fall,
259 # which can be spotted on old machines
260
261 # Use this as screen factor in zooming screen.
262 # Values less than 1.0 will make screen smaller and vice versa!
263 # Suggested values are 0.3 till 3.0?
264
265 # Screen factor = 1.5
266
267
268 # Note: if you want to use Screen Width and Screen Height directly, comment out `Screen factor` whole option
269 # otherwise they won't take effect
270 # Default Screen Width is 560, Screen Height is 384
271
272 # Screen Width = 800
273 # Screen Height = 600
274
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 // Based on MAME's 6821pia.c
1 // - by Kyle Kim (Apple in PC)
2
3 //
4 // From mame.txt (http://www.mame.net/readme.html)
5 //
6 // VI. Reuse of Source Code
7 // --------------------------
8 // This chapter might not apply to specific portions of MAME (e.g. CPU
9 // emulators) which bear different copyright notices.
10 // The source code cannot be used in a commercial product without the written
11 // authorization of the authors. Use in non-commercial products is allowed, and
12 // indeed encouraged. If you use portions of the MAME source code in your
13 // program, however, you must make the full source code freely available as
14 // well.
15 // Usage of the _information_ contained in the source code is free for any use.
16 // However, given the amount of time and energy it took to collect this
17 // information, if you find new information we would appreciate if you made it
18 // freely available as well.
19 //
20
21 #include "wincompat.h"
22 #include "6821.h"
23
24 // Ctrl-A(B) register bit mask define
25 /*
26 0 1
27 bit0 IRQ1_DISABLED IRQ1_ENABLED
28 bit1 C1_HIGH_TO_LOW C1_LOW_TO_HIGH
29 bit2 DDR_SELECTED OUTPUT_SELECTED
30
31 bit3 RESET_C2 SET_C2 ( C2_OUTPUT & C2_SETMODE )
32 bit3 STROBE_C1_RESET STROBE_E_RESET ( C2_OUTPUT & C2_STROBE_MODE )
33 bit4 C2_STROBE_MODE C2_SETMODE ( C2_OUTPUT )
34
35 bit3 IRQ2_DISABLED IRQ2_ENABLED ( C2_INPUT )
36 bit4 C2_HIGH_TO_LOW C2_HIGH_TO_LOW ( C2_INPUT )
37 bit5 C2_INPUT C2_OUTPUT
38 */
39 #define PIA_IRQ1 0x80
40 #define PIA_IRQ2 0x40
41 #define SET_IRQ1(c) c |= PIA_IRQ1;
42 #define SET_IRQ2(c) c |= PIA_IRQ2;
43 #define CLEAR_IRQ1(c) c &= ~PIA_IRQ1;
44 #define CLEAR_IRQ2(c) c &= ~PIA_IRQ2;
45 #define IRQ1(c) ( c & PIA_IRQ1 )
46 #define IRQ2(c) ( c & PIA_IRQ2 )
47
48 #define IRQ1_ENABLED(c) ( c & 0x01 )
49 #define IRQ1_DISABLED(c) !( c & 0x01 )
50 #define C1_LOW_TO_HIGH(c) ( c & 0x02 )
51 #define C1_HIGH_TO_LOW(c) !( c & 0x02 )
52 #define OUTPUT_SELECTED(c) ( c & 0x04 )
53 #define DDR_SELECTED(c) !( c & 0x04 )
54 #define IRQ2_ENABLED(c) ( c & 0x08 )
55 #define IRQ2_DISABLED(c) !( c & 0x08 )
56 #define STROBE_E_RESET(c) ( c & 0x08 )
57 #define STROBE_C1_RESET(c) !( c & 0x08 )
58 #define SET_C2(c) ( c & 0x08 )
59 #define RESET_C2(c) !( c & 0x08 )
60 #define C2_LOW_TO_HIGH(c) ( c & 0x10 )
61 #define C2_HIGH_TO_LOW(c) !( c & 0x10 )
62 #define C2_SET_MODE(c) ( c & 0x10 )
63 #define C2_STROBE_MODE(c) !( c & 0x10 )
64 #define C2_OUTPUT(c) ( c & 0x20 )
65 #define C2_INPUT(c) !( c & 0x20 )
66
67 #define PIA_W_CALLBACK(st, val) \
68 if ( st.func ) st.func( this, st.objTo, 0, val )
69
70 //////////////////////////////////////////////////////////////////////
71
72 C6821::C6821()
73 {
74 Reset();
75 m_stOutA.objTo = NULL;
76 m_stOutA.func = NULL;
77 m_stOutB.objTo = NULL;
78 m_stOutB.func = NULL;
79 m_stOutCA2.objTo = NULL;
80 m_stOutCA2.func = NULL;
81 m_stOutCB2.objTo = NULL;
82 m_stOutCB2.func = NULL;
83 m_stOutIRQA.objTo = NULL;
84 m_stOutIRQA.func = NULL;
85 m_stOutIRQB.objTo = NULL;
86 m_stOutIRQB.func = NULL;
87 }
88
89 C6821::~C6821()
90 {
91
92 }
93
94 void C6821::SetListenerA(void *objTo, mem_write_handler func)
95 {
96 m_stOutA.objTo = objTo;
97 m_stOutA.func = func;
98 }
99
100 void C6821::SetListenerB(void *objTo, mem_write_handler func)
101 {
102 m_stOutB.objTo = objTo;
103 m_stOutB.func = func;
104 }
105
106 void C6821::SetListenerCA2(void *objTo, mem_write_handler func)
107 {
108 m_stOutCA2.objTo = objTo;
109 m_stOutCA2.func = func;
110 }
111
112 void C6821::SetListenerCB2(void *objTo, mem_write_handler func)
113 {
114 m_stOutCB2.objTo = objTo;
115 m_stOutCB2.func = func;
116 }
117
118 BYTE C6821::Read(BYTE byRS)
119 {
120 BYTE retval = 0;
121 byRS &= 3;
122 switch ( byRS )
123 {
124 /******************* port A output/DDR read *******************/
125 case PIA_DDRA:
126 // read output register
127 if ( OUTPUT_SELECTED(m_byCTLA) )
128 {
129 // combine input and output values
130 retval = ( m_byOA & m_byDDRA ) | ( m_byIA & ~m_byDDRA );
131 // IRQ flags implicitly cleared by a read
132 CLEAR_IRQ1( m_byCTLA );
133 CLEAR_IRQ1( m_byCTLB );
134 UpdateInterrupts();
135 // CA2 is configured as output and in read strobe mode
136 if ( C2_OUTPUT(m_byCTLA) && C2_STROBE_MODE(m_byCTLA) )
137 {
138 // this will cause a transition low; call the output function if we're currently high
139 if ( m_byOCA2 )
140 PIA_W_CALLBACK( m_stOutCA2, 0 );
141 m_byOCA2 = 0;
142
143 // if the CA2 strobe is cleared by the E, reset it right away
144 if ( STROBE_E_RESET( m_byCTLA ) )
145 {
146 PIA_W_CALLBACK( m_stOutCA2, 1 );
147 m_byOCA2 = 1;
148 }
149 }
150 }
151 // read DDR register
152 else
153 {
154 retval = m_byDDRA;
155 }
156 break;
157
158 /******************* port B output/DDR read *******************/
159 case PIA_DDRB:
160
161 // read output register
162 if ( OUTPUT_SELECTED( m_byCTLB ) )
163 {
164 // combine input and output values
165 retval = ( m_byOB & m_byDDRB ) + ( m_byIB & ~m_byDDRB );
166
167 // IRQ flags implicitly cleared by a read
168 CLEAR_IRQ2( m_byCTLA );
169 CLEAR_IRQ2( m_byCTLB );
170 UpdateInterrupts();
171 }
172 /* read DDR register */
173 else
174 {
175 retval = m_byDDRB;
176 }
177 break;
178
179 /******************* port A control read *******************/
180 case PIA_CTLA:
181 // read control register
182 retval = m_byCTLA;
183 // when CA2 is an output, IRQA2 = 0, and is not affected by CA2 transitions.
184 if ( C2_OUTPUT( m_byCTLA ) )
185 retval &= ~PIA_IRQ2;
186 break;
187
188 /******************* port B control read *******************/
189 case PIA_CTLB:
190 retval = m_byCTLB;
191 // when CB2 is an output, IRQB2 = 0, and is not affected by CB2 transitions.
192 if ( C2_OUTPUT( m_byCTLB ) )
193 retval &= ~PIA_IRQ2;
194 break;
195
196 }
197
198 return retval;
199 }
200
201 void C6821::Write(BYTE byRS, BYTE byData)
202 {
203 byRS &= 3;
204
205 switch( byRS )
206 {
207 /******************* port A output/DDR write *******************/
208 case PIA_DDRA:
209
210 // write output register
211 if ( OUTPUT_SELECTED( m_byCTLA ) )
212 {
213 // update the output value
214 m_byOA = byData;
215
216 // send it to the output function
217 if ( m_byDDRA )
218 PIA_W_CALLBACK( m_stOutA, m_byOA & m_byDDRA );
219 }
220
221 // write DDR register
222 else
223 {
224 if ( m_byDDRA != byData )
225 {
226 m_byDDRA = byData;
227
228 // send it to the output function
229 if ( m_byDDRA )
230 PIA_W_CALLBACK( m_stOutA, m_byOA & m_byDDRA );
231 }
232 }
233 break;
234
235 /******************* port B output/DDR write *******************/
236 case PIA_DDRB:
237
238 // write output register
239 if ( OUTPUT_SELECTED( m_byCTLB ) )
240 {
241 // update the output value
242 m_byOB = byData;
243
244 // send it to the output function
245 if ( m_byDDRB )
246 PIA_W_CALLBACK( m_stOutB, m_byOB & m_byDDRB );
247
248 // CB2 is configured as output and in write strobe mode
249 if ( C2_OUTPUT( m_byCTLB ) && C2_STROBE_MODE( m_byCTLB ) )
250 {
251 // this will cause a transition low; call the output function if we're currently high
252 if ( m_byOCB2 )
253 PIA_W_CALLBACK( m_stOutCB2, 0 );
254 m_byOCB2 = 0;
255
256 // if the CB2 strobe is cleared by the E, reset it right away
257 if ( STROBE_E_RESET( m_byCTLB ) )
258 {
259 PIA_W_CALLBACK( m_stOutCB2, 1 );
260 m_byOCB2 = 1;
261 }
262 }
263 }
264 // write DDR register
265 else
266 {
267 if ( m_byDDRB != byData )
268 {
269 m_byDDRB = byData;
270
271 // send it to the output function
272 if ( m_byDDRB )
273 PIA_W_CALLBACK( m_stOutB, m_byOB & m_byDDRB );
274 }
275 }
276 break;
277
278 /******************* port A control write *******************/
279 case PIA_CTLA:
280 // Bit 7 and 6 read only
281 byData &= 0x3f;
282
283 // CA2 is configured as output and in set/reset mode
284 if ( C2_OUTPUT( byData ) )
285 {
286 // determine the new value
287 int temp = SET_C2( byData ) ? 1 : 0;
288
289 // if this creates a transition, call the CA2 output function
290 if ( m_byOCA2 ^ temp)
291 PIA_W_CALLBACK( m_stOutCA2, temp );
292
293 // set the new value
294 m_byOCA2 = temp;
295 }
296
297 // update the control register
298 m_byCTLA = ( m_byCTLA & ~0x3F ) | byData;
299
300 // update externals
301 UpdateInterrupts();
302 break;
303
304 /******************* port B control write *******************/
305 case PIA_CTLB:
306
307 /* Bit 7 and 6 read only - PD 16/01/00 */
308
309 byData &= 0x3f;
310
311 // CB2 is configured as output and in set/reset mode
312 if ( C2_OUTPUT( byData ) )
313 {
314 // determine the new value
315 int temp = SET_C2( byData ) ? 1 : 0;
316
317 // if this creates a transition, call the CA2 output function
318 if ( m_byOCB2 ^ temp)
319 PIA_W_CALLBACK( m_stOutCB2, temp );
320
321 // set the new value
322 m_byOCB2 = temp;
323 }
324
325 // update the control register
326 m_byCTLB = ( m_byCTLB & ~0x3F ) | byData;
327
328 // update externals
329 UpdateInterrupts();
330 break;
331 }
332
333 }
334
335 void C6821::Reset()
336 {
337 m_byIA = 0;
338 m_byCA1 = 0;
339 m_byICA2 = 0;
340 m_byOA = 0;
341 m_byOCA2 = 0;
342 m_byDDRA = 0;
343 m_byCTLA = 0;
344 m_byIRQAState = 0;
345
346 m_byIB = 0;
347 m_byCB1 = 0;
348 m_byICB2 = 0;
349 m_byOB = 0;
350 m_byOCB2 = 0;
351 m_byDDRB = 0;
352 m_byCTLB = 0;
353 m_byIRQBState = 0;
354 }
355
356 void C6821::UpdateInterrupts()
357 {
358 BYTE byNewState;
359
360 // start with IRQ A
361 byNewState = 0;
362 if ( ( IRQ1( m_byCTLA ) && IRQ1_ENABLED( m_byCTLA ) ) ||
363 ( IRQ2( m_byCTLA ) && IRQ2_ENABLED( m_byCTLA ) ) )
364 byNewState = 1;
365
366 if ( byNewState != m_byIRQAState )
367 {
368 m_byIRQAState = byNewState;
369 PIA_W_CALLBACK( m_stOutIRQA, m_byIRQAState );
370 }
371
372 /* then do IRQ B */
373 byNewState = 0;
374 if ( ( IRQ1( m_byCTLB ) && IRQ1_ENABLED( m_byCTLB ) ) ||
375 ( IRQ2( m_byCTLB ) && IRQ2_ENABLED( m_byCTLB ) ) )
376 byNewState = 1;
377
378 if ( byNewState != m_byIRQBState )
379 {
380 m_byIRQBState = byNewState;
381 PIA_W_CALLBACK( m_stOutIRQB, m_byIRQBState );
382 }
383 }
384
385 void C6821::SetCA1(BYTE byData)
386 {
387 byData = byData ? 1 : 0;
388
389 // the new state has caused a transition
390 if ( m_byCA1 ^ byData )
391 {
392 // handle the active transition
393 if ( ( byData && C1_LOW_TO_HIGH( m_byCTLA ) ) ||
394 ( !byData && C1_HIGH_TO_LOW( m_byCTLA ) ) )
395 {
396 // mark the IRQ
397 SET_IRQ1(m_byCTLA);
398
399 // update externals
400 UpdateInterrupts();
401
402 // CA2 is configured as output and in read strobe mode and cleared by a CA1 transition
403 if ( C2_OUTPUT( m_byCTLA ) && C2_STROBE_MODE( m_byCTLA ) && STROBE_C1_RESET( m_byCTLA ) )
404 {
405 // call the CA2 output function
406 if ( !m_byOCA2 )
407 PIA_W_CALLBACK( m_stOutCA2, 1 );
408
409 // clear CA2
410 m_byOCA2 = 1;
411 }
412 }
413 }
414
415 // set the new value for CA1
416 m_byCA1 = byData;
417 }
418
419 void C6821::SetCA2(BYTE byData)
420 {
421 byData = byData ? 1 : 0;
422
423 // CA2 is in input mode
424 if ( C2_INPUT( m_byCTLA ) )
425 {
426 // the new state has caused a transition
427 if ( m_byICA2 ^ byData )
428 {
429 // handle the active transition
430 if ( ( byData && C2_LOW_TO_HIGH( m_byCTLA ) ) ||
431 ( !byData && C2_HIGH_TO_LOW( m_byCTLA ) ) )
432 {
433 // mark the IRQ
434 SET_IRQ2( m_byCTLA );
435
436 // update externals
437 UpdateInterrupts();
438 }
439 }
440 }
441
442 // set the new value for CA2
443 m_byICA2 = byData;
444 }
445
446 void C6821::SetCB1(BYTE byData)
447 {
448 byData = byData ? 1 : 0;
449
450 // the new state has caused a transition
451 if ( m_byCB1 ^ byData )
452 {
453 // handle the active transition
454 if ( ( byData && C1_LOW_TO_HIGH( m_byCTLB ) ) ||
455 ( !byData && C1_HIGH_TO_LOW( m_byCTLB ) ) )
456 {
457 // mark the IRQ
458 SET_IRQ1( m_byCTLB );
459
460 // update externals
461 UpdateInterrupts();
462
463 // CB2 is configured as output and in read strobe mode and cleared by a CA1 transition
464 if ( C2_OUTPUT( m_byCTLB ) && C2_STROBE_MODE( m_byCTLB ) && STROBE_C1_RESET( m_byCTLB ) )
465 {
466 // the IRQ1 flag must have also been cleared
467 if ( !IRQ1( m_byCTLB ) )
468 {
469 // call the CB2 output function
470 if ( !m_byOCB2 )
471 PIA_W_CALLBACK( m_stOutCB2, 1 );
472
473 // clear CB2
474 m_byOCB2 = 1;
475 }
476 }
477 }
478 }
479
480 // set the new value for CA1
481 m_byCB1 = byData;
482
483 }
484
485 void C6821::SetCB2(BYTE byData)
486 {
487 byData = byData ? 1 : 0;
488
489 // CA2 is in input mode
490 if ( C2_INPUT( m_byCTLB ) )
491 {
492 // the new state has caused a transition
493 if ( m_byICB2 ^ byData )
494 {
495 // handle the active transition
496 if ( ( byData && C2_LOW_TO_HIGH( m_byCTLB ) ) ||
497 ( !byData && C2_HIGH_TO_LOW( m_byCTLB ) ) )
498 {
499 // mark the IRQ
500 SET_IRQ2( m_byCTLB );
501
502 // update externals
503 UpdateInterrupts();
504 }
505 }
506 }
507
508 // set the new value for CA2
509 m_byICB2 = byData;
510 }
511
512 void C6821::SetPA(BYTE byData)
513 {
514 m_byIA = byData;
515 }
516
517 void C6821::SetPB(BYTE byData)
518 {
519 m_byIB = byData;
520 }
521
522 BYTE C6821::GetPA()
523 {
524 return m_byOA & m_byDDRA;
525 }
526
527 BYTE C6821::GetPB()
528 {
529 return m_byOB & m_byDDRB;
530 }
0 // Motorola MC6821 PIA
1
2 typedef void (*mem_write_handler) (void* objFrom, void* objTo, int nAddr, BYTE byData);
3
4 typedef struct _STWriteHandler
5 {
6 void* objTo;
7 mem_write_handler func;
8 } STWriteHandler;
9
10 //
11
12 #define PIA_DDRA 0
13 #define PIA_CTLA 1
14 #define PIA_DDRB 2
15 #define PIA_CTLB 3
16
17 class C6821
18 {
19 public:
20 C6821();
21 virtual ~C6821();
22
23 BYTE GetPB();
24 BYTE GetPA();
25 void SetPB(BYTE byData);
26 void SetPA(BYTE byData);
27 void SetCA1( BYTE byData );
28 void SetCA2( BYTE byData );
29 void SetCB1( BYTE byData );
30 void SetCB2( BYTE byData );
31 void Reset();
32 BYTE Read( BYTE byRS );
33 void Write( BYTE byRS, BYTE byData );
34
35 void UpdateInterrupts();
36
37 void SetListenerA( void *objTo, mem_write_handler func );
38 void SetListenerB( void *objTo, mem_write_handler func );
39 void SetListenerCA2( void *objTo, mem_write_handler func );
40 void SetListenerCB2( void *objTo, mem_write_handler func );
41
42 protected:
43 BYTE m_byIA;
44 BYTE m_byCA1;
45 BYTE m_byICA2;
46 BYTE m_byOA;
47 BYTE m_byOCA2;
48 BYTE m_byDDRA;
49 BYTE m_byCTLA;
50 BYTE m_byIRQAState;
51
52 BYTE m_byIB;
53 BYTE m_byCB1;
54 BYTE m_byICB2;
55 BYTE m_byOB;
56 BYTE m_byOCB2;
57 BYTE m_byDDRB;
58 BYTE m_byCTLB;
59 BYTE m_byIRQBState;
60
61 STWriteHandler m_stOutA;
62 STWriteHandler m_stOutB;
63 STWriteHandler m_stOutCA2;
64 STWriteHandler m_stOutCB2;
65 STWriteHandler m_stOutIRQA;
66 STWriteHandler m_stOutIRQB;
67 };
0 /***************************************************************************
1
2 ay8910.c
3
4
5 Emulation of the AY-3-8910 / YM2149 sound chip.
6
7 Based on various code snippets by Ville Hallik, Michael Cuddy,
8 Tatsuyuki Satoh, Fabrice Frances, Nicola Salmoria.
9
10 ***************************************************************************/
11
12 //
13 // From mame.txt (http://www.mame.net/readme.html)
14 //
15 // VI. Reuse of Source Code
16 // --------------------------
17 // This chapter might not apply to specific portions of MAME (e.g. CPU
18 // emulators) which bear different copyright notices.
19 // The source code cannot be used in a commercial product without the written
20 // authorization of the authors. Use in non-commercial products is allowed, and
21 // indeed encouraged. If you use portions of the MAME source code in your
22 // program, however, you must make the full source code freely available as
23 // well.
24 // Usage of the _information_ contained in the source code is free for any use.
25 // However, given the amount of time and energy it took to collect this
26 // information, if you find new information we would appreciate if you made it
27 // freely available as well.
28 //
29
30
31 #include "wincompat.h"
32 #include <stdio.h>
33 #include <string.h>
34
35 #include <SDL/SDL.h>
36 //#include <unistd.h>
37 //#include <stdlib.h>
38
39 //#include <crtdbg.h>
40 #include "AY8910.h"
41
42 #include "Common.h"
43 #include "Structs.h"
44 #include "AppleWin.h" // For g_fh
45 #include "Mockingboard.h" // For g_uTimer1IrqCount
46
47 ///////////////////////////////////////////////////////////
48 // typedefs & dummy funcs to allow MAME code to compile:
49
50 typedef UINT8 (*mem_read_handler)(UINT32);
51 typedef void (*mem_write_handler)(UINT32, UINT8);
52
53 static void logerror(char* psz, ...)
54 {
55 }
56
57 static unsigned short activecpu_get_pc()
58 {
59 return 0;
60 }
61
62 //
63 ///////////////////////////////////////////////////////////
64
65 #define MAX_OUTPUT 0x7fff
66
67 // See AY8910_set_clock() for definition of STEP
68 #define STEP 0x8000
69
70
71 static int num = 0, ym_num = 0;
72
73 struct AY8910
74 {
75 int Channel;
76 int SampleRate;
77 mem_read_handler PortAread;
78 mem_read_handler PortBread;
79 mem_write_handler PortAwrite;
80 mem_write_handler PortBwrite;
81 int register_latch;
82 unsigned char Regs[16];
83 int lastEnable;
84 unsigned int UpdateStep;
85 int PeriodA,PeriodB,PeriodC,PeriodN,PeriodE;
86 int CountA,CountB,CountC,CountN,CountE;
87 unsigned int VolA,VolB,VolC,VolE;
88 unsigned char EnvelopeA,EnvelopeB,EnvelopeC;
89 unsigned char OutputA,OutputB,OutputC,OutputN;
90 signed char CountEnv;
91 unsigned char Hold,Alternate,Attack,Holding;
92 int RNG;
93 unsigned int VolTable[32];
94 };
95
96 /* register id's */
97 #define AY_AFINE (0)
98 #define AY_ACOARSE (1)
99 #define AY_BFINE (2)
100 #define AY_BCOARSE (3)
101 #define AY_CFINE (4)
102 #define AY_CCOARSE (5)
103 #define AY_NOISEPER (6)
104 #define AY_ENABLE (7)
105 #define AY_AVOL (8)
106 #define AY_BVOL (9)
107 #define AY_CVOL (10)
108 #define AY_EFINE (11)
109 #define AY_ECOARSE (12)
110 #define AY_ESHAPE (13)
111
112 #define AY_PORTA (14)
113 #define AY_PORTB (15)
114
115
116 static struct AY8910 AYPSG[MAX_8910]; /* array of PSG's */
117
118 static bool g_bAYReset = false; // Doing AY8910_reset()
119
120 //-----------------------------------------------------------------------------
121
122 //#define LOG_AY8910
123 #ifdef LOG_AY8910
124 static void LogAY8910(int n, int r, UINT uFreq)
125 {
126 // TO DO: Determine freq from 6522 timer
127
128 if ((g_fh == NULL) || g_bAYReset)
129 return;
130
131 static UINT nCnt = 0;
132 const UINT nNumAYs = 4; // 1..4
133 if((r == 0))
134 {
135 if(nCnt == 0)
136 {
137 fprintf(g_fh, "Time : ");
138 for(UINT i=0; i<nNumAYs; i++)
139 fprintf(g_fh, "APer BPer CPer NP EN AV BV CV ");
140 fprintf(g_fh, "\n");
141 }
142
143 fprintf(g_fh, "%02d.%02d: ", g_uTimer1IrqCount/uFreq, g_uTimer1IrqCount%uFreq);
144
145 for(int j=0; j<n*(3*5+5*3+1); j++)
146 fprintf(g_fh, " ");
147
148 UINT i=n;
149 {
150 UCHAR* pAYRegs = &AYPSG[i].Regs[0];
151 fprintf(g_fh, "%04X ", *(USHORT*)&pAYRegs[AY_AFINE]);
152 fprintf(g_fh, "%04X ", *(USHORT*)&pAYRegs[AY_BFINE]);
153 fprintf(g_fh, "%04X ", *(USHORT*)&pAYRegs[AY_CFINE]);
154 fprintf(g_fh, "%02X ", pAYRegs[AY_NOISEPER]);
155 fprintf(g_fh, "%02X ", pAYRegs[AY_ENABLE]);
156 fprintf(g_fh, "%02X ", pAYRegs[AY_AVOL]);
157 fprintf(g_fh, "%02X ", pAYRegs[AY_BVOL]);
158 fprintf(g_fh, "%02X ", pAYRegs[AY_CVOL]);
159 }
160 fprintf(g_fh, "\n");
161
162 nCnt++;
163 }
164 }
165 #endif
166
167 //-----------------------------------------------------------------------------
168
169 void _AYWriteReg(int n, int r, int v)
170 {
171 struct AY8910 *PSG = &AYPSG[n];
172 int old;
173
174
175 PSG->Regs[r] = v;
176
177 #ifdef LOG_AY8910
178 LogAY8910(n, r, 60);
179 #endif
180
181 /* A note about the period of tones, noise and envelope: for speed reasons,*/
182 /* we count down from the period to 0, but careful studies of the chip */
183 /* output prove that it instead counts up from 0 until the counter becomes */
184 /* greater or equal to the period. This is an important difference when the*/
185 /* program is rapidly changing the period to modulate the sound. */
186 /* To compensate for the difference, when the period is changed we adjust */
187 /* our internal counter. */
188 /* Also, note that period = 0 is the same as period = 1. This is mentioned */
189 /* in the YM2203 data sheets. However, this does NOT apply to the Envelope */
190 /* period. In that case, period = 0 is half as period = 1. */
191 switch( r )
192 {
193 case AY_AFINE:
194 case AY_ACOARSE:
195 PSG->Regs[AY_ACOARSE] &= 0x0f;
196 old = PSG->PeriodA;
197 PSG->PeriodA = (PSG->Regs[AY_AFINE] + 256 * PSG->Regs[AY_ACOARSE]) * PSG->UpdateStep;
198 if (PSG->PeriodA == 0) PSG->PeriodA = PSG->UpdateStep;
199 PSG->CountA += PSG->PeriodA - old;
200 if (PSG->CountA <= 0) PSG->CountA = 1;
201 break;
202 case AY_BFINE:
203 case AY_BCOARSE:
204 PSG->Regs[AY_BCOARSE] &= 0x0f;
205 old = PSG->PeriodB;
206 PSG->PeriodB = (PSG->Regs[AY_BFINE] + 256 * PSG->Regs[AY_BCOARSE]) * PSG->UpdateStep;
207 if (PSG->PeriodB == 0) PSG->PeriodB = PSG->UpdateStep;
208 PSG->CountB += PSG->PeriodB - old;
209 if (PSG->CountB <= 0) PSG->CountB = 1;
210 break;
211 case AY_CFINE:
212 case AY_CCOARSE:
213 PSG->Regs[AY_CCOARSE] &= 0x0f;
214 old = PSG->PeriodC;
215 PSG->PeriodC = (PSG->Regs[AY_CFINE] + 256 * PSG->Regs[AY_CCOARSE]) * PSG->UpdateStep;
216 if (PSG->PeriodC == 0) PSG->PeriodC = PSG->UpdateStep;
217 PSG->CountC += PSG->PeriodC - old;
218 if (PSG->CountC <= 0) PSG->CountC = 1;
219 break;
220 case AY_NOISEPER:
221 PSG->Regs[AY_NOISEPER] &= 0x1f;
222 old = PSG->PeriodN;
223 PSG->PeriodN = PSG->Regs[AY_NOISEPER] * PSG->UpdateStep;
224 if (PSG->PeriodN == 0) PSG->PeriodN = PSG->UpdateStep;
225 PSG->CountN += PSG->PeriodN - old;
226 if (PSG->CountN <= 0) PSG->CountN = 1;
227 break;
228 case AY_ENABLE:
229 if ((PSG->lastEnable == -1) ||
230 ((PSG->lastEnable & 0x40) != (PSG->Regs[AY_ENABLE] & 0x40)))
231 {
232 /* write out 0xff if port set to input */
233 if (PSG->PortAwrite)
234 (*PSG->PortAwrite)(0, (UINT8) ((PSG->Regs[AY_ENABLE] & 0x40) ? PSG->Regs[AY_PORTA] : 0xff)); // [TC: UINT8 cast]
235 }
236
237 if ((PSG->lastEnable == -1) ||
238 ((PSG->lastEnable & 0x80) != (PSG->Regs[AY_ENABLE] & 0x80)))
239 {
240 /* write out 0xff if port set to input */
241 if (PSG->PortBwrite)
242 (*PSG->PortBwrite)(0, (UINT8) ((PSG->Regs[AY_ENABLE] & 0x80) ? PSG->Regs[AY_PORTB] : 0xff)); // [TC: UINT8 cast]
243 }
244
245 PSG->lastEnable = PSG->Regs[AY_ENABLE];
246 break;
247 case AY_AVOL:
248 PSG->Regs[AY_AVOL] &= 0x1f;
249 PSG->EnvelopeA = PSG->Regs[AY_AVOL] & 0x10;
250 PSG->VolA = PSG->EnvelopeA ? PSG->VolE : PSG->VolTable[PSG->Regs[AY_AVOL] ? PSG->Regs[AY_AVOL]*2+1 : 0];
251 break;
252 case AY_BVOL:
253 PSG->Regs[AY_BVOL] &= 0x1f;
254 PSG->EnvelopeB = PSG->Regs[AY_BVOL] & 0x10;
255 PSG->VolB = PSG->EnvelopeB ? PSG->VolE : PSG->VolTable[PSG->Regs[AY_BVOL] ? PSG->Regs[AY_BVOL]*2+1 : 0];
256 break;
257 case AY_CVOL:
258 PSG->Regs[AY_CVOL] &= 0x1f;
259 PSG->EnvelopeC = PSG->Regs[AY_CVOL] & 0x10;
260 PSG->VolC = PSG->EnvelopeC ? PSG->VolE : PSG->VolTable[PSG->Regs[AY_CVOL] ? PSG->Regs[AY_CVOL]*2+1 : 0];
261 break;
262 case AY_EFINE:
263 case AY_ECOARSE:
264 // _ASSERT((PSG->Regs[AY_EFINE] == 0) && (PSG->Regs[AY_ECOARSE] == 0));
265 old = PSG->PeriodE;
266 PSG->PeriodE = ((PSG->Regs[AY_EFINE] + 256 * PSG->Regs[AY_ECOARSE])) * PSG->UpdateStep;
267 if (PSG->PeriodE == 0) PSG->PeriodE = PSG->UpdateStep / 2;
268 PSG->CountE += PSG->PeriodE - old;
269 if (PSG->CountE <= 0) PSG->CountE = 1;
270 break;
271 case AY_ESHAPE:
272 // _ASSERT(PSG->Regs[AY_ESHAPE] == 0);
273 /* envelope shapes:
274 C AtAlH
275 0 0 x x \___
276
277 0 1 x x /___
278
279 1 0 0 0 \\\\
280
281 1 0 0 1 \___
282
283 1 0 1 0 \/\/
284 ___
285 1 0 1 1 \
286
287 1 1 0 0 ////
288 ___
289 1 1 0 1 /
290
291 1 1 1 0 /\/\
292
293 1 1 1 1 /___
294
295 The envelope counter on the AY-3-8910 has 16 steps. On the YM2149 it
296 has twice the steps, happening twice as fast. Since the end result is
297 just a smoother curve, we always use the YM2149 behaviour.
298 */
299 PSG->Regs[AY_ESHAPE] &= 0x0f;
300 PSG->Attack = (PSG->Regs[AY_ESHAPE] & 0x04) ? 0x1f : 0x00;
301 if ((PSG->Regs[AY_ESHAPE] & 0x08) == 0)
302 {
303 /* if Continue = 0, map the shape to the equivalent one which has Continue = 1 */
304 PSG->Hold = 1;
305 PSG->Alternate = PSG->Attack;
306 }
307 else
308 {
309 PSG->Hold = PSG->Regs[AY_ESHAPE] & 0x01;
310 PSG->Alternate = PSG->Regs[AY_ESHAPE] & 0x02;
311 }
312 PSG->CountE = PSG->PeriodE;
313 PSG->CountEnv = 0x1f;
314 PSG->Holding = 0;
315 PSG->VolE = PSG->VolTable[PSG->CountEnv ^ PSG->Attack];
316 if (PSG->EnvelopeA) PSG->VolA = PSG->VolE;
317 if (PSG->EnvelopeB) PSG->VolB = PSG->VolE;
318 if (PSG->EnvelopeC) PSG->VolC = PSG->VolE;
319 break;
320 case AY_PORTA:
321 if (PSG->Regs[AY_ENABLE] & 0x40)
322 {
323 if (PSG->PortAwrite)
324 (*PSG->PortAwrite)(0, PSG->Regs[AY_PORTA]);
325 else
326 logerror("PC %04x: warning - write %02x to 8910 #%d Port A\n",activecpu_get_pc(),PSG->Regs[AY_PORTA],n);
327 }
328 else
329 {
330 logerror("warning: write to 8910 #%d Port A set as input - ignored\n",n);
331 }
332 break;
333 case AY_PORTB:
334 if (PSG->Regs[AY_ENABLE] & 0x80)
335 {
336 if (PSG->PortBwrite)
337 (*PSG->PortBwrite)(0, PSG->Regs[AY_PORTB]);
338 else
339 logerror("PC %04x: warning - write %02x to 8910 #%d Port B\n",activecpu_get_pc(),PSG->Regs[AY_PORTB],n);
340 }
341 else
342 {
343 logerror("warning: write to 8910 #%d Port B set as input - ignored\n",n);
344 }
345 break;
346 }
347 }
348
349
350 // /length/ is the number of samples we require
351 // NB. This should be called at twice the 6522 IRQ rate or (eg) 60Hz if no IRQ.
352 void AY8910Update(int chip,INT16 **buffer,int length) // [TC: Removed static]
353 {
354 struct AY8910 *PSG = &AYPSG[chip];
355 INT16 *buf1,*buf2,*buf3;
356 int outn;
357
358 buf1 = buffer[0];
359 buf2 = buffer[1];
360 buf3 = buffer[2];
361
362
363 /* The 8910 has three outputs, each output is the mix of one of the three */
364 /* tone generators and of the (single) noise generator. The two are mixed */
365 /* BEFORE going into the DAC. The formula to mix each channel is: */
366 /* (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable). */
367 /* Note that this means that if both tone and noise are disabled, the output */
368 /* is 1, not 0, and can be modulated changing the volume. */
369
370
371 /* If the channels are disabled, set their output to 1, and increase the */
372 /* counter, if necessary, so they will not be inverted during this update. */
373 /* Setting the output to 1 is necessary because a disabled channel is locked */
374 /* into the ON state (see above); and it has no effect if the volume is 0. */
375 /* If the volume is 0, increase the counter, but don't touch the output. */
376 if (PSG->Regs[AY_ENABLE] & 0x01)
377 {
378 if (PSG->CountA <= length*STEP) PSG->CountA += length*STEP;
379 PSG->OutputA = 1;
380 }
381 else if (PSG->Regs[AY_AVOL] == 0)
382 {
383 /* note that I do count += length, NOT count = length + 1. You might think */
384 /* it's the same since the volume is 0, but doing the latter could cause */
385 /* interferencies when the program is rapidly modulating the volume. */
386 if (PSG->CountA <= length*STEP) PSG->CountA += length*STEP;
387 }
388 if (PSG->Regs[AY_ENABLE] & 0x02)
389 {
390 if (PSG->CountB <= length*STEP) PSG->CountB += length*STEP;
391 PSG->OutputB = 1;
392 }
393 else if (PSG->Regs[AY_BVOL] == 0)
394 {
395 if (PSG->CountB <= length*STEP) PSG->CountB += length*STEP;
396 }
397 if (PSG->Regs[AY_ENABLE] & 0x04)
398 {
399 if (PSG->CountC <= length*STEP) PSG->CountC += length*STEP;
400 PSG->OutputC = 1;
401 }
402 else if (PSG->Regs[AY_CVOL] == 0)
403 {
404 if (PSG->CountC <= length*STEP) PSG->CountC += length*STEP;
405 }
406
407 /* for the noise channel we must not touch OutputN - it's also not necessary */
408 /* since we use outn. */
409 if ((PSG->Regs[AY_ENABLE] & 0x38) == 0x38) /* all off */
410 if (PSG->CountN <= length*STEP) PSG->CountN += length*STEP;
411
412 outn = (PSG->OutputN | PSG->Regs[AY_ENABLE]);
413
414
415 /* buffering loop */
416 while (length)
417 {
418 int vola,volb,volc;
419 int left;
420
421
422 /* vola, volb and volc keep track of how long each square wave stays */
423 /* in the 1 position during the sample period. */
424 vola = volb = volc = 0;
425
426 left = STEP;
427 do
428 {
429 int nextevent;
430
431
432 if (PSG->CountN < left) nextevent = PSG->CountN;
433 else nextevent = left;
434
435 if (outn & 0x08)
436 {
437 if (PSG->OutputA) vola += PSG->CountA;
438 PSG->CountA -= nextevent;
439 /* PeriodA is the half period of the square wave. Here, in each */
440 /* loop I add PeriodA twice, so that at the end of the loop the */
441 /* square wave is in the same status (0 or 1) it was at the start. */
442 /* vola is also incremented by PeriodA, since the wave has been 1 */
443 /* exactly half of the time, regardless of the initial position. */
444 /* If we exit the loop in the middle, OutputA has to be inverted */
445 /* and vola incremented only if the exit status of the square */
446 /* wave is 1. */
447 while (PSG->CountA <= 0)
448 {
449 PSG->CountA += PSG->PeriodA;
450 if (PSG->CountA > 0)
451 {
452 PSG->OutputA ^= 1;
453 if (PSG->OutputA) vola += PSG->PeriodA;
454 break;
455 }
456 PSG->CountA += PSG->PeriodA;
457 vola += PSG->PeriodA;
458 }
459 if (PSG->OutputA) vola -= PSG->CountA;
460 }
461 else
462 {
463 PSG->CountA -= nextevent;
464 while (PSG->CountA <= 0)
465 {
466 PSG->CountA += PSG->PeriodA;
467 if (PSG->CountA > 0)
468 {
469 PSG->OutputA ^= 1;
470 break;
471 }
472 PSG->CountA += PSG->PeriodA;
473 }
474 }
475
476 if (outn & 0x10)
477 {
478 if (PSG->OutputB) volb += PSG->CountB;
479 PSG->CountB -= nextevent;
480 while (PSG->CountB <= 0)
481 {
482 PSG->CountB += PSG->PeriodB;
483 if (PSG->CountB > 0)
484 {
485 PSG->OutputB ^= 1;
486 if (PSG->OutputB) volb += PSG->PeriodB;
487 break;
488 }
489 PSG->CountB += PSG->PeriodB;
490 volb += PSG->PeriodB;
491 }
492 if (PSG->OutputB) volb -= PSG->CountB;
493 }
494 else
495 {
496 PSG->CountB -= nextevent;
497 while (PSG->CountB <= 0)
498 {
499 PSG->CountB += PSG->PeriodB;
500 if (PSG->CountB > 0)
501 {
502 PSG->OutputB ^= 1;
503 break;
504 }
505 PSG->CountB += PSG->PeriodB;
506 }
507 }
508
509 if (outn & 0x20)
510 {
511 if (PSG->OutputC) volc += PSG->CountC;
512 PSG->CountC -= nextevent;
513 while (PSG->CountC <= 0)
514 {
515 PSG->CountC += PSG->PeriodC;
516 if (PSG->CountC > 0)
517 {
518 PSG->OutputC ^= 1;
519 if (PSG->OutputC) volc += PSG->PeriodC;
520 break;
521 }
522 PSG->CountC += PSG->PeriodC;
523 volc += PSG->PeriodC;
524 }
525 if (PSG->OutputC) volc -= PSG->CountC;
526 }
527 else
528 {
529 PSG->CountC -= nextevent;
530 while (PSG->CountC <= 0)
531 {
532 PSG->CountC += PSG->PeriodC;
533 if (PSG->CountC > 0)
534 {
535 PSG->OutputC ^= 1;
536 break;
537 }
538 PSG->CountC += PSG->PeriodC;
539 }
540 }
541
542 PSG->CountN -= nextevent;
543 if (PSG->CountN <= 0)
544 {
545 /* Is noise output going to change? */
546 if ((PSG->RNG + 1) & 2) /* (bit0^bit1)? */
547 {
548 PSG->OutputN = ~PSG->OutputN;
549 outn = (PSG->OutputN | PSG->Regs[AY_ENABLE]);
550 }
551
552 /* The Random Number Generator of the 8910 is a 17-bit shift */
553 /* register. The input to the shift register is bit0 XOR bit3 */
554 /* (bit0 is the output). This was verified on AY-3-8910 and YM2149 chips. */
555
556 /* The following is a fast way to compute bit17 = bit0^bit3. */
557 /* Instead of doing all the logic operations, we only check */
558 /* bit0, relying on the fact that after three shifts of the */
559 /* register, what now is bit3 will become bit0, and will */
560 /* invert, if necessary, bit14, which previously was bit17. */
561 if (PSG->RNG & 1) PSG->RNG ^= 0x24000; /* This version is called the "Galois configuration". */
562 PSG->RNG >>= 1;
563 PSG->CountN += PSG->PeriodN;
564 }
565
566 left -= nextevent;
567 } while (left > 0);
568
569 /* update envelope */
570 if (PSG->Holding == 0)
571 {
572 PSG->CountE -= STEP;
573 if (PSG->CountE <= 0)
574 {
575 do
576 {
577 PSG->CountEnv--;
578 PSG->CountE += PSG->PeriodE;
579 } while (PSG->CountE <= 0);
580
581 /* check envelope current position */
582 if (PSG->CountEnv < 0)
583 {
584 if (PSG->Hold)
585 {
586 if (PSG->Alternate)
587 PSG->Attack ^= 0x1f;
588 PSG->Holding = 1;
589 PSG->CountEnv = 0;
590 }
591 else
592 {
593 /* if CountEnv has looped an odd number of times (usually 1), */
594 /* invert the output. */
595 if (PSG->Alternate && (PSG->CountEnv & 0x20))
596 PSG->Attack ^= 0x1f;
597
598 PSG->CountEnv &= 0x1f;
599 }
600 }
601
602 PSG->VolE = PSG->VolTable[PSG->CountEnv ^ PSG->Attack];
603 /* reload volume */
604 if (PSG->EnvelopeA) PSG->VolA = PSG->VolE;
605 if (PSG->EnvelopeB) PSG->VolB = PSG->VolE;
606 if (PSG->EnvelopeC) PSG->VolC = PSG->VolE;
607 }
608 }
609
610 #if 0
611 *(buf1++) = (vola * PSG->VolA) / STEP;
612 *(buf2++) = (volb * PSG->VolB) / STEP;
613 *(buf3++) = (volc * PSG->VolC) / STEP;
614 #else
615 // Output PCM wave [-32768...32767] instead of MAME's voltage level [0...32767]
616 // - This allows for better s/w mixing
617
618 if(PSG->VolA)
619 {
620 if(vola)
621 *(buf1++) = (vola * PSG->VolA) / STEP;
622 else
623 *(buf1++) = - (int) PSG->VolA;
624 }
625 else
626 {
627 *(buf1++) = 0;
628 }
629
630 //
631
632 if(PSG->VolB)
633 {
634 if(volb)
635 *(buf2++) = (volb * PSG->VolB) / STEP;
636 else
637 *(buf2++) = - (int) PSG->VolB;
638 }
639 else
640 {
641 *(buf2++) = 0;
642 }
643
644 //
645
646 if(PSG->VolC)
647 {
648 if(volc)
649 *(buf3++) = (volc * PSG->VolC) / STEP;
650 else
651 *(buf3++) = - (int) PSG->VolC;
652 }
653 else
654 {
655 *(buf3++) = 0;
656 }
657 #endif
658
659 length--;
660 }
661 }
662
663
664 static void AY8910_set_clock(int chip,int clock)
665 {
666 struct AY8910 *PSG = &AYPSG[chip];
667
668 /* the step clock for the tone and noise generators is the chip clock */
669 /* divided by 8; for the envelope generator of the AY-3-8910, it is half */
670 /* that much (clock/16), but the envelope of the YM2149 goes twice as */
671 /* fast, therefore again clock/8. */
672 /* Here we calculate the number of steps which happen during one sample */
673 /* at the given sample rate. No. of events = sample rate / (clock/8). */
674 /* STEP is a multiplier used to turn the fraction into a fixed point */
675 /* number. */
676 PSG->UpdateStep = (unsigned int) (((double)STEP * PSG->SampleRate * 8 + clock/2) / clock); // [TC: unsigned int cast]
677 }
678
679
680 static void build_mixer_table(int chip)
681 {
682 struct AY8910 *PSG = &AYPSG[chip];
683 int i;
684 double out;
685
686
687 /* calculate the volume->voltage conversion table */
688 /* The AY-3-8910 has 16 levels, in a logarithmic scale (3dB per step) */
689 /* The YM2149 still has 16 levels for the tone generators, but 32 for */
690 /* the envelope generator (1.5dB per step). */
691 out = MAX_OUTPUT;
692 for (i = 31;i > 0;i--)
693 {
694 PSG->VolTable[i] = (unsigned int) (out + 0.5); /* round to nearest */ // [TC: unsigned int cast]
695
696 out /= 1.188502227; /* = 10 ^ (1.5/20) = 1.5dB */
697 }
698 PSG->VolTable[0] = 0;
699 }
700
701
702 #if 0
703 void ay8910_write_ym(int chip, int addr, int data)
704 {
705 struct AY8910 *PSG = &AYPSG[chip];
706
707 // if (addr & 1)
708 // { /* Data port */
709 // int r = PSG->register_latch;
710 int r = addr;
711
712 if (r > 15) return;
713 if (r < 14)
714 {
715 if (r == AY_ESHAPE || PSG->Regs[r] != data)
716 {
717 /* update the output buffer before changing the register */
718 // stream_update(PSG->Channel,0);
719 AY8910Update(chip, INT16 **buffer, int length)
720 }
721 }
722
723 _AYWriteReg(PSG,r,data);
724 }
725 // else
726 // { /* Register port */
727 // PSG->register_latch = data & 0x0f;
728 // }
729 }
730 #endif
731
732
733 void AY8910_reset(int chip)
734 {
735 g_bAYReset = true;
736
737 int i;
738 struct AY8910 *PSG = &AYPSG[chip];
739
740 PSG->register_latch = 0;
741 PSG->RNG = 1;
742 PSG->OutputA = 0;
743 PSG->OutputB = 0;
744 PSG->OutputC = 0;
745 PSG->OutputN = 0xff;
746 PSG->lastEnable = -1; /* force a write */
747 for (i = 0;i < AY_PORTA;i++)
748 _AYWriteReg(chip,i,0); /* AYWriteReg() uses the timer system; we cannot */
749 /* call it at this time because the timer system */
750 /* has not been initialized. */
751
752 g_bAYReset = false;
753 }
754
755 //-------------------------------------
756
757 void AY8910_InitAll(int nClock, int nSampleRate)
758 {
759 for(int nChip=0; nChip<MAX_8910; nChip++)
760 {
761 struct AY8910 *PSG = &AYPSG[nChip];
762
763 memset(PSG,0,sizeof(struct AY8910));
764 PSG->SampleRate = nSampleRate;
765
766 PSG->PortAread = NULL;
767 PSG->PortBread = NULL;
768 PSG->PortAwrite = NULL;
769 PSG->PortBwrite = NULL;
770
771 AY8910_set_clock(nChip, nClock);
772
773 build_mixer_table(nChip);
774 }
775 }
776
777 //-------------------------------------
778
779 void AY8910_InitClock(int nClock)
780 {
781 for(int nChip=0; nChip<MAX_8910; nChip++)
782 {
783 AY8910_set_clock(nChip, nClock);
784 }
785 }
786
787 //-------------------------------------
788
789 BYTE* AY8910_GetRegsPtr(UINT nAyNum)
790 {
791 if(nAyNum >= MAX_8910)
792 return NULL;
793
794 return &AYPSG[nAyNum].Regs[0];
795 }
0 #ifndef AY8910_H
1 #define AY8910_H
2
3 #define MAX_8910 4
4
5 void _AYWriteReg(int n, int r, int v);
6 void AY8910_write_ym(int chip, int addr, int data);
7 void AY8910_reset(int chip);
8 void AY8910Update(int chip,INT16 **buffer,int length);
9
10 void AY8910_InitAll(int nClock, int nSampleRate);
11 void AY8910_InitClock(int nClock);
12 BYTE* AY8910_GetRegsPtr(UINT nAyNum);
13
14 #endif
0 #pragma once
1
2 #ifdef _WIN32
3 #define FILE_SEPARATOR TEXT('\\')
4 #else
5 #define FILE_SEPARATOR TEXT('/')
6 #endif
7
8 #define FTP_SEPARATOR TEXT('/')
9
10 // let it be our second version!
11 #define LINAPPLE_VERSION 2
12
13 #include <curl/curl.h>
14
15 extern FILE * spMono,*spStereo;
16
17 extern char VERSIONSTRING[]; // Contructed in WinMain()
18
19 extern TCHAR *g_pAppTitle;
20
21 extern eApple2Type g_Apple2Type;
22
23 extern BOOL behind;
24 extern DWORD cumulativecycles;
25 extern DWORD cyclenum;
26 extern DWORD emulmsec;
27 extern bool g_bFullSpeed;
28
29 // Win32
30 //extern HINSTANCE g_hInstance;
31
32
33 extern AppMode_e g_nAppMode;
34
35 extern UINT g_ScreenWidth;
36 extern UINT g_ScreenHeight;
37
38 extern DWORD needsprecision;
39 //extern TCHAR g_sProgramDir[MAX_PATH];
40 extern TCHAR g_sCurrentDir[MAX_PATH];
41 extern TCHAR g_sHDDDir[MAX_PATH];
42 extern TCHAR g_sSaveStateDir[MAX_PATH];
43 extern TCHAR g_sParallelPrinterFile[MAX_PATH];
44 // FTP vars
45 extern TCHAR g_sFTPLocalDir[MAX_PATH]; // FTP Local Dir, see linapple.conf for details
46 extern TCHAR g_sFTPServer[MAX_PATH]; // full path to default FTP server
47 extern TCHAR g_sFTPServerHDD[MAX_PATH]; // full path to default FTP server
48
49 //extern TCHAR g_sFTPUser[256]; // user name
50 //extern TCHAR g_sFTPPass[256]; // password
51 extern TCHAR g_sFTPUserPass[512]; // full login line
52
53 extern CURL * g_curl;
54
55
56 extern bool g_bResetTiming;
57 extern BOOL restart;
58
59 extern DWORD g_dwSpeed;
60 extern double g_fCurrentCLK6502;
61
62 extern int g_nCpuCyclesFeedback;
63 extern DWORD g_dwCyclesThisFrame;
64
65 extern FILE* g_fh; // Filehandle for log file
66 extern bool g_bDisableDirectSound; // Cmd line switch: don't init DS (so no MB support)
67
68 extern UINT g_Slot4; // Mockingboard or Mouse in slot4
69
70 void SetCurrentCLK6502();
0 /*
1 AppleWin : An Apple //e emulator for Windows
2
3 Copyright (C) 1994-1996, Michael O'Brien
4 Copyright (C) 1999-2001, Oliver Schmidt
5 Copyright (C) 2002-2005, Tom Charlesworth
6 Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski
7
8 AppleWin is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 AppleWin is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with AppleWin; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 /* Description: main
24 *
25 * Author: Various
26 */
27
28 /* Adaptation for SDL and POSIX (l) by beom beotiger, Nov-Dec 2007, krez beotiger March 2012 AD */
29
30 #include "stdafx.h"
31 //#pragma hdrstop
32 #include "MouseInterface.h"
33
34 // for time logging
35 #include <time.h>
36 #include <sys/time.h>
37
38 #include <curl/curl.h>
39
40 #include <stdlib.h>
41
42 //char VERSIONSTRING[] = "xx.yy.zz.ww";
43
44 TCHAR *g_pAppTitle = TITLE_APPLE_2E_ENHANCED;
45
46 eApple2Type g_Apple2Type = A2TYPE_APPLE2EEHANCED;
47
48 BOOL behind = 0; // Redundant
49 DWORD cumulativecycles = 0; // Wraps after ~1hr 9mins
50 DWORD cyclenum = 0; // Used by SpkrToggle() for non-wave sound
51 DWORD emulmsec = 0;
52 static DWORD emulmsec_frac = 0;
53 bool g_bFullSpeed = false;
54 bool hddenabled = false;
55 static bool g_uMouseInSlot4 = false; // not any mouse in slot4??--bb
56 // Win32
57 //HINSTANCE g_hInstance = (HINSTANCE)0;
58
59 AppMode_e g_nAppMode = MODE_LOGO;
60
61 // Default screen sizes
62 // SCREEN_WIDTH & SCREEN_HEIGHT defined in Frame.h
63 UINT g_ScreenWidth = SCREEN_WIDTH;
64 UINT g_ScreenHeight = SCREEN_HEIGHT;
65
66 //static int lastmode = MODE_LOGO; -- not used???
67 DWORD needsprecision = 0; // Redundant
68 //TCHAR g_sProgramDir[MAX_PATH] = TEXT("");
69 TCHAR g_sCurrentDir[MAX_PATH] = TEXT(""); // Also Starting Dir for Slot6 disk images?? --bb
70 TCHAR g_sHDDDir[MAX_PATH] = TEXT(""); // starting dir for HDV (Apple][ HDD) images?? --bb
71 TCHAR g_sSaveStateDir[MAX_PATH] = TEXT(""); // starting dir for states --bb
72 TCHAR g_sParallelPrinterFile[MAX_PATH] = TEXT("Printer.txt"); // default file name for Parallel printer
73
74 // FTP Variables
75 TCHAR g_sFTPLocalDir[MAX_PATH] = TEXT(""); // FTP Local Dir, see linapple.conf for details
76 TCHAR g_sFTPServer[MAX_PATH] = TEXT(""); // full path to default FTP server
77 TCHAR g_sFTPServerHDD[MAX_PATH] = TEXT(""); // full path to default FTP server
78
79 //TCHAR g_sFTPUser[256] = TEXT("anonymous"); // user name
80 //TCHAR g_sFTPPass[256] = TEXT("mymail@hotmail.com"); // password
81 TCHAR g_sFTPUserPass[512] = TEXT("anonymous:mymail@hotmail.com"); // full login line
82
83 bool g_bResetTiming = false; // Redundant
84 BOOL restart = 0;
85
86 // several parameters affecting the speed of emulated CPU
87 DWORD g_dwSpeed = SPEED_NORMAL; // Affected by Config dialog's speed slider bar
88 double g_fCurrentCLK6502 = CLK_6502; // Affected by Config dialog's speed slider bar
89 static double g_fMHz = 1.0; // Affected by Config dialog's speed slider bar
90
91 int g_nCpuCyclesFeedback = 0;
92 DWORD g_dwCyclesThisFrame = 0;
93
94 FILE* g_fh = NULL; // file for logging, let's use stderr instead?
95 bool g_bDisableDirectSound = false; // direct sound, use SDL Sound, or SDL_mixer???
96
97 CSuperSerialCard sg_SSC;
98 CMouseInterface sg_Mouse;
99
100 UINT g_Slot4 = CT_Mockingboard; // CT_Mockingboard or CT_MouseInterface
101
102 CURL *g_curl = NULL; // global easy curl resourse
103 //===========================================================================
104
105 // ???? what is DBG_CALC_FREQ??? O_O --bb
106 #define DBG_CALC_FREQ 0
107 #if DBG_CALC_FREQ
108 const UINT MAX_CNT = 256;
109 double g_fDbg[MAX_CNT];
110 UINT g_nIdx = 0;
111 double g_fMeanPeriod,g_fMeanFreq;
112 ULONG g_nPerfFreq = 0;
113 #endif
114
115
116
117 //---------------------------------------------------------------------------
118
119 void ContinueExecution()
120 {
121 static BOOL pageflipping = 0; //?
122
123 const double fUsecPerSec = 1.e6;
124
125 const UINT nExecutionPeriodUsec = 1000; // 1.0ms
126 const double fExecutionPeriodClks = g_fCurrentCLK6502 * ((double)nExecutionPeriodUsec / fUsecPerSec);
127
128 bool bScrollLock_FullSpeed = g_bScrollLock_FullSpeed; //g_uScrollLockToggle;
129
130 g_bFullSpeed = ( (g_dwSpeed == SPEED_MAX) ||
131 bScrollLock_FullSpeed ||
132 (DiskIsSpinning() && enhancedisk && !Spkr_IsActive() && !MB_IsActive()) );
133
134 if(g_bFullSpeed)
135 {
136 // Don't call Spkr_Mute() - will get speaker clicks
137 MB_Mute();
138 SysClk_StopTimer();
139 g_nCpuCyclesFeedback = 0; // For the case when this is a big -ve number
140 // SetPriorityNormal();
141 }
142 else
143 {
144 // Don't call Spkr_Demute()
145 MB_Demute();
146 SysClk_StartTimerUsec(nExecutionPeriodUsec);
147 // Switch to higher priority, eg. for audio (BUG #015394)
148 // SetPriorityAboveNormal();
149 }
150
151 //
152
153 int nCyclesToExecute = (int) fExecutionPeriodClks + g_nCpuCyclesFeedback;
154 if(nCyclesToExecute < 0)
155 nCyclesToExecute = 0;
156
157 DWORD dwExecutedCycles = CpuExecute(nCyclesToExecute);
158 g_dwCyclesThisFrame += dwExecutedCycles;
159
160 //
161
162 cyclenum = dwExecutedCycles;
163
164 DiskUpdatePosition(dwExecutedCycles);
165 JoyUpdatePosition();
166 // the next call does not present in current Applewin as on March 2012??
167 VideoUpdateVbl(g_dwCyclesThisFrame);
168
169 SpkrUpdate(cyclenum);
170 sg_SSC.CommUpdate(cyclenum);
171 PrintUpdate(cyclenum);
172
173 //
174
175 const DWORD CLKS_PER_MS = (DWORD)g_fCurrentCLK6502 / 1000;
176
177 emulmsec_frac += dwExecutedCycles;
178 if(emulmsec_frac > CLKS_PER_MS)
179 {
180 emulmsec += emulmsec_frac / CLKS_PER_MS;
181 emulmsec_frac %= CLKS_PER_MS;
182 }
183
184 //
185 // DETERMINE WHETHER THE SCREEN WAS UPDATED, THE DISK WAS SPINNING,
186 // OR THE KEYBOARD I/O PORTS WERE BEING EXCESSIVELY QUERIED THIS CLOCKTICK
187 VideoCheckPage(0);
188 BOOL screenupdated = VideoHasRefreshed();
189 BOOL systemidle = 0; //(KeybGetNumQueries() > (clockgran << 2)); // && (!ranfinegrain); // TO DO
190
191 if(screenupdated)
192 pageflipping = 3;
193
194 //
195
196 if(g_dwCyclesThisFrame >= dwClksPerFrame)
197 {
198 g_dwCyclesThisFrame -= dwClksPerFrame;
199
200 if(g_nAppMode != MODE_LOGO)
201 {
202 VideoUpdateFlash();
203
204 static BOOL anyupdates = 0;
205 static DWORD lastcycles = 0;
206 static BOOL lastupdates[2] = {0,0};
207
208 anyupdates |= screenupdated;
209
210 //
211
212 lastcycles = cumulativecycles;
213 if ((!anyupdates) && (!lastupdates[0]) && (!lastupdates[1]) && VideoApparentlyDirty())
214 {
215 VideoCheckPage(1);
216 static DWORD lasttime = 0;
217 DWORD currtime = GetTickCount();
218 if ((!g_bFullSpeed) ||
219 (currtime-lasttime >= (DWORD)((graphicsmode || !systemidle) ? 100 : 25)))
220 {
221 VideoRefreshScreen();
222 lasttime = currtime;
223 }
224 screenupdated = 1;
225 }
226
227 lastupdates[1] = lastupdates[0];
228 lastupdates[0] = anyupdates;
229 anyupdates = 0;
230
231 if (pageflipping)
232 pageflipping--;
233 }
234
235 MB_EndOfVideoFrame();
236 }
237
238 //
239
240 if(!g_bFullSpeed)
241 {
242 SysClk_WaitTimer();
243
244 #if DBG_CALC_FREQ
245 if(g_nPerfFreq)
246 {
247 //QueryPerformanceCounter((LARGE_INTEGER*)&nTime1); QueryPerformanceFrequency
248 LONG nTime1 = GetTickCount();//no QueryPerformanceCounter and alike
249 LONG nTimeDiff = nTime1 - nTime0;
250 double fTime = (double)nTimeDiff / (double)(LONG)g_nPerfFreq;
251
252 g_fDbg[g_nIdx] = fTime;
253 g_nIdx = (g_nIdx+1) & (MAX_CNT-1);
254 g_fMeanPeriod = 0.0;
255 for(UINT n=0; n<MAX_CNT; n++)
256 g_fMeanPeriod += g_fDbg[n];
257 g_fMeanPeriod /= (double)MAX_CNT;
258 g_fMeanFreq = 1.0 / g_fMeanPeriod;
259 }
260 #endif
261 }
262 }
263
264 //===========================================================================
265
266 void SetCurrentCLK6502()
267 {
268 static DWORD dwPrevSpeed = (DWORD) -1;
269
270 if(dwPrevSpeed == g_dwSpeed)
271 return;
272
273 dwPrevSpeed = g_dwSpeed;
274
275 // SPEED_MIN = 0 = 0.50 MHz
276 // SPEED_NORMAL = 10 = 1.00 MHz
277 // 20 = 2.00 MHz
278 // SPEED_MAX-1 = 39 = 3.90 MHz
279 // SPEED_MAX = 40 = ???? MHz (run full-speed, /g_fCurrentCLK6502/ is ignored)
280
281
282 if(g_dwSpeed < SPEED_NORMAL)
283 g_fMHz = 0.5 + (double)g_dwSpeed * 0.05;
284 else
285 g_fMHz = (double)g_dwSpeed / 10.0;
286
287 g_fCurrentCLK6502 = CLK_6502 * g_fMHz;
288
289 //
290 // Now re-init modules that are dependent on /g_fCurrentCLK6502/
291 //
292
293 SpkrReinitialize();
294 MB_Reinitialize();
295 }
296
297 //===========================================================================
298 void EnterMessageLoop ()
299 {
300 // MSG message;
301 SDL_Event event;
302
303 // PeekMessage(&message, NULL, 0, 0, PM_NOREMOVE);
304 while(true)
305
306 // while (message.message!=WM_QUIT)
307 {
308 if(SDL_PollEvent(&event))
309 {
310 if(event.type == SDL_QUIT && event.key.keysym.sym != SDLK_F4) return;
311 FrameDispatchMessage(&event);
312
313
314
315 // if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
316 // {
317 // TranslateMessage(&message);
318 // DispatchMessage(&message);
319
320 while ((g_nAppMode == MODE_RUNNING) || (g_nAppMode == MODE_STEPPING))
321 {
322 if(SDL_PollEvent(&event)) {
323 if(event.type == SDL_QUIT && event.key.keysym.sym != SDLK_F4) return;
324 FrameDispatchMessage(&event);
325 }
326 else if (g_nAppMode == MODE_STEPPING)
327 {
328 DebugContinueStepping();
329 }
330 else
331 {
332 ContinueExecution();
333 if (g_nAppMode != MODE_DEBUG)
334 {
335 if (g_bFullSpeed)
336 ContinueExecution();
337 }
338 }
339 }
340 }
341 else
342 {
343 if (g_nAppMode == MODE_DEBUG)
344 DebuggerUpdate();
345 else if (g_nAppMode == MODE_LOGO || g_nAppMode == MODE_PAUSED)
346 SDL_Delay(100); // Stop process hogging CPU
347 }
348 }
349 }
350
351 //===========================================================================
352 // void GetProgramDirectory () {
353 // GetModuleFileName((HINSTANCE)0,g_sProgramDir,MAX_PATH);
354 // g_sProgramDir[MAX_PATH-1] = 0;
355 // int loop = _tcslen(g_sProgramDir);
356 // while (loop--)
357 // if ((g_sProgramDir[loop] == TEXT('\\')) ||
358 // (g_sProgramDir[loop] == TEXT(':'))) {
359 // g_sProgramDir[loop+1] = 0;
360 // break;
361 // }
362 // }
363
364
365 //---------------------------------------------------------------------------
366
367 int DoDiskInsert(int nDrive, LPSTR szFileName)
368 {
369 // DWORD dwAttributes = GetFileAttributes(szFileName);
370 //
371 //
372 // if(dwAttributes == INVALID_FILE_ATTRIBUTES)
373 // {
374 // return -1;
375 // }
376 //
377 // BOOL bWriteProtected = (dwAttributes & FILE_ATTRIBUTE_READONLY) ? TRUE : FALSE;
378
379 return DiskInsert(nDrive, szFileName, 0, 0);
380 }
381
382 //===========================================================================
383 // Let us load main configuration from config file. Y_Y --bb
384 void LoadConfiguration ()
385 {
386 DWORD dwComputerType;
387
388 /* if (LOAD(TEXT(REGVALUE_APPLE2_TYPE),&dwComputerType))
389 {
390 if (dwComputerType >= A2TYPE_MAX)
391 dwComputerType = A2TYPE_APPLE2EEHANCED;
392 g_Apple2Type = (eApple2Type) dwComputerType;
393 }
394 else
395 {*/
396 LOAD(TEXT("Computer Emulation"),&dwComputerType);
397 switch (dwComputerType)
398 {
399 // NB. No A2TYPE_APPLE2E
400
401 case 0: g_Apple2Type = A2TYPE_APPLE2;break;
402 case 1: g_Apple2Type = A2TYPE_APPLE2PLUS;break;
403 case 2: g_Apple2Type = A2TYPE_APPLE2EEHANCED;break;
404 default: g_Apple2Type = A2TYPE_APPLE2EEHANCED;break;
405 }
406 // }
407 // determine Apple type and set appropriate caption -- should be in (F9)switching modes?
408 switch (g_Apple2Type)
409 {
410 case A2TYPE_APPLE2: g_pAppTitle = TITLE_APPLE_2; break;
411 case A2TYPE_APPLE2PLUS: g_pAppTitle = TITLE_APPLE_2_PLUS; break;
412 case A2TYPE_APPLE2E: g_pAppTitle = TITLE_APPLE_2E; break;
413 case A2TYPE_APPLE2EEHANCED: g_pAppTitle = TITLE_APPLE_2E_ENHANCED; break;
414 }
415
416 LOAD(TEXT("Joystick 0"),&joytype[0]);
417 LOAD(TEXT("Joystick 1"),&joytype[1]);
418 LOAD(TEXT("Sound Emulation") ,&soundtype);
419
420 DWORD dwSerialPort;
421 LOAD(TEXT("Serial Port") ,&dwSerialPort);
422 sg_SSC.SetSerialPort(dwSerialPort); // ----------- why it is here????
423
424 LOAD(TEXT("Emulation Speed") ,&g_dwSpeed);
425
426 LOAD(TEXT("Enhance Disk Speed"),(DWORD *)&enhancedisk);//
427 LOAD(TEXT("Video Emulation") ,&videotype);
428 // printf("Video Emulation = %d\n", videotype);
429
430 DWORD dwTmp = 0; // temp var
431
432 LOAD(TEXT("Fullscreen") ,&dwTmp); // load fullscreen flag
433 fullscreen = (BOOL) dwTmp;