Compare commits

...

41 Commits
1.2 ... master

Author SHA1 Message Date
Jeremy Rand
836d4fbc21 Update the readme. 2021-07-26 23:29:07 -04:00
Jeremy Rand
78d451657e Issue release 2.7. 2021-03-17 22:48:01 -04:00
Jeremy Rand
b477317279 Some fixes to the save option upgrade code and mark this as a beta build. 2021-03-15 00:37:47 -04:00
Jeremy Rand
8bb8f4511b Do not set the high bit of the read character to indicate that the apple key(s) are held down if the high bit is already set. 2021-03-12 00:38:54 -05:00
Jeremy Rand
3861bfc00c Add the option to change the keys used to navigate the gem board. 2021-03-12 00:14:05 -05:00
Jeremy Rand
ab895a6d88 Update README to reflect the new release. 2020-05-28 22:37:56 -04:00
Jeremy Rand
8a7c234e61 Implement a series of fixes for Mockingboard speech support based on feedback from TomCh. Much of this is actually changed merged from the Mockingboard detection code from TotalReplay (also feedback from TomCh). Bump the version number to 2.6 to prepare for the next release. 2020-05-28 22:37:14 -04:00
Jeremy Rand
bc1cbc975c Fix an off by one error found by TomCh in the speech code which lead to the beginning of the next speech phrase to be played. This is why "excellent" sounded more like "excellent-ay". Worse, it would lead to the 5 bytes after the phrase "incredible" to be treated like speech data and who knows what that did.
Also, bump the version number to 2.6.a1 in preparation for a 2.6 release with these fixes.
2020-05-04 23:07:02 -04:00
Jeremy Rand
e21c7375f6 Ensure that the game hint is set correctly even after loading a new level. The key is to check for an "end of game" condition at the top of the main game loop. Unless there is a bug in the "next level" code, it will never been the end of the game when the next level starts. But it is the end of game check which also sets the hint square which is the first square it can find with a valid move. 2020-05-03 23:04:25 -04:00
Jeremy Rand
1d5eb0a636 Bump the version up to 2.5. 2020-03-30 23:35:32 -04:00
Jeremy Rand
d8ec0349c5 Add a comment about the problems detecting the //e card from get_ostype(). 2020-03-24 23:54:14 -04:00
Jeremy Rand
0a5c8b5fe3 Detection of the //e card is buggy in the cc65 runtime so implement my own detection of this HW to workaround the buggy double lores implementation. 2020-03-24 02:06:45 -04:00
Jeremy Rand
49ccd2bfdc Add code to handle buggy double lores HW on the Apple //e card for the Mac. Apparently it doesn't handle the colour shifting that is required in the aux bank on other Apple // HW. 2020-03-23 23:28:28 -04:00
Jeremy Rand
d3d97db1f6 Only show the "enable/disable mouse" option if a mouse is actually present. Force the mouse option on when the options file is upgraded to the latest version. Allow mouse and joystick controls to co-exist. In past versions, the mouse interrupts messed up the joystick measurements but those are now done with interrupts disabled so that isn't a problem now. With this change, the mouse behaves like the mockingboard - it is auto-detected and just used but can be disabled if the user does not want it enabled even though present on the system.
Also bump the version number to 2.4.
2020-03-09 22:59:38 -04:00
Jeremy Rand
20ad7dda1c Add code from Total Replay to detect the sound chip automatically on startup. This then leads to a complete rethinking about how to save/load the options for the game. It used to ask what slot the mockingboard was in (if any) and whether it had a speech chip. Now, the game should just know this information. So, I turned the first boolean in the save file into an options file version byte and bumped it to "2". The boolean was always true and was kind of a very simple "magic number" to say that the contents was valid. Now it is a version number of the contents. The slot number and boolean for the speech chip is are now each turned into booleans - one to say whether to enable a mockingboard if found and the other to enable the speech chip if found.
This means there are three booleans in the options related to sound now.  The first one enables/disables sound entirely and is default on.  The second is only relevant if the sound is enabled and says "use a mockingboard if present".  Again this is true by default.  Finally, the this says "use a speech chip on the mockingboard if present" and is only relevant if the mockingboard is also enabled.

So, the basic approach now is to default the "best" sound options and auto-detect the sound HW at launch.  The user can then use the options to downgrade their sound all the way to basic Apple // sound or turn off the sound entirely.
2020-03-04 22:23:09 -05:00
Jeremy Rand
72fc265e5a Fix the mouse interrupt based VBL for the //c and //c+. This used to work under cc65 v2.13.3 but when I moved the codebase to cc65 v2.17, the mouse driver interrupt handler changed. It used to call the "show" callback routine when handling the interrupt. In v2.17, it stopped calling "show" from the interrupt handler and instead called a new "draw" callback. Because the "show" callback was not being called, the game would wait forever for a VBL interval on the //c and //c+. This fixes the problem by setting the "draw" hook to my VBL callback on the //c and //c+.
Bumped the version number to v2.3.
2020-02-26 22:36:42 -05:00
Jeremy Rand
2c981b6f1d Do not turn on joystick control by default on first launch. Keyboard and mouse are the primary interfaces and joystick is just an option which can be turned on (but is a bit weird so not on by default). 2020-02-20 22:16:03 -05:00
Jeremy Rand
7955b7a0ec And bump the version number. 2020-01-30 22:57:32 -05:00
Jeremy Rand
7b7847d391 Ported some mockingboard detection code from Total Replay into the startup. If there are no game options saved, then it tries to detect a Mockingboard and use it automatically. No detection for a speech chip yet (although that may be coming and if so, I will port that in also). 2020-01-30 22:56:47 -05:00
Jeremy Rand
c67874ca74 Total Replay would like a jump to $100 when the game quits. This change should do that. The version number also got bumped too 2.2a2. 2020-01-29 22:02:39 -05:00
Jeremy Rand
879030f4ff Use uppercase for the file names because that works better with Total Replay. Fix a problem where HISCR is left on after switching to mixed mode. Fix bugs with formatting of the text when saving the game, prompting for the next level and notifying that the end of the game has been reached in mixed text mode. 2020-01-29 00:31:19 -05:00
Jeremy Rand
74e22c1854 Update the README file. 2020-01-24 21:53:59 -05:00
Jeremy Rand
e8783b019b Add a build option in the Makefile for a Total Reply build. For a TR build, we have a special quit handler which jumps to a special vector. Also in a TR build, ".tr" is appended to the version number to make it clear it is a TR build. Bump the version number up to 2.1. 2020-01-24 21:46:51 -05:00
Jeremy Rand
34e320a605 Make the project clean of 65c02 instructions. This should let this run on an unenhanced //e. 2020-01-22 23:31:42 -05:00
Jeremy Rand
d0daa023d8 Update the project template again to include the output products. 2019-08-08 23:50:21 -04:00
Jeremy Rand
140f55a213 Fix minor bug from the build engine. 2019-08-08 22:58:25 -04:00
Jeremy Rand
0db89da22c Update to the latest build engine release. 2019-08-07 22:58:54 -04:00
Jeremy Rand
6d4ae62b77 Fix problems related to moving to cc65 2.17. 2018-10-21 14:13:58 -04:00
Jeremy Rand
f619aa0313 Add support for cc65 2.17. 2018-10-17 23:13:12 -04:00
Jeremy Rand
87819667be Update the build engine to support capturing build errors in Xcode itself. 2018-06-25 22:58:40 -04:00
Jeremy Rand
a608ddbe8f Remove build files which snuck in to git. 2018-06-19 23:10:21 -04:00
Jeremy Rand
7d75ae8dcc Upgrade to the new build engine. 2018-06-19 23:07:49 -04:00
Jeremy Rand
a6750230da Update the readme file. 2016-12-24 01:54:17 -05:00
Jeremy Rand
47c563e815 Update the readme file. 2016-12-24 01:53:35 -05:00
Jeremy Rand
1f24457a8a Say "good", "excellent" and "incredible" on long chain reactions. 2016-12-24 01:49:20 -05:00
Jeremy Rand
3d84abcc16 Move the the loader system type because the code is getting too big to accommodate anything else... 2016-12-23 23:09:42 -05:00
Jeremy Rand
9bca2bc307 Modify options to allow enabling mockingboard and speech chip support. Hook up mockingboard and speech support. 2016-12-23 22:51:45 -05:00
Jeremy Rand
c9a1c8c9f1 Add speech binary messages to the sound file. 2016-12-23 01:05:54 -05:00
Jeremy Rand
78986f77a1 Add mockingboard sounds. 2016-12-22 00:39:09 -05:00
Jeremy Rand
36ed166670 Add mockingboard library and start reworking the sound code to prepare to integrate it. 2016-12-20 00:05:41 -05:00
Jeremy Rand
7e7d34a878 Update the readme file to point to the latest release. 2016-09-12 22:28:54 -04:00
43 changed files with 3373 additions and 1180 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2019 Jeremy Rand
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,8 +1,10 @@
A2Bejwld
Apple // Bejeweled
========
This is an implementation of Bejeweled written for the Apple //. It is my HackFest entry at KansasFest 2016.
![A2Bejwld Screenshot](/a2bejwld.png "A2Bejwld Screenshot")
![A2Bejwld Screenshot](/a2bejwld.png "Apple // Bejeweled Screenshot")
[Download a disk image](https://github.com/jeremysrand/a2bejwld/releases/download/1.1.1/a2bejwld.dsk)
[Download a disk image](https://github.com/jeremysrand/a2bejwld/releases/download/2.7/a2bejwld.dsk)
[Watch the YouTube video](https://youtu.be/yseAGBzREik)

View File

@ -3,166 +3,250 @@
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
9D4D1AB11D6D708E00D20BB8 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D6B472E1D3FB16F00F6D704 /* main.c */; };
9D4D1AB21D6D709100D20BB8 /* ui.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D6B47431D403F5B00F6D704 /* ui.c */; };
9D4D1AB31D6D709600D20BB8 /* game.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D6B47401D40098300F6D704 /* game.c */; };
9D4D1AB41D6D709F00D20BB8 /* machine.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D4D1AA31D6D0E9B00D20BB8 /* machine.c */; };
9D4D1AB51D6D70A300D20BB8 /* anim.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D6B47481D4270EC00F6D704 /* anim.c */; };
9DE4036422FD232B00EC061A /* AppleCommander.jar in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DE4036322FD232B00EC061A /* AppleCommander.jar */; };
9DE4036622FD232B00EC061A /* bastokenizer-tools-bt-0.2.0.jar in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DE4036522FD232B00EC061A /* bastokenizer-tools-bt-0.2.0.jar */; };
9DE4036822FD232B00EC061A /* createDiskImage in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9DE4036722FD232B00EC061A /* createDiskImage */; };
9DE4036A22FD232B00EC061A /* bt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9DE4036922FD232B00EC061A /* bt */; };
9DE4036C22FD232B00EC061A /* DevApple.vii in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9DE4036B22FD232B00EC061A /* DevApple.vii */; };
9DE4036E22FD232B00EC061A /* dos33_template.dsk in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9DE4036D22FD232B00EC061A /* dos33_template.dsk */; };
9DE4037022FD232B00EC061A /* errorFilter.sh in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9DE4036F22FD232B00EC061A /* errorFilter.sh */; };
9DE4037222FD232B00EC061A /* head.mk in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9DE4037122FD232B00EC061A /* head.mk */; };
9DE4037422FD232B00EC061A /* prodos_template.dsk in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9DE4037322FD232B00EC061A /* prodos_template.dsk */; };
9DE4037622FD232B00EC061A /* tail.mk in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9DE4037522FD232B00EC061A /* tail.mk */; };
9DE4037822FD232B00EC061A /* V2Make.scpt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9DE4037722FD232B00EC061A /* V2Make.scpt */; };
9DE4037B22FD232B00EC061A /* a2bejwld.xcscheme in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9DE4037A22FD232B00EC061A /* a2bejwld.xcscheme */; };
9DE403A622FD235F00EC061A /* ui.c in Sources */ = {isa = PBXBuildFile; fileRef = 9DE4038E22FD235E00EC061A /* ui.c */; };
9DE403A722FD235F00EC061A /* mockingboard.c in Sources */ = {isa = PBXBuildFile; fileRef = 9DE4039122FD235E00EC061A /* mockingboard.c */; };
9DE403A822FD235F00EC061A /* vbl.s in Sources */ = {isa = PBXBuildFile; fileRef = 9DE4039322FD235E00EC061A /* vbl.s */; };
9DE403A922FD235F00EC061A /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 9DE4039522FD235E00EC061A /* main.c */; };
9DE403AA22FD235F00EC061A /* joystick.c in Sources */ = {isa = PBXBuildFile; fileRef = 9DE4039822FD235E00EC061A /* joystick.c */; };
9DE403AB22FD235F00EC061A /* anim.c in Sources */ = {isa = PBXBuildFile; fileRef = 9DE4039922FD235E00EC061A /* anim.c */; };
9DE403AC22FD235F00EC061A /* sound.c in Sources */ = {isa = PBXBuildFile; fileRef = 9DE4039B22FD235E00EC061A /* sound.c */; };
9DE403AD22FD235F00EC061A /* dbllores.s in Sources */ = {isa = PBXBuildFile; fileRef = 9DE4039C22FD235E00EC061A /* dbllores.s */; };
9DE403AE22FD235F00EC061A /* Makefile in Sources */ = {isa = PBXBuildFile; fileRef = 9DE4039D22FD235E00EC061A /* Makefile */; };
9DE403AF22FD235F00EC061A /* mockingboard_speech.s in Sources */ = {isa = PBXBuildFile; fileRef = 9DE4039E22FD235F00EC061A /* mockingboard_speech.s */; };
9DE403B022FD235F00EC061A /* game.c in Sources */ = {isa = PBXBuildFile; fileRef = 9DE4039F22FD235F00EC061A /* game.c */; };
9DE403B122FD235F00EC061A /* mouseWrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = 9DE403A022FD235F00EC061A /* mouseWrapper.c */; };
9DE403B222FD235F00EC061A /* machine.c in Sources */ = {isa = PBXBuildFile; fileRef = 9DE403A422FD235F00EC061A /* machine.c */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9D4D1AA71D6D704800D20BB8 /* CopyFiles */ = {
9DE4035A22FD232B00EC061A /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
9DE4037422FD232B00EC061A /* prodos_template.dsk in CopyFiles */,
9DE4036A22FD232B00EC061A /* bt in CopyFiles */,
9DE4036E22FD232B00EC061A /* dos33_template.dsk in CopyFiles */,
9DE4036822FD232B00EC061A /* createDiskImage in CopyFiles */,
9DE4037B22FD232B00EC061A /* a2bejwld.xcscheme in CopyFiles */,
9DE4037822FD232B00EC061A /* V2Make.scpt in CopyFiles */,
9DE4037222FD232B00EC061A /* head.mk in CopyFiles */,
9DE4036C22FD232B00EC061A /* DevApple.vii in CopyFiles */,
9DE4037022FD232B00EC061A /* errorFilter.sh in CopyFiles */,
9DE4037622FD232B00EC061A /* tail.mk in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
9D3A9FB81D455CCF004C5897 /* joystick.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = joystick.h; sourceTree = "<group>"; };
9D3A9FB91D455CD8004C5897 /* joystick.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = joystick.c; sourceTree = "<group>"; };
9D4D1AA31D6D0E9B00D20BB8 /* machine.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = machine.c; sourceTree = "<group>"; };
9D4D1AA41D6D0E9B00D20BB8 /* machine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = machine.h; sourceTree = "<group>"; };
9D4D1AA91D6D704800D20BB8 /* dummy */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dummy; sourceTree = BUILT_PRODUCTS_DIR; };
9D509F911D654F9900161DDC /* mouseWrapper.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mouseWrapper.c; sourceTree = "<group>"; };
9D509F921D654F9900161DDC /* mouseWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mouseWrapper.h; sourceTree = "<group>"; };
9D509F941D66AE2800161DDC /* a2e.stdmou.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = a2e.stdmou.s; sourceTree = "<group>"; };
9D6B472E1D3FB16F00F6D704 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
9D6B472F1D3FB16F00F6D704 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
9D6B47311D3FB16F00F6D704 /* AppleCommander.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; name = AppleCommander.jar; path = make/AppleCommander.jar; sourceTree = "<group>"; };
9D6B47321D3FB16F00F6D704 /* createDiskImage */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = createDiskImage; path = make/createDiskImage; sourceTree = "<group>"; };
9D6B47331D3FB16F00F6D704 /* DevApple.vii */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; name = DevApple.vii; path = make/DevApple.vii; sourceTree = "<group>"; };
9D6B47341D3FB16F00F6D704 /* dos33_template.dsk */ = {isa = PBXFileReference; lastKnownFileType = file; name = dos33_template.dsk; path = make/dos33_template.dsk; sourceTree = "<group>"; };
9D6B47351D3FB16F00F6D704 /* head.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = head.mk; path = make/head.mk; sourceTree = "<group>"; };
9D6B47361D3FB16F00F6D704 /* prodos_template.dsk */ = {isa = PBXFileReference; lastKnownFileType = file; name = prodos_template.dsk; path = make/prodos_template.dsk; sourceTree = "<group>"; };
9D6B47371D3FB16F00F6D704 /* tail.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = tail.mk; path = make/tail.mk; sourceTree = "<group>"; };
9D6B47381D3FB16F00F6D704 /* V2Make.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; name = V2Make.scpt; path = make/V2Make.scpt; sourceTree = "<group>"; };
9D6B473E1D3FB20000F6D704 /* dbllores.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = dbllores.s; sourceTree = "<group>"; };
9D6B473F1D3FB5C800F6D704 /* dbllores.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dbllores.h; sourceTree = "<group>"; };
9D6B47401D40098300F6D704 /* game.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = game.c; sourceTree = "<group>"; };
9D6B47411D40098300F6D704 /* game.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = game.h; sourceTree = "<group>"; };
9D6B47421D400B4900F6D704 /* types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = "<group>"; };
9D6B47431D403F5B00F6D704 /* ui.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ui.c; sourceTree = "<group>"; };
9D6B47441D403F5B00F6D704 /* ui.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ui.h; sourceTree = "<group>"; };
9D6B47451D426E6300F6D704 /* vbl.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = vbl.s; sourceTree = "<group>"; };
9D6B47471D42709200F6D704 /* vbl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = vbl.h; sourceTree = "<group>"; };
9D6B47481D4270EC00F6D704 /* anim.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = anim.c; sourceTree = "<group>"; };
9D6B47491D4270EC00F6D704 /* anim.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = anim.h; sourceTree = "<group>"; };
9D6B474A1D42DEB600F6D704 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
9D6B474C1D43BBAC00F6D704 /* a2bejwld.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = a2bejwld.png; sourceTree = "<group>"; };
9DC0327323D948D000797D62 /* text.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = text.s; sourceTree = "<group>"; };
9DC0327423D9497600797D62 /* text.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = text.h; sourceTree = "<group>"; };
9DE4035422FD232B00EC061A /* a2bejwld */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = a2bejwld; sourceTree = BUILT_PRODUCTS_DIR; };
9DE4035722FD232B00EC061A /* a2bejwld.dsk */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = a2bejwld.dsk; sourceTree = BUILT_PRODUCTS_DIR; };
9DE4035C22FD232B00EC061A /* doNotBuild */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = doNotBuild; sourceTree = BUILT_PRODUCTS_DIR; };
9DE4036322FD232B00EC061A /* AppleCommander.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; name = AppleCommander.jar; path = make/AppleCommander.jar; sourceTree = "<group>"; };
9DE4036522FD232B00EC061A /* bastokenizer-tools-bt-0.2.0.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; name = "bastokenizer-tools-bt-0.2.0.jar"; path = "make/bastokenizer-tools-bt-0.2.0.jar"; sourceTree = "<group>"; };
9DE4036722FD232B00EC061A /* createDiskImage */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = createDiskImage; path = make/createDiskImage; sourceTree = "<group>"; };
9DE4036922FD232B00EC061A /* bt */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = bt; path = make/bt; sourceTree = "<group>"; };
9DE4036B22FD232B00EC061A /* DevApple.vii */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; name = DevApple.vii; path = make/DevApple.vii; sourceTree = "<group>"; };
9DE4036D22FD232B00EC061A /* dos33_template.dsk */ = {isa = PBXFileReference; lastKnownFileType = file; name = dos33_template.dsk; path = make/dos33_template.dsk; sourceTree = "<group>"; };
9DE4036F22FD232B00EC061A /* errorFilter.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = errorFilter.sh; path = make/errorFilter.sh; sourceTree = "<group>"; };
9DE4037122FD232B00EC061A /* head.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = head.mk; path = make/head.mk; sourceTree = "<group>"; };
9DE4037322FD232B00EC061A /* prodos_template.dsk */ = {isa = PBXFileReference; lastKnownFileType = file; name = prodos_template.dsk; path = make/prodos_template.dsk; sourceTree = "<group>"; };
9DE4037522FD232B00EC061A /* tail.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = tail.mk; path = make/tail.mk; sourceTree = "<group>"; };
9DE4037722FD232B00EC061A /* V2Make.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; name = V2Make.scpt; path = make/V2Make.scpt; sourceTree = "<group>"; };
9DE4037A22FD232B00EC061A /* a2bejwld.xcscheme */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = a2bejwld.xcscheme; path = a2bejwld.xcodeproj/xcshareddata/xcschemes/a2bejwld.xcscheme; sourceTree = SOURCE_ROOT; };
9DE4038A22FD234700EC061A /* a2bejwld.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = a2bejwld.png; sourceTree = "<group>"; };
9DE4038B22FD234700EC061A /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
9DE4038C22FD234700EC061A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
9DE4038D22FD235E00EC061A /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = "<group>"; };
9DE4038E22FD235E00EC061A /* ui.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ui.c; sourceTree = "<group>"; };
9DE4038F22FD235E00EC061A /* sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sound.h; sourceTree = "<group>"; };
9DE4039022FD235E00EC061A /* game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = game.h; sourceTree = "<group>"; };
9DE4039122FD235E00EC061A /* mockingboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mockingboard.c; sourceTree = "<group>"; };
9DE4039222FD235E00EC061A /* mouseWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mouseWrapper.h; sourceTree = "<group>"; };
9DE4039322FD235E00EC061A /* vbl.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = vbl.s; sourceTree = "<group>"; };
9DE4039422FD235E00EC061A /* ui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ui.h; sourceTree = "<group>"; };
9DE4039522FD235E00EC061A /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
9DE4039622FD235E00EC061A /* anim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = anim.h; sourceTree = "<group>"; };
9DE4039722FD235E00EC061A /* joystick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = joystick.h; sourceTree = "<group>"; };
9DE4039822FD235E00EC061A /* joystick.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = joystick.c; sourceTree = "<group>"; };
9DE4039922FD235E00EC061A /* anim.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = anim.c; sourceTree = "<group>"; };
9DE4039A22FD235E00EC061A /* machine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = machine.h; sourceTree = "<group>"; };
9DE4039B22FD235E00EC061A /* sound.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sound.c; sourceTree = "<group>"; };
9DE4039C22FD235E00EC061A /* dbllores.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = dbllores.s; sourceTree = "<group>"; };
9DE4039D22FD235E00EC061A /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
9DE4039E22FD235F00EC061A /* mockingboard_speech.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = mockingboard_speech.s; sourceTree = "<group>"; };
9DE4039F22FD235F00EC061A /* game.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = game.c; sourceTree = "<group>"; };
9DE403A022FD235F00EC061A /* mouseWrapper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mouseWrapper.c; sourceTree = "<group>"; };
9DE403A122FD235F00EC061A /* mockingboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mockingboard.h; sourceTree = "<group>"; };
9DE403A222FD235F00EC061A /* dbllores.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dbllores.h; sourceTree = "<group>"; };
9DE403A322FD235F00EC061A /* vbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vbl.h; sourceTree = "<group>"; };
9DE403A422FD235F00EC061A /* machine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = machine.c; sourceTree = "<group>"; };
9DE403A522FD235F00EC061A /* mockingboard_speech.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mockingboard_speech.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
9D4D1AA61D6D704800D20BB8 /* Frameworks */ = {
9DE4035922FD232B00EC061A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9DE4036422FD232B00EC061A /* AppleCommander.jar in Frameworks */,
9DE4036622FD232B00EC061A /* bastokenizer-tools-bt-0.2.0.jar in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9D3A9FBA1D4578B4004C5897 /* mouse */ = {
9DE4034D22FD232B00EC061A = {
isa = PBXGroup;
children = (
9D509F941D66AE2800161DDC /* a2e.stdmou.s */,
9D509F911D654F9900161DDC /* mouseWrapper.c */,
9D509F921D654F9900161DDC /* mouseWrapper.h */,
9DE4038A22FD234700EC061A /* a2bejwld.png */,
9DE4038B22FD234700EC061A /* LICENSE */,
9DE4038C22FD234700EC061A /* README.md */,
9DE4035D22FD232B00EC061A /* a2bejwld */,
9DE4035522FD232B00EC061A /* Products */,
);
name = mouse;
sourceTree = "<group>";
};
9D3A9FBE1D457973004C5897 /* joystick */ = {
9DE4035522FD232B00EC061A /* Products */ = {
isa = PBXGroup;
children = (
9D3A9FB91D455CD8004C5897 /* joystick.c */,
9D3A9FB81D455CCF004C5897 /* joystick.h */,
);
name = joystick;
sourceTree = "<group>";
};
9D4D1AAA1D6D704800D20BB8 /* Products */ = {
isa = PBXGroup;
children = (
9D4D1AA91D6D704800D20BB8 /* dummy */,
9DE4035422FD232B00EC061A /* a2bejwld */,
9DE4035722FD232B00EC061A /* a2bejwld.dsk */,
9DE4035C22FD232B00EC061A /* doNotBuild */,
);
name = Products;
sourceTree = "<group>";
};
9D6B47271D3FB16F00F6D704 = {
9DE4035D22FD232B00EC061A /* a2bejwld */ = {
isa = PBXGroup;
children = (
9D6B474A1D42DEB600F6D704 /* README.md */,
9D6B474B1D43BB9100F6D704 /* screenshots */,
9D6B472D1D3FB16F00F6D704 /* a2bejwld */,
9D4D1AAA1D6D704800D20BB8 /* Products */,
);
sourceTree = "<group>";
};
9D6B472D1D3FB16F00F6D704 /* a2bejwld */ = {
isa = PBXGroup;
children = (
9D6B472E1D3FB16F00F6D704 /* main.c */,
9D6B47431D403F5B00F6D704 /* ui.c */,
9D6B47441D403F5B00F6D704 /* ui.h */,
9D6B47401D40098300F6D704 /* game.c */,
9D6B47411D40098300F6D704 /* game.h */,
9D6B47421D400B4900F6D704 /* types.h */,
9D6B473E1D3FB20000F6D704 /* dbllores.s */,
9D6B473F1D3FB5C800F6D704 /* dbllores.h */,
9D6B47451D426E6300F6D704 /* vbl.s */,
9D6B47471D42709200F6D704 /* vbl.h */,
9D4D1AA31D6D0E9B00D20BB8 /* machine.c */,
9D4D1AA41D6D0E9B00D20BB8 /* machine.h */,
9D6B47481D4270EC00F6D704 /* anim.c */,
9D6B47491D4270EC00F6D704 /* anim.h */,
9D6B472F1D3FB16F00F6D704 /* Makefile */,
9D3A9FBE1D457973004C5897 /* joystick */,
9D3A9FBA1D4578B4004C5897 /* mouse */,
9D6B47301D3FB16F00F6D704 /* make */,
9DE4039D22FD235E00EC061A /* Makefile */,
9DE4039522FD235E00EC061A /* main.c */,
9DE4039F22FD235F00EC061A /* game.c */,
9DE4039022FD235E00EC061A /* game.h */,
9DE403A422FD235F00EC061A /* machine.c */,
9DE4039A22FD235E00EC061A /* machine.h */,
9DE4038D22FD235E00EC061A /* types.h */,
9DE4038E22FD235E00EC061A /* ui.c */,
9DE4039422FD235E00EC061A /* ui.h */,
9DE403B322FD237600EC061A /* sound */,
9DE403B722FD23D600EC061A /* graphics */,
9DE403B622FD239900EC061A /* mouse */,
9DE403B522FD239100EC061A /* Mockingboard */,
9DE403B422FD238400EC061A /* joystick */,
9DE4036222FD232B00EC061A /* make */,
9DE4037922FD232B00EC061A /* Supporting Files */,
);
path = a2bejwld;
sourceTree = "<group>";
};
9D6B47301D3FB16F00F6D704 /* make */ = {
9DE4036222FD232B00EC061A /* make */ = {
isa = PBXGroup;
children = (
9D6B47311D3FB16F00F6D704 /* AppleCommander.jar */,
9D6B47321D3FB16F00F6D704 /* createDiskImage */,
9D6B47331D3FB16F00F6D704 /* DevApple.vii */,
9D6B47341D3FB16F00F6D704 /* dos33_template.dsk */,
9D6B47351D3FB16F00F6D704 /* head.mk */,
9D6B47361D3FB16F00F6D704 /* prodos_template.dsk */,
9D6B47371D3FB16F00F6D704 /* tail.mk */,
9D6B47381D3FB16F00F6D704 /* V2Make.scpt */,
9DE4036322FD232B00EC061A /* AppleCommander.jar */,
9DE4036522FD232B00EC061A /* bastokenizer-tools-bt-0.2.0.jar */,
9DE4036722FD232B00EC061A /* createDiskImage */,
9DE4036922FD232B00EC061A /* bt */,
9DE4036B22FD232B00EC061A /* DevApple.vii */,
9DE4036D22FD232B00EC061A /* dos33_template.dsk */,
9DE4036F22FD232B00EC061A /* errorFilter.sh */,
9DE4037122FD232B00EC061A /* head.mk */,
9DE4037322FD232B00EC061A /* prodos_template.dsk */,
9DE4037522FD232B00EC061A /* tail.mk */,
9DE4037722FD232B00EC061A /* V2Make.scpt */,
);
name = make;
sourceTree = "<group>";
};
9D6B474B1D43BB9100F6D704 /* screenshots */ = {
9DE4037922FD232B00EC061A /* Supporting Files */ = {
isa = PBXGroup;
children = (
9D6B474C1D43BBAC00F6D704 /* a2bejwld.png */,
9DE4037A22FD232B00EC061A /* a2bejwld.xcscheme */,
);
name = screenshots;
name = "Supporting Files";
sourceTree = "<group>";
};
9DE403B322FD237600EC061A /* sound */ = {
isa = PBXGroup;
children = (
9DE4039B22FD235E00EC061A /* sound.c */,
9DE4038F22FD235E00EC061A /* sound.h */,
);
name = sound;
sourceTree = "<group>";
};
9DE403B422FD238400EC061A /* joystick */ = {
isa = PBXGroup;
children = (
9DE4039822FD235E00EC061A /* joystick.c */,
9DE4039722FD235E00EC061A /* joystick.h */,
);
name = joystick;
sourceTree = "<group>";
};
9DE403B522FD239100EC061A /* Mockingboard */ = {
isa = PBXGroup;
children = (
9DE403A522FD235F00EC061A /* mockingboard_speech.h */,
9DE4039E22FD235F00EC061A /* mockingboard_speech.s */,
9DE4039122FD235E00EC061A /* mockingboard.c */,
9DE403A122FD235F00EC061A /* mockingboard.h */,
);
name = Mockingboard;
sourceTree = "<group>";
};
9DE403B622FD239900EC061A /* mouse */ = {
isa = PBXGroup;
children = (
9DE403A022FD235F00EC061A /* mouseWrapper.c */,
9DE4039222FD235E00EC061A /* mouseWrapper.h */,
);
name = mouse;
sourceTree = "<group>";
};
9DE403B722FD23D600EC061A /* graphics */ = {
isa = PBXGroup;
children = (
9DE4039922FD235E00EC061A /* anim.c */,
9DE4039622FD235E00EC061A /* anim.h */,
9DE403A222FD235F00EC061A /* dbllores.h */,
9DE4039C22FD235E00EC061A /* dbllores.s */,
9DC0327423D9497600797D62 /* text.h */,
9DC0327323D948D000797D62 /* text.s */,
9DE403A322FD235F00EC061A /* vbl.h */,
9DE4039322FD235E00EC061A /* vbl.s */,
);
name = graphics;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXLegacyTarget section */
9D6B472C1D3FB16F00F6D704 /* a2bejwld */ = {
9DE4035222FD232B00EC061A /* a2bejwld */ = {
isa = PBXLegacyTarget;
buildArgumentsString = "-C a2bejwld $(ACTION)";
buildConfigurationList = 9D6B473B1D3FB16F00F6D704 /* Build configuration list for PBXLegacyTarget "a2bejwld" */;
buildConfigurationList = 9DE4037E22FD232B00EC061A /* Build configuration list for PBXLegacyTarget "a2bejwld" */;
buildPhases = (
);
buildToolPath = /usr/bin/make;
@ -175,159 +259,212 @@
/* End PBXLegacyTarget section */
/* Begin PBXNativeTarget section */
9D4D1AA81D6D704800D20BB8 /* dummy */ = {
9DE4035322FD232B00EC061A /* Binary */ = {
isa = PBXNativeTarget;
buildConfigurationList = 9D4D1AAE1D6D704800D20BB8 /* Build configuration list for PBXNativeTarget "dummy" */;
buildConfigurationList = 9DE4038122FD232B00EC061A /* Build configuration list for PBXNativeTarget "Binary" */;
buildPhases = (
9D4D1AA51D6D704800D20BB8 /* Sources */,
9D4D1AA61D6D704800D20BB8 /* Frameworks */,
9D4D1AA71D6D704800D20BB8 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = dummy;
productName = dummy;
productReference = 9D4D1AA91D6D704800D20BB8 /* dummy */;
name = Binary;
productName = Binary;
productReference = 9DE4035422FD232B00EC061A /* a2bejwld */;
productType = "com.apple.product-type.tool";
};
9DE4035622FD232B00EC061A /* DiskImage */ = {
isa = PBXNativeTarget;
buildConfigurationList = 9DE4038422FD232B00EC061A /* Build configuration list for PBXNativeTarget "DiskImage" */;
buildPhases = (
);
buildRules = (
);
dependencies = (
);
name = DiskImage;
productName = DiskImage;
productReference = 9DE4035722FD232B00EC061A /* a2bejwld.dsk */;
productType = "com.apple.product-type.tool";
};
9DE4035B22FD232B00EC061A /* doNotBuild */ = {
isa = PBXNativeTarget;
buildConfigurationList = 9DE4038722FD232B00EC061A /* Build configuration list for PBXNativeTarget "doNotBuild" */;
buildPhases = (
9DE4035822FD232B00EC061A /* Sources */,
9DE4035922FD232B00EC061A /* Frameworks */,
9DE4035A22FD232B00EC061A /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = doNotBuild;
productName = doNotBuild;
productReference = 9DE4035C22FD232B00EC061A /* doNotBuild */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
9D6B47281D3FB16F00F6D704 /* Project object */ = {
9DE4034E22FD232B00EC061A /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0730;
LastUpgradeCheck = 1030;
ORGANIZATIONNAME = "Jeremy Rand";
TargetAttributes = {
9D4D1AA81D6D704800D20BB8 = {
CreatedOnToolsVersion = 7.3.1;
9DE4035222FD232B00EC061A = {
CreatedOnToolsVersion = 10.3;
};
9D6B472C1D3FB16F00F6D704 = {
CreatedOnToolsVersion = 7.3.1;
9DE4035322FD232B00EC061A = {
CreatedOnToolsVersion = 10.3;
};
9DE4035622FD232B00EC061A = {
CreatedOnToolsVersion = 10.3;
};
9DE4035B22FD232B00EC061A = {
CreatedOnToolsVersion = 10.3;
};
};
};
buildConfigurationList = 9D6B472B1D3FB16F00F6D704 /* Build configuration list for PBXProject "a2bejwld" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
buildConfigurationList = 9DE4035122FD232B00EC061A /* Build configuration list for PBXProject "a2bejwld" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 9D6B47271D3FB16F00F6D704;
productRefGroup = 9D4D1AAA1D6D704800D20BB8 /* Products */;
mainGroup = 9DE4034D22FD232B00EC061A;
productRefGroup = 9DE4035522FD232B00EC061A /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
9D6B472C1D3FB16F00F6D704 /* a2bejwld */,
9D4D1AA81D6D704800D20BB8 /* dummy */,
9DE4035222FD232B00EC061A /* a2bejwld */,
9DE4035322FD232B00EC061A /* Binary */,
9DE4035622FD232B00EC061A /* DiskImage */,
9DE4035B22FD232B00EC061A /* doNotBuild */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
9D4D1AA51D6D704800D20BB8 /* Sources */ = {
9DE4035822FD232B00EC061A /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9D4D1AB51D6D70A300D20BB8 /* anim.c in Sources */,
9D4D1AB31D6D709600D20BB8 /* game.c in Sources */,
9D4D1AB11D6D708E00D20BB8 /* main.c in Sources */,
9D4D1AB21D6D709100D20BB8 /* ui.c in Sources */,
9D4D1AB41D6D709F00D20BB8 /* machine.c in Sources */,
9DE403AE22FD235F00EC061A /* Makefile in Sources */,
9DE403B222FD235F00EC061A /* machine.c in Sources */,
9DE403B022FD235F00EC061A /* game.c in Sources */,
9DE403A922FD235F00EC061A /* main.c in Sources */,
9DE403A822FD235F00EC061A /* vbl.s in Sources */,
9DE403AD22FD235F00EC061A /* dbllores.s in Sources */,
9DE403B122FD235F00EC061A /* mouseWrapper.c in Sources */,
9DE403AB22FD235F00EC061A /* anim.c in Sources */,
9DE403AF22FD235F00EC061A /* mockingboard_speech.s in Sources */,
9DE403AA22FD235F00EC061A /* joystick.c in Sources */,
9DE403AC22FD235F00EC061A /* sound.c in Sources */,
9DE403A622FD235F00EC061A /* ui.c in Sources */,
9DE403A722FD235F00EC061A /* mockingboard.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
9D4D1AAF1D6D704800D20BB8 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "-";
HEADER_SEARCH_PATHS = /usr/local/lib/cc65/include;
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
};
name = Debug;
};
9D4D1AB01D6D704800D20BB8 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "-";
HEADER_SEARCH_PATHS = /usr/local/lib/cc65/include;
MACOSX_DEPLOYMENT_TARGET = 10.11;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
};
name = Release;
};
9D6B47391D3FB16F00F6D704 /* Debug */ = {
9DE4037C22FD232B00EC061A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = "__fastcall__=\"\"";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MTL_ENABLE_DEBUG_INFO = YES;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
};
name = Debug;
};
9D6B473A1D3FB16F00F6D704 /* Release */ = {
9DE4037D22FD232B00EC061A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = "__fastcall__=\"\"";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
@ -335,14 +472,17 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
};
name = Release;
};
9D6B473C1D3FB16F00F6D704 /* Debug */ = {
9DE4037F22FD232B00EC061A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEBUGGING_SYMBOLS = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = VD9FGCW36C;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
OTHER_CFLAGS = "";
@ -351,46 +491,131 @@
};
name = Debug;
};
9D6B473D1D3FB16F00F6D704 /* Release */ = {
9DE4038022FD232B00EC061A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = VD9FGCW36C;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
9DE4038222FD232B00EC061A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = VD9FGCW36C;
PRODUCT_NAME = a2bejwld;
};
name = Debug;
};
9DE4038322FD232B00EC061A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = VD9FGCW36C;
PRODUCT_NAME = a2bejwld;
};
name = Release;
};
9DE4038522FD232B00EC061A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = VD9FGCW36C;
PRODUCT_NAME = a2bejwld.dsk;
};
name = Debug;
};
9DE4038622FD232B00EC061A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = VD9FGCW36C;
PRODUCT_NAME = a2bejwld.dsk;
};
name = Release;
};
9DE4038822FD232B00EC061A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = VD9FGCW36C;
GCC_PREPROCESSOR_DEFINITIONS = "__fastcall__=\"\"";
HEADER_SEARCH_PATHS = (
$TEMP_ROOT/a2bejwld.build/$CONFIGURATION/a2bejwld.build/DerivedSources,
/usr/local/share/cc65/include,
);
PRODUCT_NAME = doNotBuild;
};
name = Debug;
};
9DE4038922FD232B00EC061A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = VD9FGCW36C;
GCC_PREPROCESSOR_DEFINITIONS = "__fastcall__=\"\"";
HEADER_SEARCH_PATHS = (
$TEMP_ROOT/a2bejwld.build/$CONFIGURATION/a2bejwld.build/DerivedSources,
/usr/local/share/cc65/include,
);
PRODUCT_NAME = doNotBuild;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
9D4D1AAE1D6D704800D20BB8 /* Build configuration list for PBXNativeTarget "dummy" */ = {
9DE4035122FD232B00EC061A /* Build configuration list for PBXProject "a2bejwld" */ = {
isa = XCConfigurationList;
buildConfigurations = (
9D4D1AAF1D6D704800D20BB8 /* Debug */,
9D4D1AB01D6D704800D20BB8 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
9D6B472B1D3FB16F00F6D704 /* Build configuration list for PBXProject "a2bejwld" */ = {
isa = XCConfigurationList;
buildConfigurations = (
9D6B47391D3FB16F00F6D704 /* Debug */,
9D6B473A1D3FB16F00F6D704 /* Release */,
9DE4037C22FD232B00EC061A /* Debug */,
9DE4037D22FD232B00EC061A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
9D6B473B1D3FB16F00F6D704 /* Build configuration list for PBXLegacyTarget "a2bejwld" */ = {
9DE4037E22FD232B00EC061A /* Build configuration list for PBXLegacyTarget "a2bejwld" */ = {
isa = XCConfigurationList;
buildConfigurations = (
9D6B473C1D3FB16F00F6D704 /* Debug */,
9D6B473D1D3FB16F00F6D704 /* Release */,
9DE4037F22FD232B00EC061A /* Debug */,
9DE4038022FD232B00EC061A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
9DE4038122FD232B00EC061A /* Build configuration list for PBXNativeTarget "Binary" */ = {
isa = XCConfigurationList;
buildConfigurations = (
9DE4038222FD232B00EC061A /* Debug */,
9DE4038322FD232B00EC061A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
9DE4038422FD232B00EC061A /* Build configuration list for PBXNativeTarget "DiskImage" */ = {
isa = XCConfigurationList;
buildConfigurations = (
9DE4038522FD232B00EC061A /* Debug */,
9DE4038622FD232B00EC061A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
9DE4038722FD232B00EC061A /* Build configuration list for PBXNativeTarget "doNotBuild" */ = {
isa = XCConfigurationList;
buildConfigurations = (
9DE4038822FD232B00EC061A /* Debug */,
9DE4038922FD232B00EC061A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 9D6B47281D3FB16F00F6D704 /* Project object */;
rootObject = 9DE4034E22FD232B00EC061A /* Project object */;
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0830"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -14,7 +14,7 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9D6B472C1D3FB16F00F6D704"
BlueprintIdentifier = "9D0B917C1F526C2D004D7E0B"
BuildableName = "a2bejwld"
BlueprintName = "a2bejwld"
ReferencedContainer = "container:a2bejwld.xcodeproj">
@ -34,23 +34,53 @@
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<PathRunnable
runnableDebuggingMode = "0"
FilePath = "/usr/bin/make">
</PathRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9D6B472C1D3FB16F00F6D704"
BlueprintIdentifier = "9D0B917C1F526C2D004D7E0B"
BuildableName = "a2bejwld"
BlueprintName = "a2bejwld"
ReferencedContainer = "container:a2bejwld.xcodeproj">
</BuildableReference>
</MacroExpansion>
<CommandLineArguments>
<CommandLineArgument
argument = "-C"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "$PROJECT_DIR/a2bejwld"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "OBJECT_FILE_DIR=$OBJECT_FILE_DIR"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "DERIVED_SOURCES_DIR=$DERIVED_SOURCES_DIR"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "TARGET_BUILD_DIR=$TARGET_BUILD_DIR"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "execute"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
@ -63,7 +93,7 @@
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9D6B472C1D3FB16F00F6D704"
BlueprintIdentifier = "9D0B917C1F526C2D004D7E0B"
BuildableName = "a2bejwld"
BlueprintName = "a2bejwld"
ReferencedContainer = "container:a2bejwld.xcodeproj">

View File

@ -4,28 +4,25 @@
<dict>
<key>SchemeUserState</key>
<dict>
<key>a2bejwld.xcscheme</key>
<key>Binary.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
<integer>3</integer>
</dict>
<key>dummy.xcscheme</key>
<key>DiskImage.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>9D4D1AA81D6D704800D20BB8</key>
<key>a2bejwld.xcscheme_^#shared#^_</key>
<dict>
<key>primary</key>
<true/>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>9D6B472C1D3FB16F00F6D704</key>
<key>doNotBuild.xcscheme_^#shared#^_</key>
<dict>
<key>primary</key>
<true/>
<key>orderHint</key>
<integer>2</integer>
</dict>
</dict>
</dict>

View File

@ -18,22 +18,25 @@ include make/head.mk
# The name of your system or binary file to build goes here:
PGM=a2bejwld
# Set the config you are building for. See these pages for details:
# http://cc65.github.io/cc65/doc/apple2.html#s4
# http://cc65.github.io/cc65/doc/apple2enh.html#s4
#
# Uncomment the one you want below (the first one is the default):
# MACHINE = apple2
# MACHINE = apple2-dos33
# MACHINE = apple2-system
# MACHINE = apple2-loader
MACHINE = apple2-loader
# MACHINE = apple2-reboot
# MACHINE = apple2enh
# MACHINE = apple2enh-dos33
MACHINE = apple2enh-system
* MACHINE = apple2enh-loader
# MACHINE = apple2enh-system
# MACHINE = apple2enh-loader
# MACHINE = apple2enh-reboot
# Uncomment the appropriate project type. If your entry point is
# main() in a .c file, then your project type is cc65. If your
# entry point is in an assembly file, then you project type is
# ca65:
PROJECT_TYPE = cc65
# PROJECT_TYPE = ca65
# Uncomment and set this to your starting address in Apple II memory
# if necessary:
# START_ADDR = 6000
@ -43,31 +46,24 @@ MACHINE = apple2enh-system
# the one you want below (the first one is the default):
# CPU = 6502
# CPU = 65SC02
CPU = 65C02
CPU = 6502
# CPU = 65816
# Note: You can assemble for 65816 in 16-bit mode but the C compiler
# will only produce 8-bit code.
# Any *.c files in your main project directory will automatically be
# built. But, if you have subdirectories with C files in them, you
# should add them to the list of C_SRCS to build. Do that by
# uncommenting the following line and changing "someSubDir" to match
# the subdirectory you have created. Add multiple lines like this
# for each subdirectory:
# C_SRCS += $(wildcard someSubDir/*.c)
# Any *.s files in your main project directory will automatically be
# built. But, if you have subdirectories with assembly files in them,
# you should add them to the list of ASM_SRCS to build. Do that by
# uncommenting the following line and changing "someSubDir" to match
# the subdirectory you have created. Add multiple lines like this
# for each subdirectory:
# ASM_SRCS += $(wildcard someSubDir/*.s)
# Add any other directories where you are putting C or assembly source
# files to this list. Note that if you are generating source files into
# $(GENDIR), you should add $(GENDIR) to SRCDIRS here:
SRCDIRS+=
# If you have a non-standard cc65 install, you may need to change
# some of these. Uncomment the following line and change it to the
# correct path to CC65_HOME if the default is not correct:
# export CC65_HOME := /usr/local/lib/cc65
# correct path to CC65_HOME if the default is not correct. If you
# are using cc65 v2.13.3, the default is:
# /usr/local/lib/cc65
# If you are using cc65 v2.17, the default is:
# /usr/local/share/cc65
# export CC65_HOME := /path/to/your/cc65/directory
#
# If the path to the cc65 binaries is not correct, uncomment this
# line and change it:
@ -75,7 +71,7 @@ CPU = 65C02
# If you want to add arguments to the compile commandline, add them
# to this variable:
# CFLAGS += -Os
CFLAGS += -Os
# If you want to add arguments to the assembly commandline, add them
# to this variable:
@ -85,10 +81,174 @@ CPU = 65C02
# this variable:
# LDFLAGS += -v
# If you want to add arguments to the BASIC tokenizer commandline,
# add them to this valiable:
# BASICFLAGS += --optimize
# If you want to link the lores graphics driver with your executable,
# uncomment the next line.
# DRIVERS += loresgr
#
# To use the lores driver, add code which looks like this to your
# project:
#
# #include "drivers/a2_lores_drv.h"
# int main(void)
# {
# tgi_install(&a2_lores_drv);
# tgi_init();
# // Use the graphics driver
# tgi_uninstall();
# }
#
# Read the $CC65_HOME/include/tgi.h file to see what the
# driver interface provides. Also check out
# $CC65_HOME/include/apple2.h to see the colour definitions.
# If you want to link the hires graphics driver with your executable,
# uncomment the next line.
# DRIVERS += hiresgr
#
# To use the hires driver, add code which looks like this to your
# project:
#
# #include "drivers/a2_hires_drv.h"
# int main(void)
# {
# tgi_install(&a2_hires_drv);
# tgi_init();
# // Use the graphics driver
# tgi_uninstall();
# }
#
# Read the $CC65_HOME/cc65/include/tgi.h file to see what the
# driver interface provides. Also check out
# $CC65_HOME/include/apple2.h to see the colour definitions.
# If you want to link the extended memory driver with your executable,
# uncomment the next line.
# DRIVERS += auxmem
#
# To use the auxmem driver, add code which looks like this to your
# project:
#
# #include "drivers/a2_auxmem_drv.h"
# int main(void)
# {
# em_install(&a2_auxmem_drv);
# // Use the auxmem driver
# em_uninstall();
# }
#
# Read the $CC65_HOME/include/em.h file to see what the
# driver interface provides.
# If you want to link the joystick driver with your executable,
# uncomment the next line.
# DRIVERS += joystick
#
# To use the joystick driver, add code which looks like this to your
# project:
#
# #include "drivers/a2_joystick_drv.h"
# int main(void)
# {
# joy_install(&a2_joystick_drv);
# // Use the joystick driver
# joy_uninstall();
# }
#
# Read the $CC65_HOME/include/joystick.h file to see what the
# driver interface provides.
# If you want to link the mouse driver with your executable,
# uncomment the next line.
DRIVERS += mouse
#
# To use the mouse driver, add code which looks like this to your
# project:
#
# #include "drivers/a2_mouse_drv.h"
# int main(void)
# {
# mouse_install(&mouse_def_callbacks, &a2_mouse_drv);
# // Use the mouse driver
# mouse_uninstall();
# }
#
# Read the $CC65_HOME/include/mouse.h file to see what the
# driver interface provides.
# If you want to link the serial driver with your executable,
# uncomment the next line.
# DRIVERS += serial
#
# To use the serial driver, add code which looks like this to your
# project:
#
# #include "drivers/a2_serial_drv.h"
# int main(void)
# {
# ser_install(&a2_serial_drv);
# // Use the serial driver
# ser_uninstall();
# }
#
# Read the $CC65_HOME/include/serial.h file to see what the
# driver interface provides.
# If you have java installed in a non-standard location, you can set
# the path to it by uncommenting the following line:
# export JAVA=/usr/bin/java
# If you want to copy one or more files or directories to the target disk
# image, add the root directory to this variable. All files will be
# copied from the source to the target using the same path from the source.
#
# For example, if you set COPYDIRS to dir and in your project you have
# the following files:
# dir/mySystemFile
# dir/newDir/anotherFile
#
# Then, during the copy phase, mySystemFile will be copied into the root
# of the disk and anotherFile will be copied into a directory named
# newDir. The newDir directory will be created if it does not already
# exist.
#
# The name of the file to copy is checked and if it ends in:
# .as - It assumes the file is in AppleSingle format. The .as
# suffix is stripped from the name when copied to the
# disk image.
# .<char> - If the file ends with a single character which matches
# a DOS 3.3 file type (A, B, T, etc) it uses that value as
# the file type of the file copied to the disk image. The
# single character is removed from the file name.
# .<TLA> - If the file ends with a three letter alpha extension, it
# uses that TLA as the file type of the file copied to the
# disk image. The TLA is removed from the file name.
#
# If you do not provide any type information for your filenames,
# it will be copied as a binary.
#
COPYDIRS=
# Add any rules you want to execute before any compiles or assembly
# commands are called here, if any. You can generate .c, .s or .h
# files for example. You can generate data files. Whatever you
# might need.
#
# You should generate these files in the $(GENDIR) directory or
# within a subdirectory under $(GENDIR) which you create yourself.
#
# All of your commands associated with a rule _must_ start with a tab
# character. Xcode makes it a bit tough to type a tab character by
# default. Press option-tab within Xcode to insert a tab character.
gen:
# For any files you generated in the gen target above, you should
# add rules in genclean to remove those generated files when you
# clean your build.
genclean:
# Do not change anything else below here...
include make/tail.mk

View File

@ -1,427 +0,0 @@
;
; File generated by co65 v 2.13.3 using model `cc65-module'
;
.fopt compiler,"co65 v 2.13.3"
.case on
.debuginfo off
.export _a2e_stdmou_mou
;
; CODE SEGMENT
;
.segment "CODE"
_a2e_stdmou_mou:
.byte $6D
.byte $6F
.byte $75
.byte $02
.word _a2e_stdmou_mou+41
.word _a2e_stdmou_mou+170
.word _a2e_stdmou_mou+286
.word _a2e_stdmou_mou+295
.word _a2e_stdmou_mou+180
.word _a2e_stdmou_mou+238
.word _a2e_stdmou_mou+253
.word _a2e_stdmou_mou+299
.word _a2e_stdmou_mou+305
.word _a2e_stdmou_mou+309
.word _a2e_stdmou_mou+322
.word _a2e_stdmou_mou+327
.byte $40
.byte $4C
.byte $00
.byte $00
.byte $4C
.byte $00
.byte $00
.byte $4C
.byte $00
.byte $00
.byte $4C
.byte $00
.byte $00
.byte $A9
.byte $00
.byte $85
.byte <(ZEROPAGE+8)
.byte $A9
.byte $C0
.byte $85
.byte <(ZEROPAGE+9)
.byte $E6
.byte <(ZEROPAGE+9)
.byte $A5
.byte <(ZEROPAGE+9)
.byte $C9
.byte $C8
.byte $90
.byte $05
.byte $A9
.byte $04
.byte $A2
.byte $00
.byte $60
.byte $A2
.byte $03
.byte $BC
.word _a2e_stdmou_mou+421
.byte $BD
.word _a2e_stdmou_mou+425
.byte $D1
.byte <(ZEROPAGE+8)
.byte $D0
.byte $E7
.byte $CA
.byte $10
.byte $F3
.byte $A5
.byte <(ZEROPAGE+9)
.byte $8D
.word DATA+2
.byte $8D
.word DATA+7
.byte $8D
.word DATA+12
.byte $78
.byte $29
.byte $0F
.byte $8D
.word BSS+13
.byte $0A
.byte $0A
.byte $0A
.byte $0A
.byte $8D
.word DATA+9
.byte $2C
.byte $82
.byte $C0
.byte $A2
.byte $19
.byte $20
.word DATA+0
.byte $2C
.byte $80
.byte $C0
.byte $A9
.byte $01
.byte $A2
.byte $12
.byte $20
.word DATA+0
.byte $A9
.byte <(_a2e_stdmou_mou+173)
.byte $A2
.byte >(_a2e_stdmou_mou+429)
.byte $20
.word _a2e_stdmou_mou+180
.byte $AE
.word BSS+13
.byte $A9
.byte $8B
.byte $9D
.byte $78
.byte $04
.byte $A9
.byte $00
.byte $9D
.byte $78
.byte $05
.byte $A9
.byte $5F
.byte $9D
.byte $F8
.byte $04
.byte $A9
.byte $00
.byte $9D
.byte $F8
.byte $05
.byte $A2
.byte $16
.byte $20
.word DATA+0
.byte $20
.word _a2e_stdmou_mou+372
.byte $A9
.byte $09
.byte $A2
.byte $12
.byte $20
.word DATA+0
.byte $58
.byte $A9
.byte $00
.byte $A2
.byte $00
.byte $60
.byte $78
.byte $20
.word _a2e_stdmou_mou+29
.byte $A9
.byte $00
.byte $A2
.byte $12
.byte $D0
.byte $ED
.byte $85
.byte <(ZEROPAGE+8)
.byte $86
.byte <(ZEROPAGE+9)
.byte $A2
.byte $00
.byte $A0
.byte $00
.byte $20
.word _a2e_stdmou_mou+195
.byte $A2
.byte $01
.byte $A0
.byte $02
.byte $78
.byte $B1
.byte <(ZEROPAGE+8)
.byte $99
.word BSS+0
.byte $8D
.byte $78
.byte $04
.byte $C8
.byte $B1
.byte <(ZEROPAGE+8)
.byte $99
.word BSS+0
.byte $8D
.byte $78
.byte $05
.byte $C8
.byte $C8
.byte $C8
.byte $B1
.byte <(ZEROPAGE+8)
.byte $99
.word BSS+0
.byte $8D
.byte $F8
.byte $04
.byte $C8
.byte $B1
.byte <(ZEROPAGE+8)
.byte $99
.word BSS+0
.byte $8D
.byte $F8
.byte $05
.byte $8A
.byte $A2
.byte $17
.byte $D0
.byte $B3
.byte $85
.byte <(ZEROPAGE+8)
.byte $86
.byte <(ZEROPAGE+9)
.byte $A0
.byte $07
.byte $B9
.word BSS+0
.byte $91
.byte <(ZEROPAGE+8)
.byte $88
.byte $10
.byte $F8
.byte $60
.byte $AC
.word BSS+13
.byte $78
.byte $99
.byte $F8
.byte $04
.byte $8A
.byte $99
.byte $F8
.byte $05
.byte $98
.byte $AA
.byte $A0
.byte $00
.byte $B1
.byte <(ZEROPAGE+0)
.byte $C8
.byte $9D
.byte $78
.byte $04
.byte $B1
.byte <(ZEROPAGE+0)
.byte $9D
.byte $78
.byte $05
.byte $20
.word _a2e_stdmou_mou+372
.byte $A2
.byte $16
.byte $D0
.byte $83
.byte $CE
.word BSS+14
.byte $78
.byte $20
.word _a2e_stdmou_mou+29
.byte $58
.byte $60
.byte $EE
.word BSS+14
.byte $60
.byte $AD
.word BSS+12
.byte $A2
.byte $00
.byte $60
.byte $A0
.byte $03
.byte $D0
.byte $02
.byte $A0
.byte $04
.byte $78
.byte $B9
.word BSS+8
.byte $91
.byte <(ZEROPAGE+8)
.byte $88
.byte $10
.byte $F8
.byte $58
.byte $60
.byte $A9
.byte $05
.byte $A2
.byte $00
.byte $60
.byte $AD
.word BSS+13
.byte $F0
.byte $08
.byte $A2
.byte $13
.byte $20
.word DATA+0
.byte $90
.byte $02
.byte $18
.byte $60
.byte $A2
.byte $14
.byte $20
.word DATA+0
.byte $AC
.word BSS+13
.byte $B9
.byte $78
.byte $07
.byte $AA
.byte $0A
.byte $29
.byte $20
.byte $F0
.byte $02
.byte $A9
.byte $01
.byte $90
.byte $02
.byte $09
.byte $10
.byte $8D
.word BSS+12
.byte $8A
.byte $29
.byte $20
.byte $F0
.byte $27
.byte $20
.word _a2e_stdmou_mou+29
.byte $AC
.word BSS+13
.byte $B9
.byte $78
.byte $04
.byte $BE
.byte $78
.byte $05
.byte $8D
.word BSS+8
.byte $8E
.word BSS+9
.byte $20
.word _a2e_stdmou_mou+35
.byte $AC
.word BSS+13
.byte $B9
.byte $F8
.byte $04
.byte $BE
.byte $F8
.byte $05
.byte $8D
.word BSS+10
.byte $8E
.word BSS+11
.byte $20
.word _a2e_stdmou_mou+38
.byte $AD
.word BSS+14
.byte $F0
.byte $03
.byte $20
.word _a2e_stdmou_mou+32
.byte $38
.byte $60
.byte $05
.byte $07
.byte $0B
.byte $0C
.byte $38
.byte $18
.byte $01
.byte $20
.byte $00
.byte $00
.byte $00
.byte $00
.byte $17
.byte $01
.byte $BF
.byte $00
;
; DATA SEGMENT
;
.segment "DATA"
DATA:
.byte $BC
.byte $00
.byte $FF
.byte $8C
.word DATA+11
.byte $A2
.byte $FF
.byte $A0
.byte $FF
.byte $4C
.byte $FF
.byte $FF
;
; BSS SEGMENT
;
.segment "BSS"
BSS:
.res 15
;
; ZEROPAGE SEGMENT
;
.import __ZP_START__ ; Linker generated symbol
ZEROPAGE = __ZP_START__
.end

View File

@ -18,6 +18,7 @@
#include "dbllores.h"
#include "game.h"
#include "machine.h"
#include "sound.h"
#include "ui.h"
@ -28,33 +29,26 @@
#define DROP_ACCELERATION 1
#define CLEAR_GEM_SOUND_NORMAL 0
#define CLEAR_GEM_SOUND_STAR 1
#define CLEAR_GEM_SOUND_SPECIAL 2
#define CLEAR_GEM_SOUND_EXPLODE 3
#define NUM_CLEAR_GEM_SOUNDS 4
#define VERTICAL_PIXELS 48
#define HORIZONTAL_PIXELS 64
#define VERTICAL_PIXELS_PER_SQUARE (VERTICAL_PIXELS / BOARD_SIZE)
#define HORIZONTAL_PIXELS_PER_SQUARE (HORIZONTAL_PIXELS / BOARD_SIZE)
#define DRAW_GEM_AT_XY(x, y, gemType, starred) \
gTempY = y; \
gTempX = x; \
gTempGemType = gemType; \
if (starred) { \
__asm__("lda %v", gTempY); \
__asm__("ldx %v", gTempX); \
__asm__("ldy %v", gTempGemType); \
__asm__("jsr _drawAndStarGemAtXY"); \
} else { \
__asm__("lda %v", gTempY); \
__asm__("ldx %v", gTempX); \
__asm__("ldy %v", gTempGemType); \
__asm__("jsr _drawGemAtXY"); \
#define DRAW_GEM_AT_XY(x, y, gemType, starred) \
gTempY = y; \
gTempX = x; \
gTempGemType = gemType; \
if (starred) { \
__asm__ volatile("lda %v", gTempY); \
__asm__ volatile("ldx %v", gTempX); \
__asm__ volatile("ldy %v", gTempGemType); \
__asm__ volatile("jsr _drawAndStarGemAtXY"); \
} else { \
__asm__ volatile("lda %v", gTempY); \
__asm__ volatile("ldx %v", gTempX); \
__asm__ volatile("ldy %v", gTempGemType); \
__asm__ volatile("jsr _drawGemAtXY"); \
}
@ -70,7 +64,6 @@ typedef struct tStarAnimState
typedef struct tClearGemAnimState
{
uint8_t squaresToClear[NUM_SQUARES / (sizeof(uint8_t))];
uint8_t clearGemSound;
bool gotOne;
} tClearGemAnimState;
@ -105,28 +98,6 @@ static uint8_t gTempX;
static uint8_t gTempY;
static uint8_t gTempGemType;
static uint8_t gClearGemSoundFreq[NUM_CLEAR_GEM_SOUNDS][8] = {
{ // CLEAR_GEM_SOUND_NORMAL
30, 25, 20, 30, 30, 30, 30, 0 },
{ // CLEAR_GEM_SOUND_STAR
10, 9, 8, 7, 6, 5, 4, 0 },
{ // CLEAR_GEM_SOUND_SPECIAL
4, 6, 8, 10, 8, 6, 4, 0 },
{ // CLEAR_GEM_SOUND_EXPLODE
50, 60, 50, 60, 50, 60, 50, 0 }
};
static uint8_t gClearGemSoundDuration[NUM_CLEAR_GEM_SOUNDS][8] = {
{ // CLEAR_GEM_SOUND_NORMAL
10, 15, 20, 10, 10, 10, 10, 0 },
{ // CLEAR_GEM_SOUND_STAR
30, 31, 32, 33, 34, 35, 36, 0 },
{ // CLEAR_GEM_SOUND_SPECIAL
36, 34, 32, 30, 32, 34, 36, 0 },
{ // CLEAR_GEM_SOUND_EXPLODE
8, 8, 8, 8, 8, 8, 8, 0 },
};
static tClearGemHandler gClearGemHandler[] = {
explodeGemFrame1,
explodeGemFrame2,
@ -149,9 +120,9 @@ void drawGemAtSquare(tSquare square)
tempGemType = gemTypeAtSquare(square);
tempSquare = square;
__asm__("lda %v", tempSquare);
__asm__("ldy %v", tempGemType);
__asm__("jsr _drawGem");
__asm__ volatile("lda %v", tempSquare);
__asm__ volatile("ldy %v", tempGemType);
__asm__ volatile("jsr _drawGem");
}
@ -213,6 +184,7 @@ void doStarAnim(void)
void beginClearGemAnim(void)
{
memset(&gClearGemAnimState, 0, sizeof(gClearGemAnimState));
beginClearGemSound();
}
@ -235,50 +207,22 @@ void undoClearAtSquare(tSquare square)
}
void playSoundForExplodingGem(void)
{
if (gClearGemAnimState.clearGemSound < CLEAR_GEM_SOUND_EXPLODE)
gClearGemAnimState.clearGemSound = CLEAR_GEM_SOUND_EXPLODE;
}
void playSoundForStarringGem(void)
{
if (gClearGemAnimState.clearGemSound < CLEAR_GEM_SOUND_STAR)
gClearGemAnimState.clearGemSound = CLEAR_GEM_SOUND_STAR;
}
void playSoundForSpecialGem(void)
{
if (gClearGemAnimState.clearGemSound < CLEAR_GEM_SOUND_SPECIAL)
gClearGemAnimState.clearGemSound = CLEAR_GEM_SOUND_SPECIAL;
}
#undef DEBUG_CLEAR_ANIM
void endClearGemAnim(void)
{
tSquare square;
uint8_t bit;
uint8_t offset;
uint8_t *clearGemSoundFreq;
uint8_t *clearGemSoundDuration;
uint8_t frame;
if (!gClearGemAnimState.gotOne)
return;
clearGemSoundFreq = &(gClearGemSoundFreq[gClearGemAnimState.clearGemSound][0]);
clearGemSoundDuration = &(gClearGemSoundDuration[gClearGemAnimState.clearGemSound][0]);
for (frame = 0; frame < (sizeof(gClearGemHandler) / sizeof(gClearGemHandler[0])); frame++) {
bit = 1;
offset = 0;
playSound(*clearGemSoundFreq, *clearGemSoundDuration);
clearGemSoundFreq++;
clearGemSoundDuration++;
playClearGemSound(frame);
gVblWait();
for (square = 0; square < NUM_SQUARES; square++) {
@ -321,17 +265,6 @@ void swapSquares(tSquare square1, tGemType gemType1, bool starred1,
temp = y2;
y2 = y1;
y1 = temp;
#if 0
// We don't need to swap square numbers. The code from here on
// doesn't distinguish between the two square numbers. So, save
// some time and don't swap.
//
// Be careful if this assumption is no longer true.
temp = square2;
square2 = square1;
square1 = temp;
#endif
temp = gemType2;
gemType2 = gemType1;
@ -446,6 +379,7 @@ void endDropAnim(void)
tDropGemInfo *neighbourInfo;
bool done;
int8_t limit;
uint8_t numLanded;
if (!gDropGemAnimState.gotOne)
return;
@ -482,6 +416,7 @@ void endDropAnim(void)
while (true) {
done = true;
numLanded = 0;
for (square = 0; square < NUM_SQUARES; square++) {
gemInfo = &(gDropGemAnimState.gemState[square]);
@ -491,7 +426,8 @@ void endDropAnim(void)
if (gemInfo->y == gemInfo->endY) {
gemInfo->landed = true;
playSound(1, 1);
playLandingSound(numLanded);
numLanded++;
continue;
}
@ -603,4 +539,4 @@ void endDropAnim(void)
cgetc();
#endif
}
}
}

View File

@ -27,9 +27,6 @@ extern void doStarAnim(void);
extern void beginClearGemAnim(void);
extern void addClearAtSquare(tSquare square);
extern void undoClearAtSquare(tSquare square);
extern void playSoundForExplodingGem(void);
extern void playSoundForStarringGem(void);
extern void playSoundForSpecialGem(void);
extern void endClearGemAnim(void);
extern void swapSquares(tSquare square1, tGemType gemType1, bool starred1,

View File

@ -19,6 +19,16 @@ extern void __fastcall__ clearDblLoRes(void);
extern void __fastcall__ unshowDblLoRes(void);
extern void __fastcall__ mixedTextMode(void);
// The Apple //e card does not implement double lores correctly. The colours
// used on the aux bank need to be shifted but the //e card expects unshifted
// colour values (ie the same as those on the main. This function is called
// when the game detects it is not running on a //c or //gs. I would like to
// get_ostype() from the cc65 runtime but it doesn't work reliably for detecting
// the //e card. So I put in my own detection based on the technote. If the
// function detects it is runing on a //e card, it causes the graphics
// routines to use the same colours in the main and aux banks.
extern void __fastcall__ setBuggyDblLoRes(void);
extern void __fastcall__ drawBgSquare(tSquare square);
extern void __fastcall__ drawGem(tSquare square);
@ -45,4 +55,4 @@ extern void __fastcall__ drawGemAtXY(uint8_t y);
extern void __fastcall__ drawAndStarGemAtXY(uint8_t y);
#endif /* defined(__a2bejwld__dbllores__) */
#endif /* defined(__a2bejwld__dbllores__) */

View File

@ -17,6 +17,8 @@
.export _explodeGemFrame1, _explodeGemFrame2
.export _explodeGemFrame3, _explodeGemFrame4
.export _explodeGemFrame5, _explodeGemFrame6
.export _setBuggyDblLoRes
.include "apple2.inc"
@ -83,6 +85,8 @@ gemmask := $88
.proc _unshowDblLoRes
lda #0
sta WNDTOP
lda TXTSET
rts
.endproc
@ -90,7 +94,7 @@ gemmask := $88
.proc _mixedTextMode
lda MIXSET
sta LOWSCR
sta HISCR
ldx #40
lda #$a0
@L1:
@ -102,7 +106,7 @@ gemmask := $88
cpx #0
bne @L1
sta HISCR
sta LOWSCR
ldx #40
@L2:
dex
@ -115,10 +119,18 @@ gemmask := $88
lda #0
sta WNDLFT
sta CH
lda #80
sta WNDWDTH
lda #20
sta WNDTOP
sta CV
bit $C082
jsr $FC24 ; Generate text base address
bit $C080
lda #24
sta WNDBTM
@ -129,62 +141,63 @@ gemmask := $88
.proc _clearDblLoRes
sta LOWSCR
ldx #40
lda #0
@L1:
dex
stz LINE1, X
stz LINE2, X
stz LINE3, X
stz LINE4, X
stz LINE5, X
stz LINE6, X
stz LINE7, X
stz LINE8, X
stz LINE9, X
stz LINE10, X
stz LINE11, X
stz LINE12, X
stz LINE13, X
stz LINE14, X
stz LINE15, X
stz LINE16, X
stz LINE17, X
stz LINE18, X
stz LINE19, X
stz LINE20, X
stz LINE21, X
stz LINE22, X
stz LINE23, X
stz LINE24, X
sta LINE1, X
sta LINE2, X
sta LINE3, X
sta LINE4, X
sta LINE5, X
sta LINE6, X
sta LINE7, X
sta LINE8, X
sta LINE9, X
sta LINE10, X
sta LINE11, X
sta LINE12, X
sta LINE13, X
sta LINE14, X
sta LINE15, X
sta LINE16, X
sta LINE17, X
sta LINE18, X
sta LINE19, X
sta LINE20, X
sta LINE21, X
sta LINE22, X
sta LINE23, X
sta LINE24, X
bne @L1
sta HISCR
ldx #40
@L2:
dex
stz LINE1, X
stz LINE2, X
stz LINE3, X
stz LINE4, X
stz LINE5, X
stz LINE6, X
stz LINE7, X
stz LINE8, X
stz LINE9, X
stz LINE10, X
stz LINE11, X
stz LINE12, X
stz LINE13, X
stz LINE14, X
stz LINE15, X
stz LINE16, X
stz LINE17, X
stz LINE18, X
stz LINE19, X
stz LINE20, X
stz LINE21, X
stz LINE22, X
stz LINE23, X
stz LINE24, X
sta LINE1, X
sta LINE2, X
sta LINE3, X
sta LINE4, X
sta LINE5, X
sta LINE6, X
sta LINE7, X
sta LINE8, X
sta LINE9, X
sta LINE10, X
sta LINE11, X
sta LINE12, X
sta LINE13, X
sta LINE14, X
sta LINE15, X
sta LINE16, X
sta LINE17, X
sta LINE18, X
sta LINE19, X
sta LINE20, X
sta LINE21, X
sta LINE22, X
sta LINE23, X
sta LINE24, X
bne @L2
rts
@ -269,7 +282,7 @@ colorAux: .BYTE $0
ora #$80
tax
bcc @L3
bra @L9
bcs @L9
@L8:
lsr
@ -281,7 +294,8 @@ colorAux: .BYTE $0
sta gemmask
lda maskHiAddrs2,Y
sta gemmask+1
bra @L4
clc
bcc @L4
@L3:
lda maskLoAddrs,Y
@ -295,7 +309,8 @@ colorAux: .BYTE $0
lda gemAuxColours,Y
sta gemAuxColour
stz isAux
lda #0
sta isAux
lda xPos
lsr
sta xPos
@ -332,77 +347,81 @@ colorAux: .BYTE $0
; Draw the gem
ldy #0
ldx #8
ldx #0
lda #8
sta counter
@L1:
lda isAux
beq @L6
sta HISCR
lda (line1addr)
lda (line1addr,X)
and (gemmask),Y
sta square
lda (gemmask),Y
eor #$ff
and gemAuxColour
ora square
sta (line1addr)
sta (line1addr,X)
iny
lda (line2addr)
lda (line2addr,X)
and (gemmask),Y
sta square
lda (gemmask),Y
eor #$ff
and gemAuxColour
ora square
sta (line2addr)
sta (line2addr,X)
iny
lda (line3addr)
lda (line3addr,X)
and (gemmask),Y
sta square
lda (gemmask),Y
eor #$ff
and gemAuxColour
ora square
sta (line3addr)
sta (line3addr,X)
iny
lda #0
sta isAux
stz isAux
bra @L7
clc
bcc @L7
@L6:
sta LOWSCR
lda (line1addr)
lda (line1addr,X)
and (gemmask),Y
sta square
lda (gemmask),Y
eor #$ff
and gemColour
ora square
sta (line1addr)
sta (line1addr,X)
iny
lda (line2addr)
lda (line2addr,X)
and (gemmask),Y
sta square
lda (gemmask),Y
eor #$ff
and gemColour
ora square
sta (line2addr)
sta (line2addr,X)
iny
lda (line3addr)
lda (line3addr,X)
and (gemmask),Y
sta square
lda (gemmask),Y
eor #$ff
and gemColour
ora square
sta (line3addr)
sta (line3addr,X)
iny
inc line1addr
@ -412,7 +431,7 @@ colorAux: .BYTE $0
inc isAux
@L7:
dex
dec counter
beq @L2
jmp @L1
@ -426,6 +445,7 @@ square: .BYTE $0
gemColour: .BYTE $0
gemAuxColour: .BYTE $0
isAux: .BYTE $0
counter: .BYTE $0
.endproc
@ -473,14 +493,16 @@ square: .BYTE $0
tax
bcc @L1
lda #$f0
bra @L2
clc
bcc @L2
@L4:
lsr
tax
bcc @L1
lda #$f0
bra @L2
clc
bcc @L2
@L1:
lda #$0f
@L2:
@ -507,9 +529,10 @@ square: .BYTE $0
lda lineHiAddrs,X
sta line2addr+1
ldx #0
lda starVal
ora (line2addr)
sta (line2addr)
ora (line2addr,X)
sta (line2addr,X)
rts
; Locals
@ -569,20 +592,22 @@ square: .BYTE $0
.proc _drawScore
; A is a number from 0 to 24
tay
sta score
ldx #24
lda #$dd
ldy #0
sta color
sta LOWSCR
@L1:
dex
bmi @L2
cpy #0
lda score
cmp #0
bne @L3
lda #$22
sta color
@L3:
dey
dec score
lda lineLoAddrs,X
clc
@ -592,9 +617,10 @@ square: .BYTE $0
sta line1addr+1
lda color
sta (line1addr)
sta (line1addr),Y
bra @L1
clc
bcc @L1
@L2:
rts
@ -602,6 +628,7 @@ square: .BYTE $0
; Locals
color: .BYTE $0
score: .BYTE $0
.endproc
.proc _explodeGemFrame1
@ -884,6 +911,60 @@ xPos: .BYTE $0
square: .BYTE $0
.endproc
.proc _setBuggyDblLoRes
; Unfortunately, there is a bug in get_ostype() in cc65 with detecting the Apple //e card.
; There is a version byte in the ROM of the Apple //e card and the tech note describing
; machine detection implies it is 0. The first version of the Mac SW for the card maybe used
; 0 but for sure there are versions 2 and 3 out there also. But cc65 tests for 0 specifically.
; That causes it to detect a Apple //e card with version greater than 0 as an Apple //e
; enhanced.
;
; Combine this with the fact that double lores graphics on the //e card is broken and I have
; a problem. So, rather than use get_ostype() to detect the //e card, I am detecting it myself
; below based on what the tech note says. If I find the game is running on the //e card, then
; I remap the colours used in aux memory to look correct on that HW.
;
; The bug in cc65 has been sent as a pull request back to that project for a fix here:
; https://github.com/cc65/cc65/pull/1013
; Once this is fixed and I adopt a newer version of cc65 in this project, I can clean up the
; HW detection problem.
;
; Next I will need to contact Apple to get a fix for the double lores graphics on the //e card...
bit $c082
lda $fbb3
cmp #$6
bne @L3
lda $fbc0
cmp #$e0
bne @L3
lda $fbdd
cmp #$02
bne @L3
ldx #63
@L1:
lda bgColor,X
sta bgAuxColor,X
dex
bpl @L1
ldx #8
@L2:
lda gemColours,X
sta gemAuxColours,X
dex
bpl @L2
@L3:
bit $c080
rts
.endproc
.DATA

View File

@ -26,10 +26,14 @@
#define STARTING_GEMS_PER_POINT 3
#define MAX_GEMS_PER_POINT 20
#define SCORE_FOR_GOOD 9
#define SCORE_FOR_EXCELLENT 15
#define SCORE_FOR_INCREDIBLE 25
#define GEM_TYPE_AT_SQUARE(square) gGameState.squareStates[square].gemType
#define GEM_STARRED_AT_SQUARE(square) gGameState.squareStates[square].isStarred
#define SAVE_GAME_FILE "a2bejwld.game"
#define SAVE_GAME_FILE "A2BEJWLD.GAME"
// Typedefs
@ -55,6 +59,10 @@ typedef struct tGameState {
static tGameState gGameState;
static tGameCallbacks *gGameCallbacks = NULL;
static tScore gPerMoveScore = 0;
static bool gSaidGood = false;
static bool gSaidExcellent = false;
static bool gSaidIncredible = false;
// Implementation
@ -72,6 +80,21 @@ static void incrementScore(void)
gGameCallbacks->scoreCallback(gGameState.score);
}
}
gPerMoveScore++;
if (gPerMoveScore > SCORE_FOR_INCREDIBLE) {
if (!gSaidIncredible) {
gSaidIncredible = gGameCallbacks->speakIncredible();
}
} else if (gPerMoveScore > SCORE_FOR_EXCELLENT) {
if (!gSaidExcellent) {
gSaidExcellent = gGameCallbacks->speakExcellent();
}
} else if (gPerMoveScore > SCORE_FOR_GOOD) {
if (!gSaidGood) {
gSaidGood = gGameCallbacks->speakGood();
}
}
}
@ -691,6 +714,11 @@ bool moveSquareInDir(tSquare square, tDirection dir)
return true;
}
gPerMoveScore = 0;
gSaidGood = false;
gSaidExcellent = false;
gSaidIncredible = false;
gGameCallbacks->beginClearGemAnim();
if (actOnMatchAtSquare(square, false))
goodMove = true;
@ -701,7 +729,6 @@ bool moveSquareInDir(tSquare square, tDirection dir)
if (!goodMove) {
doSwapSquares(square, otherSquare, true);
} else {
while (explodeGems())
;
@ -769,4 +796,4 @@ bool loadGame(void)
deleteGame();
return true;
}
}

View File

@ -50,6 +50,10 @@ typedef struct tGameCallbacks {
void (*dropSquareFromTo)(tSquare srcSquare, tSquare tgtSquare, tGemType gemType, bool starred);
void (*dropSquareFromOffscreen)(tSquare tgtSquare, tGemType gemType, bool starred);
void (*endDropAnim)(void);
bool (*speakGood)(void);
bool (*speakExcellent)(void);
bool (*speakIncredible)(void);
} tGameCallbacks;

View File

@ -32,7 +32,6 @@ static tJoyCallbacks *gJoyCallbacks = NULL;
static tJoyState gJoyState = {
JOY_POS_CENTER,
false,
false
};
@ -52,43 +51,41 @@ void initJoystick(tJoyCallbacks *callbacks)
}
bool isButtonPressed(tJoyButtonNum buttonNum)
bool isButtonPressed(void)
{
if (buttonNum == JOY_BUTTON_0) {
__asm__("LDA %w", BTN0);
__asm__("STA %v", gJoystickTemp);
} else if (buttonNum == JOY_BUTTON_1) {
__asm__("LDA %w", BTN1);
__asm__("STA %v", gJoystickTemp);
} else {
return false;
}
__asm__ volatile("LDA %w", BTN0);
__asm__ volatile("STA %v", gJoystickTemp);
if (gJoystickTemp > 127)
return true;
__asm__ volatile("LDA %w", BTN1);
__asm__ volatile("STA %v", gJoystickTemp);
return ((gJoystickTemp > 127) ? true : false);
}
static uint8_t joystickLeftRight(void)
{
__asm__("BIT %w", ROM_SWITCH);
__asm__("LDX #0");
__asm__("SEI");
__asm__("JSR %w", PREAD);
__asm__("CLI");
__asm__("STY %v", gJoystickTemp);
__asm__("BIT %w", RAM_SWITCH);
__asm__ volatile("BIT %w", ROM_SWITCH);
__asm__ volatile("LDX #0");
__asm__ volatile("SEI");
__asm__ volatile("JSR %w", PREAD);
__asm__ volatile("CLI");
__asm__ volatile("STY %v", gJoystickTemp);
__asm__ volatile("BIT %w", RAM_SWITCH);
return gJoystickTemp;
}
static uint8_t joystickUpDown(void)
{
__asm__("BIT %w", ROM_SWITCH);
__asm__("LDX #1");
__asm__("SEI");
__asm__("JSR %w", PREAD);
__asm__("CLI");
__asm__("STY %v", gJoystickTemp);
__asm__("BIT %w", RAM_SWITCH);
__asm__ volatile("BIT %w", ROM_SWITCH);
__asm__ volatile("LDX #1");
__asm__ volatile("SEI");
__asm__ volatile("JSR %w", PREAD);
__asm__ volatile("CLI");
__asm__ volatile("STY %v", gJoystickTemp);
__asm__ volatile("BIT %w", RAM_SWITCH);
return gJoystickTemp;
}
@ -123,8 +120,7 @@ static void readJoystickState(tJoyState *state)
pos = JOY_POS_RIGHT;
}
state->button0 = isButtonPressed(0);
state->button1 = isButtonPressed(1);
state->button = isButtonPressed();
if (axisUpDown < LOWER_THRESHOLD) {
switch (pos) {
@ -157,8 +153,7 @@ static void readJoystickState(tJoyState *state)
static bool joystickStateChanged(tJoyState *state1, tJoyState *state2) {
if ((state1->position != state2->position) ||
(state1->button0 != state2->button0) ||
(state1->button1 != state2->button1)) {
(state1->button != state2->button)) {
return true;
}
return false;

View File

@ -26,21 +26,14 @@
#define JOY_POS_DOWN_RIGHT 8
#define NUM_JOY_POSITIONS 9
#define JOY_BUTTON_0 0
#define JOY_BUTTON_1 1
#define NUM_JOY_BUTTONS 2
// Typedefs
typedef int8_t tJoyButtonNum;
typedef int8_t tJoyPos;
typedef struct tJoyState {
tJoyPos position;
bool button0;
bool button1;
bool button;
} tJoyState;
typedef struct tJoyCallbacks {
@ -64,6 +57,6 @@ typedef struct tJoyCallbacks {
extern void initJoystick(tJoyCallbacks *callbacks);
extern bool isButtonPressed(tJoyButtonNum buttonNum);
extern bool isButtonPressed(void);
extern bool pollJoystick(void);

View File

@ -11,6 +11,7 @@
#include <stdbool.h>
#include <stdint.h>
#include "dbllores.h"
#include "machine.h"
#include "vbl.h"
@ -32,24 +33,9 @@ static tMachineGSSpeed gOldSpeed = GS_SPEED_SLOW;
// Implementation
static bool machineIs2c(void)
static bool machineIs2GS(uint8_t machineType)
{
switch (get_ostype()) {
case APPLE_IIC:
case APPLE_IIC35:
case APPLE_IICEXP:
case APPLE_IICREV:
case APPLE_IICPLUS:
return true;
}
return false;
}
static bool machineIs2GS(void)
{
switch (get_ostype()) {
switch (machineType) {
case APPLE_IIGS:
case APPLE_IIGS1:
case APPLE_IIGS3:
@ -86,18 +72,25 @@ static tMachineGSSpeed setGSSpeed(tMachineGSSpeed newSpeed)
void initMachine(void)
{
if (machineIs2c()) {
uint8_t machineType = get_ostype();
if ((machineType == APPLE_IIC) ||
(machineType == APPLE_IIC35) ||
(machineType == APPLE_IICEXP) ||
(machineType == APPLE_IICREV) ||
(machineType == APPLE_IICPLUS)) {
gVblWait = vblWait2c;
} else if (machineIs2GS()) {
} else if (machineIs2GS(machineType)) {
vblInit2gs();
gOldSpeed = setGSSpeed(GS_SPEED_SLOW);
}
} else
setBuggyDblLoRes();
}
void uninitMachine(void)
{
if (machineIs2GS()) {
if (machineIs2GS(get_ostype())) {
setGSSpeed(gOldSpeed);
}
}
}

View File

@ -9,6 +9,7 @@
#include <stdbool.h>
#include <stdlib.h>
#include "ui.h"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

34
a2bejwld/make/bt Executable file
View File

@ -0,0 +1,34 @@
#!/bin/sh
if [ -z "$JAVA" ]
then
for item in "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home" /Library/Java/JavaVirtualMachines/*/Contents/Home /usr
do
if [ -x "$item/bin/java" ]
then
JAVA="$item/bin/java"
break
fi
done
fi
if [ -z "$JAVA" ]
then
echo Cannot find a path to a Java runtime.
echo Go to https://java.com/download if you do not have Java.
echo If you do have Java, you may need to uncomment the JAVA
echo line in the Makefile and set it to the path for your
echo Java runtime binary.
exit 1
fi
INPUTFILE=$1
shift
tr -d '©' < "$INPUTFILE" > /tmp/bt_filtered.$$
"$JAVA" -jar make/bastokenizer-tools-bt-0.2.0.jar $* /tmp/bt_filtered.$$
RESULT=$?
rm /tmp/bt_filtered.$$
exit $RESULT

View File

@ -1,8 +1,13 @@
#!/bin/sh
merlinStartAddr() {
awk '$1 ~ /^[oO][rR][gG]$/{print $2}' linkscript.s | sed 's/^[0$]*//'
}
if [ $# -lt 5 ]
then
echo USAGE: $0 '<AppleCommander> <machine> <diskimage> <binary>'
echo USAGE: $0 '<AppleCommander> <machine> <diskimage> <binary> <startaddress> <otherfilesordirs...>'
exit 1
fi
@ -29,16 +34,21 @@ then
fi
APPLECOMMANDER=$1
MACHINE=$2
DISKIMAGE=$3
PROGRAM=$4
STARTADDR=`echo $5 | sed 's/^0*//'`
shift
if [ ! -f "$PROGRAM" ]
then
echo "Cannot file executable $PROGRAM"
exit 1
fi
MACHINE=$1
shift
DISKIMAGE=$1
shift
PROGRAM=$1
shift
STARTADDR=`echo $1 | sed 's/^0*//'`
shift
SOURCEFILE=$PROGRAM
case "$MACHINE" in
apple2)
@ -46,8 +56,10 @@ case "$MACHINE" in
DELETELOADER=1
RENAMELOADER=0
DELETEBASIC=0
COPYBINARY=1
HASHEADER=1
FILETYPE="bin"
BASICFILETYPE="bas"
TARGETFILE=`basename $PROGRAM`
MAXFILENAMELEN=15
;;
@ -57,8 +69,10 @@ case "$MACHINE" in
DELETELOADER=1
RENAMELOADER=0
DELETEBASIC=0
COPYBINARY=1
HASHEADER=1
FILETYPE="bin"
BASICFILETYPE="bas"
TARGETFILE=`basename $PROGRAM`
MAXFILENAMELEN=15
;;
@ -68,8 +82,10 @@ case "$MACHINE" in
DELETELOADER=0
RENAMELOADER=0
DELETEBASIC=0
COPYBINARY=1
HASHEADER=1
FILETYPE="bin"
FILETYPE="B"
BASICFILETYPE="A"
TARGETFILE=`basename $PROGRAM`
MAXFILENAMELEN=30
;;
@ -79,8 +95,10 @@ case "$MACHINE" in
DELETELOADER=0
RENAMELOADER=0
DELETEBASIC=0
COPYBINARY=1
HASHEADER=1
FILETYPE="bin"
FILETYPE="B"
BASICFILETYPE="A"
TARGETFILE=`basename $PROGRAM`
MAXFILENAMELEN=30
;;
@ -90,8 +108,10 @@ case "$MACHINE" in
DELETELOADER=1
RENAMELOADER=0
DELETEBASIC=1
COPYBINARY=1
HASHEADER=0
FILETYPE="sys"
BASICFILETYPE="bas"
TARGETFILE=`basename $PROGRAM`.system
MAXFILENAMELEN=15
;;
@ -101,8 +121,10 @@ case "$MACHINE" in
DELETELOADER=1
RENAMELOADER=0
DELETEBASIC=1
COPYBINARY=1
HASHEADER=0
FILETYPE="sys"
BASICFILETYPE="bas"
TARGETFILE=`basename $PROGRAM`.system
MAXFILENAMELEN=15
;;
@ -112,8 +134,10 @@ case "$MACHINE" in
DELETELOADER=0
RENAMELOADER=1
DELETEBASIC=1
COPYBINARY=1
HASHEADER=1
FILETYPE="bin"
BASICFILETYPE="bas"
TARGETFILE=`basename $PROGRAM`
MAXFILENAMELEN=15
;;
@ -123,8 +147,10 @@ case "$MACHINE" in
DELETELOADER=0
RENAMELOADER=1
DELETEBASIC=1
COPYBINARY=1
HASHEADER=1
FILETYPE="bin"
BASICFILETYPE="bas"
TARGETFILE=`basename $PROGRAM`
MAXFILENAMELEN=15
;;
@ -134,8 +160,10 @@ case "$MACHINE" in
DELETELOADER=0
RENAMELOADER=1
DELETEBASIC=1
COPYBINARY=1
HASHEADER=1
FILETYPE="bin"
BASICFILETYPE="bas"
TARGETFILE=`basename $PROGRAM`
MAXFILENAMELEN=15
;;
@ -145,10 +173,68 @@ case "$MACHINE" in
DELETELOADER=0
RENAMELOADER=1
DELETEBASIC=1
COPYBINARY=1
HASHEADER=1
FILETYPE="bin"
BASICFILETYPE="bas"
TARGETFILE=`basename $PROGRAM`
MAXFILENAMELEN=8
MAXFILENAMELEN=15
;;
apple2-basic)
TEMPLATE="make/prodos_template.dsk"
DELETELOADER=1
RENAMELOADER=0
DELETEBASIC=0
COPYBINARY=0
FILETYPE="bas"
BASICFILETYPE="bas"
TARGETFILE=`basename $PROGRAM`
SOURCEFILE=${PROGRAM}.tok
MAXFILENAMELEN=15
;;
apple2-dos33-basic)
TEMPLATE="make/dos33_template.dsk"
DELETELOADER=0
RENAMELOADER=0
DELETEBASIC=0
COPYBINARY=0
FILETYPE="A"
BASICFILETYPE="A"
TARGETFILE=`basename $PROGRAM`
SOURCEFILE=${PROGRAM}.tok
MAXFILENAMELEN=30
;;
apple2-merlin)
TEMPLATE="make/prodos_template.dsk"
DELETELOADER=1
RENAMELOADER=0
DELETEBASIC=0
COPYBINARY=1
HASHEADER=0
FILETYPE="bin"
BASICFILETYPE="bas"
TARGETFILE=`basename $PROGRAM`
MAXFILENAMELEN=15
STARTADDR=`merlinStartAddr`
;;
apple2-dos33-merlin)
TEMPLATE="make/dos33_template.dsk"
DELETELOADER=0
RENAMELOADER=0
DELETEBASIC=0
COPYBINARY=1
HASHEADER=0
FILETYPE="B"
BASICFILETYPE="A"
TARGETFILE=`basename $PROGRAM`
MAXFILENAMELEN=30
STARTADDR=`merlinStartAddr`
;;
*)
@ -157,6 +243,19 @@ case "$MACHINE" in
;;
esac
STARTARG=""
if [ ! -z "$STARTADDR" ]
then
STARTARG="0x$STARTADDR"
fi
if [ ! -f "$SOURCEFILE" ]
then
echo "Cannot file executable $SOURCEFILE"
exit 1
fi
if [ ${#TARGETFILE} -gt $MAXFILENAMELEN ]
then
echo "The filename $TARGETFILE exceeds the max name length of the filesystem ($MAXFILENAMELEN)"
@ -185,7 +284,7 @@ then
rm -f "$DISKIMAGE"
exit 1
fi
"$JAVA" -jar "$APPLECOMMANDER" -e "$DISKIMAGE" LOADER.SYSTEM | "$JAVA" -jar "$APPLECOMMANDER" -p "$DISKIMAGE" "$LOADERFILE" sys
"$JAVA" -jar "$APPLECOMMANDER" -g "$DISKIMAGE" LOADER.SYSTEM | "$JAVA" -jar "$APPLECOMMANDER" -p "$DISKIMAGE" "$LOADERFILE" sys
"$JAVA" -jar "$APPLECOMMANDER" -d "$DISKIMAGE" LOADER.SYSTEM
fi
@ -194,15 +293,81 @@ then
"$JAVA" -jar "$APPLECOMMANDER" -d "$DISKIMAGE" BASIC.SYSTEM
fi
if [ $HASHEADER -eq 1 ]
if [ $COPYBINARY -eq 1 ]
then
HDR_STARTADDR=`od -t x2 -N 2 < "$PROGRAM" | head -1 | awk '{print $2}' | sed 's/^0*//'`
if [ "$HDR_STARTADDR" = "$STARTADDR" ]
if [ "$CC65_SUPPORTS_APPLE_SINGLE" -eq 1 ]
then
dd if="$PROGRAM" bs=4 skip=1 | "$JAVA" -jar "$APPLECOMMANDER" -p "$DISKIMAGE" "$TARGETFILE" $FILETYPE 0x$STARTADDR
else
"$JAVA" -jar "$APPLECOMMANDER" -p "$DISKIMAGE" "$TARGETFILE" $FILETYPE 0x$STARTADDR < "$PROGRAM"
"$JAVA" -jar "$APPLECOMMANDER" -as "$DISKIMAGE" "$TARGETFILE" < "$SOURCEFILE"
elif [ $HASHEADER -eq 1 ]
then
HDR_STARTADDR=`od -t x2 -N 2 < "$SOURCEFILE" | head -1 | awk '{print $2}' | sed 's/^0*//'`
if [ "$HDR_STARTADDR" = "$STARTADDR" ]
then
dd if="$SOURCEFILE" bs=4 skip=1 | "$JAVA" -jar "$APPLECOMMANDER" -p "$DISKIMAGE" "$TARGETFILE" $FILETYPE $STARTARG
else
"$JAVA" -jar "$APPLECOMMANDER" -p "$DISKIMAGE" "$TARGETFILE" $FILETYPE $STARTARG < "$SOURCEFILE"
fi
else
"$JAVA" -jar "$APPLECOMMANDER" -p "$DISKIMAGE" "$TARGETFILE" $FILETYPE $STARTARG < "$SOURCEFILE"
fi
else
"$JAVA" -jar "$APPLECOMMANDER" -p "$DISKIMAGE" "$TARGETFILE" $FILETYPE < "$PROGRAM"
fi
for ITEM in $*
do
# If this is a file matching *.tok, then this is an Applesoft BASIC file
# to copy to the disk image.
if [ -f "$ITEM" ] && echo "$ITEM" | grep '\.tok$' > /dev/null
then
DESTFILE=`basename "$ITEM" | sed 's/\.tok$//'`
"$JAVA" -jar "$APPLECOMMANDER" -p "$DISKIMAGE" "$DESTFILE" "$BASICFILETYPE" 0x801 < "$ITEM"
continue
fi
if [ ! -d "$ITEM" ]
then
echo Unable to find directory $ITEM
exit 1
fi
OLDPWD=`pwd`
cd $ITEM
find . -type f -print | while read FILE
do
TRANSFERARG=-p
FILETYPE=bin
DESTFILE=`echo $FILE | sed 's/^\.\///'`
if echo $FILE | egrep '\.as$' > /dev/null
then
# If the file ends with .as, this means the input is AppleSingle format.
# Strip the .as from the end of the file name and set the args to do
# an AppleSingle transfer.
TRANSFERARG=-as
FILETYPE=""
DESTFILE=`echo $DESTFILE | sed 's/\.as$//'`
elif echo $FILE | egrep '\.[ABITSRab]$' > /dev/null
then
# If the file ends with a single character DOS 3.3 file type, then use
# that as the file type.
FILETYPE=`echo $DESTFILE | awk -F. '{print $NF}'`
DESTFILE=`echo $DESTFILE | sed 's/\.[ABITSRab]$//'`
elif echo $FILE | egrep '\.[a-zA-Z][a-zA-Z][a-zA-Z]$' > /dev/null
then
# If the file ends with a three letter extension, use that as
# the file type.
FILETYPE=`echo $DESTFILE | awk -F. '{print $NF}'`
DESTFILE=`echo $DESTFILE | sed 's/\.[a-zA-Z][a-zA-Z][a-zA-Z]$//'`
fi
# If the file type is text, convert the line feeds to carriage return
if [ $FILETYPE = txt ] || [ $FILETYPE = T ]
then
tr '\n' '\r' < $FILE | "$JAVA" -jar "$OLDPWD/$APPLECOMMANDER" $TRANSFERARG "$DISKIMAGE" "$DESTFILE" $FILETYPE
else
"$JAVA" -jar "$OLDPWD/$APPLECOMMANDER" $TRANSFERARG "$DISKIMAGE" "$DESTFILE" $FILETYPE < $FILE
fi
done
cd "$OLDPWD"
done

59
a2bejwld/make/errorFilter.sh Executable file
View File

@ -0,0 +1,59 @@
#!/bin/sh
PWD=`pwd`
$* 2> /tmp/errors.$$
RESULT=$?
if [ $RESULT -ne 0 ]
then
exec /usr/bin/perl -x $0 $RESULT /tmp/errors.$$ "$PWD"
fi
exit 0
#!/usr/bin/perl
use strict;
my $result = $ARGV[0];
my $filename = $ARGV[1];
my $pwd = $ARGV[2];
open(FILE, "<$filename") || die "$0: Unable to open file, $!";
my $unresolvedRefError = undef;
while (<FILE>) {
chomp;
if (defined $unresolvedRefError) {
if (m/^ ([^(]+)\(([0-9]+)\)/) {
my $file = $1;
my $lineno = $2;
if (! -f "$pwd/$file") {
$file =~ s/\.s$/.c/;
}
$_ = "$pwd/$file:$lineno:0: error: $unresolvedRefError";
} else {
$unresolvedRefError = undef;
}
}
if (m/^(Unresolved external .* referenced) in:/) {
$unresolvedRefError = $1;
$_ = "";
} elsif (m/^([^(]+)\(([0-9]+)\):(.*)$/) {
my $file = $1;
my $lineno = $2;
my $error = $3;
$_ = "$pwd/$file:$lineno:0: error: $error";
}
print STDERR "$_\n";
}
unlink($filename);
exit($result);

View File

@ -10,21 +10,74 @@
# http://www.quinndunki.com/blondihacks
#
export CC65_HOME := /usr/local/lib/cc65
CC65_BIN=/usr/local/bin
CC65_BIN = /usr/local/bin
ifneq ($(wildcard /usr/local/lib/cc65),)
export CC65_HOME := /usr/local/lib/cc65
else
export CC65_HOME := /usr/local/share/cc65
endif
CL65=$(CC65_BIN)/cl65
CA65=$(CC65_BIN)/ca65
CC65=$(CC65_BIN)/cc65
CO65=$(CC65_BIN)/co65
MERLIN_DIR=/usr/local
export MERLIN_BIN=$(MERLIN_DIR)/bin/Merlin32
export MERLIN_LIB=$(MERLIN_DIR)/lib/Merlin
MERLIN_ASM=make/merlin-asm
AC=make/AppleCommander.jar
C_SRCS=$(wildcard *.c)
ASM_SRCS=$(wildcard *.s)
SRCDIRS=.
# Check for Xcode build variables for the locations of build outputs and fall back
# to the current directory if not set.
ifeq ($(OBJECT_FILE_DIR),)
OBJDIR=.
else
export OBJECT_FILE_DIR
OBJDIR=$(OBJECT_FILE_DIR)
endif
ifeq ($(DERIVED_SOURCES_DIR),)
GENDIR=.
else
export DERIVED_SOURCES_DIR
GENDIR=$(DERIVED_SOURCES_DIR)
endif
ifeq ($(TARGET_BUILD_DIR),)
TARGETDIR=.
else
export TARGET_BUILD_DIR
TARGETDIR=$(TARGET_BUILD_DIR)
endif
MACHINE=apple2
CPU=6502
CFLAGS=
ASMFLAGS=
LDFLAGS=
DRIVERS=
DRVDIR=$(GENDIR)/drivers
MKDIR=mkdir -p
XCODE_PATH=/Applications/Xcode.app
XCODE_INFO=$(XCODE_PATH)/Contents/Info.plist
CC65_PLUGIN_PATH=$(HOME)/Library/Developer/Xcode/Plug-ins/cc65.ideplugin
CC65_PLUGIN_INFO=$(CC65_PLUGIN_PATH)/Contents/Info.plist
XCODE_PLUGIN_COMPATIBILITY=DVTPlugInCompatibilityUUID
.PHONY: all gen genclean
all:
@make gen
@make build

Binary file not shown.

View File

@ -10,98 +10,280 @@
# http://www.quinndunki.com/blondihacks
#
export PATH := $(PATH):$(CC65_BIN)
BUILD_TYPE := $(shell if echo $(MACHINE) | grep -q -- -basic; then echo basic; elif echo $(MACHINE) | grep -q -- -merlin; then echo merlin; else echo cc65; fi)
CWD=$(shell pwd)
C_OBJS=$(C_SRCS:.c=.o)
C_DEPS=$(C_SRCS:.c=.u)
ASM_OBJS=$(ASM_SRCS:.s=.o)
ASM_LSTS=$(ASM_SRCS:.s=.lst)
OBJS=$(C_OBJS) $(ASM_OBJS)
MAPFILE=$(PGM).map
DISKIMAGE=$(PGM).dsk
LINK_ARGS=
DISKIMAGE=$(TARGETDIR)/$(PGM).dsk
EXECCMD=
ALLTARGET=$(DISKIMAGE)
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
ALLTARGET=execute
endif
vpath $(GENDIR)
ifneq ($(START_ADDR),)
# If the MACHINE is set to an option which does not support a variable start
# address, then error.
BASIC_SRCS=$(patsubst $(GENDIR)/%, %, $(patsubst ./%, %, $(wildcard $(addsuffix /*.bas, $(SRCDIRS)))))
BASIC_OBJS=$(patsubst %.bas, $(TARGETDIR)/%.tok, $(BASIC_SRCS))
ifeq ($(BUILD_TYPE),cc65)
export PATH := $(PATH):$(CC65_BIN)
# By default, use the a2 drivers. If the machine is one of the enhanced
# targets though, use the a2e drivers.
DRV_BASE_MACHINE=a2
BASE_MACHINE = apple2
ifneq ($(filter $(MACHINE), apple2enh apple2enh-dos33 apple2enh-system apple2enh-loader apple2enh-reboot),)
DRV_BASE_MACHINE=a2e
BASE_MACHINE = apple2enh
endif
export CC65_SUPPORTS_APPLE_SINGLE=1
CC65_CREATE_DEP_ARG=--create-dep $(@:.o=.u)
CC65_LIST_ARG=-l $(@:.o=.lst)
CC65_DRV_DIR=$(CC65_HOME)/target/$(BASE_MACHINE)/drv
MACHCONFIG= -t $(BASE_MACHINE)
ifneq ($(filter $(MACHINE), apple2-system apple2enh-system),)
$(error You cannot change start address with this machine type)
MACHCONFIG += -C $(BASE_MACHINE)-system.cfg
else
ifeq ($(PROJECT_TYPE),ca65)
MACHCONFIG += -C $(BASE_MACHINE)-asm.cfg
LDFLAGS += -u __EXEHDR__
else
MACHCONFIG += -C $(BASE_MACHINE).cfg
endif
endif
CFLAGS+=-I $(GENDIR)
ifneq ($(DRIVERS),)
SRCDIRS+=$(DRVDIR)
endif
C_SRCS=$(patsubst $(GENDIR)/%, %, $(patsubst ./%, %, $(wildcard $(addsuffix /*.c, $(SRCDIRS)))))
C_OBJS=$(patsubst %.c, $(OBJDIR)/%.o, $(C_SRCS))
C_DEPS=$(patsubst %.c, $(OBJDIR)/%.u, $(C_SRCS))
ASM_SRCS=$(patsubst $(GENDIR)/%, %, $(patsubst ./%, %, $(wildcard $(addsuffix /*.s, $(SRCDIRS)))))
ASM_OBJS=$(patsubst %.s, $(OBJDIR)/%.o, $(ASM_SRCS))
ASM_LSTS=$(patsubst %.s, $(OBJDIR)/%.lst, $(ASM_SRCS))
MAPFILE=$(TARGETDIR)/$(PGM).map
ifneq ($(START_ADDR),)
# If the MACHINE is set to an option which does not support a variable
# start address, then error.
ifneq ($(filter $(MACHINE), apple2-system apple2enh-system),)
$(error You cannot change start address with this machine type)
endif
else
# If not set, then use the default for the config as per cc65
# documentation
ifneq ($(filter $(MACHINE), apple2 apple2-dos33 apple2enh apple2enh-dos33),)
START_ADDR=803
endif
ifneq ($(filter $(MACHINE), apple2-system apple2enh-system),)
START_ADDR=2000
endif
ifneq ($(filter $(MACHINE), apple2-loader apple2-reboot apple2enh-loader apple2enh-reboot),)
START_ADDR=800
endif
endif
LDFLAGS += --start-addr 0x$(START_ADDR)
ifneq ($(filter $(MACHINE), apple2 apple2enh apple2-dos33 apple2enh-dos33),)
EXECCMD=$(shell echo brun $(PGM) | tr '[a-z]' '[A-Z]')
endif
else
# If not set, then use the default for the config as per cc65 documentation
ifneq ($(filter $(MACHINE), apple2 apple2-dos33 apple2enh apple2enh-dos33),)
START_ADDR=803
endif
ifneq ($(filter $(MACHINE), apple2-system apple2enh-system),)
START_ADDR=2000
endif
ifneq ($(filter $(MACHINE), apple2-loader apple2-reboot apple2enh-loader apple2enh-reboot),)
START_ADDR=800
endif
endif
LDFLAGS += --start-addr 0x$(START_ADDR)
C_OBJS=
C_DEPS=
ifneq ($(filter $(MACHINE), apple2 apple2enh apple2-dos33 apple2enh-dos33),)
ASM_OBJS=
ASM_LSTS=
endif
ifeq ($(BUILD_TYPE),merlin)
ASM_SRCS=$(patsubst ./%, %, $(wildcard $(addsuffix /*.s, $(SRCDIRS))))
MAPFILE=$(TARGETDIR)/_Output.txt
EXECCMD=$(shell echo brun $(PGM) | tr '[a-z]' '[A-Z]')
endif
MACHCONFIG= -t apple2
ifneq ($(filter $(MACHINE), apple2enh apple2apple2enh-dos33 apple2enh-system apple2enh-loader apple2enh-reboot),)
MACHCONFIG= -t apple2enh
ifeq ($(BUILD_TYPE),basic)
MAPFILE=
EXECCMD=$(shell echo run $(PGM) | tr '[a-z]' '[A-Z]')
endif
ifeq ($(filter $(MACHINE), apple2 apple2enh),)
MACHCONFIG += -C $(MACHINE).cfg
OBJS=$(C_OBJS) $(ASM_OBJS)
ALLTARGET=$(DISKIMAGE)
.PHONY: build execute clean cleandrivers xcodefix
build: $(ALLTARGET)
$(DISKIMAGE): $(TARGETDIR)/$(PGM) $(BASIC_OBJS)
make/createDiskImage $(AC) $(MACHINE) "$(DISKIMAGE)" "$(TARGETDIR)/$(PGM)" "$(START_ADDR)" $(BASIC_OBJS) $(COPYDIRS)
execute: $(DISKIMAGE)
osascript make/V2Make.scpt "$(TARGETDIR)" "$(PGM)" "$(CWD)/make/DevApple.vii" "$(EXECCMD)"
$(TARGETDIR)/%.tok: %.bas
$(MKDIR) `dirname $@`
make/bt $< $(BASICFLAGS) -o $@
ifneq ($(DRIVERS),)
cleandrivers:
rm -Rf "$(DRVDIR)"
else
cleandrivers:
endif
.PHONY: all execute clean
all: $(ALLTARGET)
clean:
rm -f "$(PGM)"
rm -f $(OBJS)
rm -f $(C_DEPS)
rm -f $(MAPFILE)
rm -f $(ASM_LSTS)
rm -f "$(DISKIMAGE)"
createPackage:
pkg/createPackage
clean: genclean cleandrivers
rm -f "$(TARGETDIR)/$(PGM)" $(OBJS) $(BASIC_OBJS) $(C_DEPS) $(MAPFILE) $(ASM_LSTS) "$(DISKIMAGE)"
cleanMacCruft:
rm -rf pkg
$(PGM): $(OBJS)
$(CL65) $(MACHCONFIG) --mapfile $(MAPFILE) $(LDFLAGS) -o "$(PGM)" $(OBJS)
# Some gen phase stuff...
gen: xcodefix $(DRIVERS)
$(DISKIMAGE): $(PGM)
make/createDiskImage $(AC) $(MACHINE) "$(DISKIMAGE)" "$(PGM)" "$(START_ADDR)"
xcodefix:
defaults write "$(CC65_PLUGIN_INFO)" $(XCODE_PLUGIN_COMPATIBILITY)s -array `defaults read "$(XCODE_INFO)" $(XCODE_PLUGIN_COMPATIBILITY)` || true
execute: $(DISKIMAGE)
osascript make/V2Make.scpt "$(CWD)" "$(PGM)" "$(CWD)/make/DevApple.vii" "$(EXECCMD)"
%.o: %.c
$(CL65) $(MACHCONFIG) $(CFLAGS) --create-dep -c -o $@ $<
sed -i .bak 's/\.s:/.o:/' $(@:.o=.u)
rm -f $(@:.o=.u).bak
ifeq ($(BUILD_TYPE),basic)
# Build rules for BASIC projects
%.o: %.s
$(CL65) $(MACHCONFIG) --cpu $(CPU) $(ASMFLAGS) -l -c -o $@ $<
$(TARGETDIR)/$(PGM): $(BASIC_OBJS)
cp $(TARGETDIR)/$(PGM).tok $(TARGETDIR)/$(PGM)
$(BASIC_OBJS): Makefile
endif
ifeq ($(BUILD_TYPE),merlin)
# Build rules for Merlin projects
$(TARGETDIR)/$(PGM): $(ASM_SRCS) Makefile
$(MKDIR) $(TARGETDIR)
rm -f $(TARGETDIR)/$(PGM)
$(MERLIN_ASM) linkscript.s $(PGM) $(TARGETDIR)/$(PGM)
endif
ifeq ($(BUILD_TYPE),cc65)
# Build rules for cc65 projects
$(TARGETDIR)/$(PGM): $(OBJS)
$(MKDIR) `dirname $@`
make/errorFilter.sh $(CL65) $(MACHCONFIG) --mapfile $(MAPFILE) $(LDFLAGS) -o "$(TARGETDIR)/$(PGM)" $(OBJS)
$(OBJS): Makefile
$(OBJDIR)/%.o: %.c
$(MKDIR) `dirname $@`
make/errorFilter.sh $(CL65) $(MACHCONFIG) $(CFLAGS) $(CC65_CREATE_DEP_ARG) -c -o $@ $<
sed -i .bak 's/\.s:/.o:/' $(@:.o=.u)
rm -f $(@:.o=.u).bak
$(OBJDIR)/%.o: $(GENDIR)/%.c
$(MKDIR) `dirname $@`
make/errorFilter.sh $(CL65) $(MACHCONFIG) $(CFLAGS) $(CC65_CREATE_DEP_ARG) -c -o $@ $<
sed -i .bak 's/\.s:/.o:/' $(@:.o=.u)
rm -f $(@:.o=.u).bak
$(OBJDIR)/%.o: %.s
$(MKDIR) `dirname $@`
make/errorFilter.sh $(CL65) $(MACHCONFIG) --cpu $(CPU) $(ASMFLAGS) $(CC65_LIST_ARG) -c -o $@ $<
$(OBJDIR)/%.o: $(GENDIR)/%.s
$(MKDIR) `dirname $@`
make/errorFilter.sh $(CL65) $(MACHCONFIG) --cpu $(CPU) $(ASMFLAGS) $(CC65_LIST_ARG) -c -o $@ $<
.PHONY: loresgr hiresgr auxmem joystick mouse serial
# Lores driver codegen
loresgr: $(DRVDIR)/a2_lores_drv.s $(DRVDIR)/a2_lores_drv.h
$(DRVDIR)/a2_lores_drv.s: $(CC65_DRV_DIR)/tgi/$(DRV_BASE_MACHINE).lo.tgi
mkdir -p $(DRVDIR)
$(CO65) --code-label _a2_lores_drv -o $@ $(CC65_DRV_DIR)/tgi/$(DRV_BASE_MACHINE).lo.tgi
$(DRVDIR)/a2_lores_drv.h:
mkdir -p $(DRVDIR)
echo '#include <tgi.h>' > $@
echo 'extern char a2_lores_drv;' >> $@
# Hires driver codegen
hiresgr: $(DRVDIR)/a2_hires_drv.s $(DRVDIR)/a2_hires_drv.h
$(DRVDIR)/a2_hires_drv.s: $(CC65_DRV_DIR)/tgi/$(DRV_BASE_MACHINE).hi.tgi
mkdir -p $(DRVDIR)
$(CO65) --code-label _a2_hires_drv -o $@ $(CC65_DRV_DIR)/tgi/$(DRV_BASE_MACHINE).hi.tgi
$(DRVDIR)/a2_hires_drv.h:
mkdir -p $(DRVDIR)
echo '#include <tgi.h>' > $@
echo 'extern char a2_hires_drv;' >> $@
# Auxmem driver codegen
auxmem: $(DRVDIR)/a2_auxmem_drv.s $(DRVDIR)/a2_auxmem_drv.h
$(DRVDIR)/a2_auxmem_drv.s: $(CC65_DRV_DIR)/emd/$(DRV_BASE_MACHINE).auxmem.emd
mkdir -p $(DRVDIR)
$(CO65) --code-label _a2_auxmem_drv -o $@ $(CC65_DRV_DIR)/emd/$(DRV_BASE_MACHINE).auxmem.emd
$(DRVDIR)/a2_auxmem_drv.h:
mkdir -p $(DRVDIR)
echo '#include <em.h>' > $@
echo 'extern char a2_auxmem_drv;' >> $@
# Joystick driver codegen
joystick: $(DRVDIR)/a2_joystick_drv.s $(DRVDIR)/a2_joystick_drv.h
$(DRVDIR)/a2_joystick_drv.s: $(CC65_DRV_DIR)/joy/$(DRV_BASE_MACHINE).stdjoy.joy
mkdir -p $(DRVDIR)
$(CO65) --code-label _a2_joystick_drv -o $@ $(CC65_DRV_DIR)/joy/$(DRV_BASE_MACHINE).stdjoy.joy
$(DRVDIR)/a2_joystick_drv.h:
mkdir -p $(DRVDIR)
echo '#include <joystick.h>' > $@
echo 'extern char a2_joystick_drv;' >> $@
# Mouse driver codegen
mouse: $(DRVDIR)/a2_mouse_drv.s $(DRVDIR)/a2_mouse_drv.h
$(DRVDIR)/a2_mouse_drv.s: $(CC65_DRV_DIR)/mou/$(DRV_BASE_MACHINE).stdmou.mou
mkdir -p $(DRVDIR)
$(CO65) --code-label _a2_mouse_drv -o $@ $(CC65_DRV_DIR)/mou/$(DRV_BASE_MACHINE).stdmou.mou
$(DRVDIR)/a2_mouse_drv.h:
mkdir -p $(DRVDIR)
echo '#include <mouse.h>' > $@
echo 'extern char a2_mouse_drv;' >> $@
# Serial driver codegen
serial: $(DRVDIR)/a2_serial_drv.s $(DRVDIR)/a2_serial_drv.h
$(DRVDIR)/a2_serial_drv.s: $(CC65_DRV_DIR)/ser/$(DRV_BASE_MACHINE).ssc.ser
mkdir -p $(DRVDIR)
$(CO65) --code-label _a2_serial_drv -o $@ $(CC65_DRV_DIR)/ser/$(DRV_BASE_MACHINE).ssc.ser
$(DRVDIR)/a2_serial_drv.h:
mkdir -p $(DRVDIR)
echo '#include <serial.h>' > $@
echo 'extern char a2_serial_drv;' >> $@
endif
-include $(C_DEPS)

223
a2bejwld/mockingboard.c Normal file
View File

@ -0,0 +1,223 @@
//
// mockingboard.c
// mocktest
//
// Created by Jeremy Rand on 2016-09-10.
// Copyright © 2016 Jeremy Rand. All rights reserved.
//
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "mockingboard.h"
#include "mockingboard_speech.h"
// Defines
#define LATCH_COMMAND 0x7
#define WRITE_COMMAND 0x6
#define RESET_COMMAND 0x0
#define THROUGH_PORT_B 0x4
#define MOCKINGBOARD_LATCH(soundChip) writeCommand((soundChip), LATCH_COMMAND)
#define MOCKINGBOARD_WRITE(soundChip) writeCommand((soundChip), WRITE_COMMAND)
#define MOCKINGBOARD_RESET(soundChip) writeCommand((soundChip), RESET_COMMAND)
// Typedefs
typedef enum {
SOUND_CHIP_1 = 0,
SOUND_CHIP_2 = 1,
NUM_SOUND_CHIPS = 2
} tMockingBoardSoundChip;
// Globals
// Addresses for the two 6522's (assuming slot 4 for now)
static uint8_t *gMockPortB[NUM_SOUND_CHIPS] = { (uint8_t *)0xc000, (uint8_t *)0xc080 };
static uint8_t *gMockPortA[NUM_SOUND_CHIPS] = { (uint8_t *)0xc001, (uint8_t *)0xc081 };
static uint8_t *gMockDataDirB[NUM_SOUND_CHIPS] = { (uint8_t *)0xc002, (uint8_t *)0xc082 };
static uint8_t *gMockDataDirA[NUM_SOUND_CHIPS] = { (uint8_t *)0xc003, (uint8_t *)0xc083 };
static uint8_t gMockingBoardInitialized = false;
static uint8_t gMockingBoardSpeechInitialized = false;
static uint8_t gMockingBoardSearchDone = false;
static tSlot gMockingBoardSlot = 0;
static bool gMockingBoardHasSpeech = false;
// Implementation
static uint8_t *mapIOPointer(tSlot slot, uint8_t *ptr)
{
uint16_t temp1 = (uint16_t)ptr;
uint16_t temp2 = slot;
temp2 <<= 8;
temp1 &= 0xf0ff;
temp1 |= temp2;
ptr = (uint8_t *)temp1;
return ptr;
}
bool mockingBoardInit(void)
{
tMockingBoardSoundChip soundChip;
if (!gMockingBoardSearchDone)
{
gMockingBoardSlot = getMockingBoardSlot();
if ((gMockingBoardSlot & 0x80) != 0)
gMockingBoardHasSpeech = true;
gMockingBoardSlot &= 0x7;
gMockingBoardSearchDone = true;
}
if (gMockingBoardSlot == 0)
return false;
if (gMockingBoardInitialized)
return true;
if (sizeof(tMockingSoundRegisters) != 16) {
printf("The sound registers must be 16 bytes long!\n");
}
for (soundChip = SOUND_CHIP_1; soundChip < NUM_SOUND_CHIPS; soundChip++) {
gMockPortB[soundChip] = mapIOPointer(gMockingBoardSlot, gMockPortB[soundChip]);
gMockPortA[soundChip] = mapIOPointer(gMockingBoardSlot, gMockPortA[soundChip]);
gMockDataDirB[soundChip] = mapIOPointer(gMockingBoardSlot, gMockDataDirB[soundChip]);
gMockDataDirA[soundChip] = mapIOPointer(gMockingBoardSlot, gMockDataDirA[soundChip]);
*(gMockDataDirA[soundChip]) = 0xff; // Set port A for output
*(gMockDataDirB[soundChip]) = 0x7; // Set port B for output
}
if (gMockingBoardHasSpeech) {
if (gMockingBoardSpeechInitialized) {
mockingBoardSpeechShutdown();
}
mockingBoardSpeechInit(gMockingBoardSlot);
gMockingBoardSpeechInitialized = true;
} else if (gMockingBoardSpeechInitialized) {
mockingBoardSpeechShutdown();
gMockingBoardSpeechInitialized = false;
}
gMockingBoardInitialized = true;
return true;
}
void mockingBoardShutdown(void)
{
if (gMockingBoardSpeechInitialized) {
mockingBoardSpeechShutdown();
gMockingBoardSpeechInitialized = false;
}
gMockingBoardInitialized = false;
}
tSlot mockingBoardSlot(void)
{
return gMockingBoardSlot;
}
bool mockingBoardHasSpeechChip(void)
{
return gMockingBoardHasSpeech;
}
static void writeCommand(tMockingBoardSoundChip soundChip, uint8_t command)
{
volatile uint8_t *ptr = gMockPortB[soundChip];
*ptr = command;
*ptr = THROUGH_PORT_B;
}
static void mockingBoardTableAccess(tMockingBoardSoundChip soundChip, tMockingSoundRegisters *registers)
{
uint8_t *data = (uint8_t *)registers;
volatile uint8_t *ptr = gMockPortA[soundChip];
uint8_t index;
if (!gMockingBoardInitialized)
return;
MOCKINGBOARD_RESET(soundChip);
for (index = 0; index < 16; index++) {
*ptr = index;
MOCKINGBOARD_LATCH(soundChip);
*ptr = *data;
MOCKINGBOARD_WRITE(soundChip);
data++;
}
}
void mockingBoardPlaySound(tMockingBoardSpeaker speaker, tMockingSoundRegisters *registers)
{
if ((speaker & SPEAKER_LEFT) != 0) {
mockingBoardTableAccess(SOUND_CHIP_1, registers);
}
if ((speaker & SPEAKER_RIGHT) != 0) {
mockingBoardTableAccess(SOUND_CHIP_2, registers);
}
}
void mockingBoardStopSound(tMockingBoardSpeaker speaker)
{
if ((speaker & SPEAKER_LEFT) != 0) {
MOCKINGBOARD_RESET(SOUND_CHIP_1);
}
if ((speaker & SPEAKER_RIGHT) != 0) {
MOCKINGBOARD_RESET(SOUND_CHIP_2);
}
}
bool mockingBoardSpeechIsBusy(void)
{
return (mockingBoardSpeechBusy != 0);
}
bool mockingBoardSpeechIsPlaying(void)
{
return (mockingBoardSpeechPlaying != 0);
}
bool mockingBoardSpeak(uint8_t *data, uint16_t dataLen)
{
if (!gMockingBoardSpeechInitialized)
return false;
if (mockingBoardSpeechIsBusy())
return false;
mockingBoardSpeechData = data;
mockingBoardSpeechLen = dataLen;
mockingBoardSpeakPriv();
return true;
}

134
a2bejwld/mockingboard.h Normal file
View File

@ -0,0 +1,134 @@
//
// mockingboard.h
// mocktest
//
// Created by Jeremy Rand on 2016-09-10.
// Copyright © 2016 Jeremy Rand. All rights reserved.
//
#ifndef __mocktest__mockingboard__
#define __mocktest__mockingboard__
#include <stdbool.h>
#include <stdint.h>
// Defines
#define MOCK_NUM_CHANNELS 3
#define TONE_PERIOD_C(octave) (0x7a3 >> (octave - 1))
#define TONE_PERIOD_C_SHARP(octave) (0x735 >> (octave - 1))
#define TONE_PERIOD_D(octave) (0x6cd >> (octave - 1))
#define TONE_PERIOD_D_SHARP(octave) (0x66c >> (octave - 1))
#define TONE_PERIOD_E(octave) (0x60f >> (octave - 1))
#define TONE_PERIOD_F(octave) (0x5b8 >> (octave - 1))
#define TONE_PERIOD_F_SHARP(octave) (0x566 >> (octave - 1))
#define TONE_PERIOD_G(octave) (0x518 >> (octave - 1))
#define TONE_PERIOD_G_SHARP(octave) (0x4cf >> (octave - 1))
#define TONE_PERIOD_A(octave) (0x48a >> (octave - 1))
#define TONE_PERIOD_A_SHARP(octave) (0x449 >> (octave - 1))
#define TONE_PERIOD_B(octave) (0x40b >> (octave - 1))
#define MIN_NOISE_PERIOD 0
#define MAX_NOISE_PERIOD 31
#define TONE_CHANNEL_A 1
#define TONE_CHANNEL_B 2
#define TONE_CHANNEL_C 4
#define NOISE_CHANNEL_A 8
#define NOISE_CHANNEL_B 16
#define NOISE_CHANNEL_C 32
#define ENABLE_CHANNEL(channels) (0x3f ^ (channels))
#define ENABLE_ALL_TONE_CHANNELS ENABLE_CHANNEL(TONE_CHANNEL_A|TONE_CHANNEL_B|TONE_CHANNEL_C)
#define ENABLE_ALL_NOISE_CHANNELS ENABLE_CHANNEL(NOISE_CHANNEL_A|NOISE_CHANNEL_B|NOISE_CHANNEL_C)
#define ENABLE_ALL_CHANNELS ENABLE_CHANNEL(TONE_CHANNEL_A|TONE_CHANNEL_B|TONE_CHANNEL_C|NOISE_CHANNEL_A|NOISE_CHANNEL_B|NOISE_CHANNEL_C)
#define MIN_AMPLITUDE 0
#define MAX_AMPLITUDE 15
#define VARIABLE_AMPLITUDE 16
#define MIN_ENVELOPE_PERIOD 0
#define MAX_ENVELOPE_PERIOD 65535u
#define MILLISEC_TO_ENVELOP_PERIOD(ms) ((ms) * 4)
// Here is a table of the envelope shapes and how they look:
//
// ENVELOPE_SHAPE_ONE_SHOT_DECAY \__________...
//
// ENVELOPE_SHAPE_ONE_SHOT_ATTACK /__________...
//
// ENVELOPE_SHAPE_CONT_DECAY \|\|\|\|\|\...
//
// ENVELOPE_SHAPE_CONT_DECAY_HOLD \__________...
//
// ENVELOPE_SHAPE_CONT_DECAY_ALT \/\/\/\/\/\...
// _________
// ENVELOPE_SHAPE_CONT_DECAY_ALT_HOLD \| ...
//
// ENVELOPE_SHAPE_CONT_ATTACK /|/|/|/|/|/...
// __________
// ENVELOPE_SHAPE_CONT_ATTACK_HOLD / ...
// ENVELOPE_SHAPE_CONT_ATTACK_ALT /\/\/\/\/\/...
//
// ENVELOPE_SHAPE_CONT_ATTACK_ALT_HOLD /|_________...
#define ENVELOPE_SHAPE_ONE_SHOT_DECAY 0
#define ENVELOPE_SHAPE_ONE_SHOT_ATTACK 4
#define ENVELOPE_SHAPE_CONT_DECAY 8
#define ENVELOPE_SHAPE_CONT_DECAY_HOLD 9
#define ENVELOPE_SHAPE_CONT_DECAY_ALT 10
#define ENVELOPE_SHAPE_CONT_DECAY_ALT_HOLD 11
#define ENVELOPE_SHAPE_CONT_ATTACK 12
#define ENVELOPE_SHAPE_CONT_ATTACK_HOLD 13
#define ENVELOPE_SHAPE_CONT_ATTACK_ALT 14
#define ENVELOPE_SHAPE_CONT_ATTACK_ALT_HOLD 15
// Typedefs
typedef uint8_t tSlot;
typedef enum {
SPEAKER_NONE = 0,
SPEAKER_LEFT = (1 << 0),
SPEAKER_RIGHT = (1 << 1),
SPEAKER_BOTH = (1 << 0) | (1 << 1)
} tMockingBoardSpeaker;
typedef struct tMockingSoundRegisters {
uint16_t tonePeriod[MOCK_NUM_CHANNELS];
uint8_t noisePeriod;
uint8_t enable;
uint8_t amplitude[MOCK_NUM_CHANNELS];
uint16_t envelopePeriod;
uint8_t envelopeShape;
uint8_t dummy1;
uint8_t dummy2;
} tMockingSoundRegisters;
// API
extern bool mockingBoardInit(void);
extern void mockingBoardShutdown(void);
extern tSlot mockingBoardSlot(void);
extern void mockingBoardPlaySound(tMockingBoardSpeaker speaker, tMockingSoundRegisters *registers);
extern void mockingBoardStopSound(tMockingBoardSpeaker speaker);
extern bool mockingBoardHasSpeechChip(void);
extern bool mockingBoardSpeechIsBusy(void);
extern bool mockingBoardSpeechIsPlaying(void);
extern bool mockingBoardSpeak(uint8_t *data, uint16_t dataLen);
#endif /* defined(__mocktest__mockingboard__) */

View File

@ -0,0 +1,27 @@
//
// mockingboard_speech.h
// mocktest
//
// Created by Jeremy Rand on 2016-10-17.
// Copyright © 2016 Jeremy Rand. All rights reserved.
//
#ifndef mockingboard_speech_h
#define mockingboard_speech_h
#include <stdint.h>
extern uint8_t *mockingBoardSpeechData;
extern uint16_t mockingBoardSpeechLen;
extern uint8_t mockingBoardSpeechBusy;
extern uint8_t mockingBoardSpeechPlaying;
extern uint8_t getMockingBoardSlot(void);
extern void mockingBoardSpeechInit(uint8_t slot);
extern void mockingBoardSpeechShutdown(void);
extern void mockingBoardSpeakPriv(void);
#endif /* mockingboard_speech_h */

View File

@ -0,0 +1,472 @@
;
; speech.s
; mocktest
;
; Created by Jeremy Rand on 2016-09-29.
; Copyright © 2016 Jeremy Rand. All rights reserved.
;
.export _mockingBoardSpeechInit, _mockingBoardSpeechShutdown, _mockingBoardSpeakPriv
.export _mockingBoardSpeechData, _mockingBoardSpeechLen
.export _mockingBoardSpeechBusy, _mockingBoardSpeechPlaying
.export _getMockingBoardSlot
.interruptor mock_irq
TMPPTR := $FB ; Temporary pointer used in interrupt handler
IRQL := $03FE ; Interrupt vector, low byte
IRQH := $03FF ; Interrupt vector, high byte
BASE := $40 ; First speech chip
DURPHON := BASE ; Register 0 of speech chip
INFLECT := BASE+$01 ; Register 1 of speech chip
RATEINF := BASE+$02 ; Register 2 of speech chip
CTTRAMP := BASE+$03 ; Register 3 of speech chip
FILFREQ := BASE+$04 ; Register 4 of speech chip
DDRB := $02
DDRA := $03
PCR := $8C ; Peripheral control register, 6522
IFR := $8D ; Interrupt flag register, 6522
IER := $8E
.DATA
_mockingBoardSpeechData: .byte $00, $00
_mockingBoardSpeechLen: .byte $00, $00
_outptr: .byte $00, $00
_endptr: .byte $00, $00
_mockingBoardSpeechBusy: .byte $00
_mockingBoardSpeechPlaying: .byte $00
mock_irq: .byte $60
.lobytes _mockInterrupt
.hibytes _mockInterrupt
.CODE
writeChip:
sta $C000,X
rts
readChip:
lda $C000,X
rts
;license:MIT
; By Andrew Roughan
; in the style of 4am for Total Replay
; ported into a2bejewld by jrand
;
; Mockingboard support functions
;
;------------------------------------------------------------------------------
; GetMockingboardSlot
; detect Mockingboard card by searching for 6522 timers across all slots 7->1
; access 6522 timers with deterministic cycle counts
;
; based on prior art in Mockingboard Developers Toolkit
; with optimisation from deater/french touch
; also takes into account FastChip //e clock difference
;
; in: none
; accelerators should be off
; out:
; if card was found, A = #$?n where n is the slot number of the card, otherwise #$00
; and bit 6 = 0 if Mockingboard Sound I found
; or bit 6 = 1 if Mockingboard Sound II or "A" found
; and bit 7 = 1 if Mockingboard Sound/Speech I or "C" found
; flags clobbered
; zp $80-$82 clobbered
; (jrand - and then restored because I am chicken and afraid of breaking cc65 runtime)
; X/Y clobbered
;------------------------------------------------------------------------------
.proc _getMockingBoardSlot
php
lda $80
sta zp80Backup
lda $81
sta zp81Backup
lda $82
sta zp82Backup
lda $3fe
sta irq1Backup
lda $3ff
sta irq2Backup
lda #$00
sta $80
sta $82 ; type
ldx #$C7
@slotLoop:
stx $81
ldy #$04 ; 6522 #1 $Cx04
jsr @timercheck
beq @foundI
dex
cpx #$C0
bne @slotLoop
ldx #00 ; not found
jmp @cleanup
@foundI: ; sound I or better
ldy #$84 ; 6522 #2 $Cx84
jsr @timercheck
beq @foundII
ldy #$0C
sty @mb_smc1 + 1
iny
sty @mb_smc10 + 1
iny
sty @mb_smc5 + 1
sty @mb_smc14 + 1
.BYTE $2C ; Hide next 2 bytes using a BIT opcode
@foundII: ; stereo
ror $82
lda $81
sta @mb_smc1 + 2
sta @mb_smc2 + 2
sta @mb_smc3 + 2
sta @mb_smc4 + 2
sta @mb_smc5 + 2
sta @mb_smc6 + 2
sta @mb_smc7 + 2
sta @mb_smc8 + 2
sta @mb_smc9 + 2
sta @mb_smc10 + 2
sta @mb_smc11 + 2
sta @mb_smc12 + 2
sta @mb_smc13 + 2
sta @mb_smc14 + 2
; detect speech chip
sei
lda #<@mb_irq
sta $3fe
lda #>@mb_irq
sta $3ff
lda #$0c
@mb_smc1:
sta $c48c
lda #$80
@mb_smc2:
sta $c443
lda #$c0
@mb_smc3:
sta $c440
lda #$70
@mb_smc4:
sta $c443
lda #$82
@mb_smc5:
sta $c48e
ldx #0
ldy #0
sec
cli
@wait_irq:
lda $80
bne @got_irq
iny
bne @wait_irq
inx
bne @wait_irq
clc
@got_irq:
sei
ror $82
ldy #$ff
@mb_smc6:
sty $c403
lda #$7
@mb_smc7:
sta $c402
@mb_smc8:
sty $c483
@mb_smc9:
sta $c482
and $81
ora $82
tax
iny
sty $80
tya
sta ($80),y
lda #4
sta ($80),y
tya
ldy #$80
sta ($80),y
lda #4
sta ($80),y
@cleanup:
lda zp80Backup
sta $80
lda zp81Backup
sta $81
lda zp82Backup
sta $82
lda irq1Backup
sta $3fe
lda irq2Backup
sta $3ff
txa
ldx #$00
plp
rts
@timercheck:
sec
lda ($80),y ; read 6522 timer low byte
sbc ($80),y ; second time
cmp #5 ; looking for (-)8 cycles between reads
beq :+
cmp #6 ; FastChip //e clock is different
: rts
@mb_irq:
lda #2
@mb_smc10:
sta $c48d
lda #$80
@mb_smc11:
sta $c443
lda #0
@mb_smc12:
sta $c440
lda #$70
@mb_smc13:
sta $c443
sta $80
lda #2
@mb_smc14:
sta $c48e
lda $45
rti
; Locals
zp80Backup: .BYTE $00
zp81Backup: .BYTE $00
zp82Backup: .BYTE $00
irq1Backup: .BYTE $00
irq2Backup: .BYTE $00
.endproc
.proc _mockingBoardSpeechInit
sei
; The accumulator has the slot number of the mockingboard.
; Turn that into the address of the slot and set the address
; in the read and write functions.
and #$7
ora #$c0
sta writeChip+2
sta readChip+2
; Write a jump instruction at mock_irq to turn on our handler
lda #$4c
sta mock_irq
cli
rts
.endproc
.proc _mockingBoardSpeechShutdown
sei
; Write a RTS instruction at mock_irq to disable our handler
lda #$60
sta mock_irq
cli
rts
.endproc
.proc _mockingBoardSpeakPriv
sei
; Get the starting address of the data and store in the work pointer
lda _mockingBoardSpeechData+1
sta _outptr+1
lda _mockingBoardSpeechData
sta _outptr
; Calculate the end address from the start address and the length
lda _mockingBoardSpeechLen+1
clc
adc _mockingBoardSpeechData+1
sta _endptr+1
lda _mockingBoardSpeechLen
clc
adc _mockingBoardSpeechData
bcc @L2
inc _endptr+1
@L2:
sta _endptr
; Set the busy flag
lda #$FF
sta _mockingBoardSpeechBusy
; Set peripheral control register to recognize the signal from the
; speech chip.
lda #$0C
ldx #PCR
jsr writeChip
; Raise control bit in register 3
lda #$80
ldx #CTTRAMP
jsr writeChip
; Set transitioned inflection mode in register 0
lda #$C0
ldx #DURPHON
jsr writeChip
; Lower control bit
lda #$70
ldx #CTTRAMP
jsr writeChip
; Enable 6522 interrupts
lda #$82
ldx #IER
jsr writeChip
cli
rts
.endproc
.proc _mockInterrupt
; If we have a 6522 interrupt, jump to L4.
ldx #IFR
jsr readChip
bmi @L4
; Otherwise clear the carry to indicate we didn't handle the interrupt
; and return to the caller.
clc
rts
@L4:
; Clear the interrupt flag
lda #$02
ldx #IFR
jsr writeChip
; Check for end of data file. If not the end, jump to L1
lda _outptr+1
cmp _endptr+1
bcc @L1
bne @L5
lda _outptr
cmp _endptr
bcc @L1
@L5:
; If at the end, turn everything off. Store a pause phoneme.
lda #$80
ldx #CTTRAMP
jsr writeChip
lda #$00
ldx #DURPHON
jsr writeChip
; Zero amplitude
lda #$70
ldx #CTTRAMP
jsr writeChip
; Clear busy and playing flags
lda #$00
sta _mockingBoardSpeechBusy
sta _mockingBoardSpeechPlaying
; Clear interrupt enable in 6522
lda #$02
ldx #IER
jsr writeChip
@L2:
; Set the carry flag to indicate we handled the interrupt and return to the caller.
sec
rts
@L1:
; Set the speach playing flag
lda #$ff
sta _mockingBoardSpeechPlaying
; Save the value of the tmp pointer on the stack
lda TMPPTR
pha
lda TMPPTR+1
pha
; Move the _outptr into the tmp pointer
lda _outptr
sta TMPPTR
lda _outptr+1
sta TMPPTR+1
; Init registers
ldy #$00
ldx #FILFREQ
@L6:
; Get the next data
lda (TMPPTR),Y
; Store in the speech chip
jsr writeChip
; Next data
inc TMPPTR
bne @L3
inc TMPPTR+1
@L3:
; Go to next register
dex
; If we are not done the last register, then loop back to L6
cpx #BASE-1
bne @L6
; We are done writing so move the tmp pointer back into _outptr
lda TMPPTR
sta _outptr
lda TMPPTR+1
sta _outptr+1
; Restore the tmp pointer from the stack
pla
sta TMPPTR+1
pla
sta TMPPTR
; Finish the interrupt handler
jmp @L2
.endproc

View File

@ -9,16 +9,13 @@
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <mouse.h>
#include "mouseWrapper.h"
#include "game.h"
#include "vbl.h"
// Extern to mouse driver
extern char a2e_stdmou_mou;
#include "drivers/a2_mouse_drv.h"
// Globals
@ -33,23 +30,15 @@ static struct mouse_callbacks gMouseDrvCallbacks;
bool initMouse(tMouseCallbacks *callbacks)
{
if (!gMouseInstalled) {
gMouseDrvCallbacks.hide = mouse_def_callbacks.hide;
memcpy(&gMouseDrvCallbacks, &mouse_def_callbacks, sizeof(gMouseDrvCallbacks));
// This callback is here for the //c VBL which is only detectable
// through the mouse interrupt. By registering this as our "show"
// through the mouse interrupt. By registering this as our "draw"
// function, we can ensure that we get called on our VBL interrupt
// and can unblock our VBL wait function.
gMouseDrvCallbacks.show = vblIRQCallback;
gMouseDrvCallbacks.movex = mouse_def_callbacks.movex;
gMouseDrvCallbacks.movey = mouse_def_callbacks.movey;
gMouseDrvCallbacks.draw = vblIRQCallback;
if (mouse_install(&gMouseDrvCallbacks, &a2e_stdmou_mou) == 0) {
if (mouse_install(&gMouseDrvCallbacks, &a2_mouse_drv) == 0) {
gMouseInstalled = true;
// This is required to ensure that the show callback is called
// by the interrupt handler. This whole thing is a bit of a
// hack to get the default mouse interrupt handler to do what
// we want on the //c to detect the VBL but it works for now.
mouse_show();
}
}
@ -67,6 +56,12 @@ void shutdownMouse(void)
}
bool hasMouse(void)
{
return gMouseInstalled;
}
bool pollMouse(void)
{
static uint16_t mouseDownAtX = 0;
@ -162,4 +157,4 @@ void moveMouseToSquare(tSquare square)
newY = (SQUARE_TO_Y(square) * 8) + 4;
mouse_move(newX, newY);
}
}

View File

@ -27,6 +27,7 @@ typedef struct tMouseCallbacks {
extern bool initMouse(tMouseCallbacks *callbacks);
extern void shutdownMouse(void);
extern bool hasMouse(void);
extern bool pollMouse(void);
extern void moveMouseToSquare(tSquare square);

403
a2bejwld/sound.c Normal file
View File

@ -0,0 +1,403 @@
//
// sound.c
// a2bejwld
//
// Created by Jeremy Rand on 2016-12-18.
// Copyright © 2016 Jeremy Rand. All rights reserved.
//
#include "sound.h"
#include "mockingboard.h"
#include <stdint.h>
// Defines
#define CLEAR_GEM_SOUND_NORMAL 0
#define CLEAR_GEM_SOUND_STAR 1
#define CLEAR_GEM_SOUND_SPECIAL 2
#define CLEAR_GEM_SOUND_EXPLODE 3
#define NUM_CLEAR_GEM_SOUNDS 4
// Globals
static uint8_t gSoundClearGem = CLEAR_GEM_SOUND_NORMAL;
static uint8_t gClearGemSoundFreq[NUM_CLEAR_GEM_SOUNDS][8] = {
{ // CLEAR_GEM_SOUND_NORMAL
30, 25, 20, 30, 30, 30, 30, 0 },
{ // CLEAR_GEM_SOUND_STAR
10, 9, 8, 7, 6, 5, 4, 0 },
{ // CLEAR_GEM_SOUND_SPECIAL
4, 6, 8, 10, 8, 6, 4, 0 },
{ // CLEAR_GEM_SOUND_EXPLODE
50, 60, 50, 60, 50, 60, 50, 0 }
};
static uint8_t gClearGemSoundDuration[NUM_CLEAR_GEM_SOUNDS][8] = {
{ // CLEAR_GEM_SOUND_NORMAL
10, 15, 20, 10, 10, 10, 10, 0 },
{ // CLEAR_GEM_SOUND_STAR
30, 31, 32, 33, 34, 35, 36, 0 },
{ // CLEAR_GEM_SOUND_SPECIAL
36, 34, 32, 30, 32, 34, 36, 0 },
{ // CLEAR_GEM_SOUND_EXPLODE
8, 8, 8, 8, 8, 8, 8, 0 },
};
static tMockingSoundRegisters gClearGemMockSounds[NUM_CLEAR_GEM_SOUNDS] = {
// Normal
{
{ TONE_PERIOD_C(6), TONE_PERIOD_G(6), 0 }, // Tone period for the three channels
0, // Noise period
ENABLE_CHANNEL(TONE_CHANNEL_A | TONE_CHANNEL_B), // Enable
{ VARIABLE_AMPLITUDE, VARIABLE_AMPLITUDE, MIN_AMPLITUDE }, // Amplitude for the three channels
MILLISEC_TO_ENVELOP_PERIOD(960), // Envelope period
ENVELOPE_SHAPE_ONE_SHOT_DECAY, // Envelope shape
0, // Dummy1
0 // Dummy2
},
// Star
{
{ TONE_PERIOD_C(5), TONE_PERIOD_G(5), TONE_PERIOD_E(5) }, // Tone period for the three channels
10, // Noise period
ENABLE_ALL_CHANNELS, // Enable
{ VARIABLE_AMPLITUDE, VARIABLE_AMPLITUDE, MIN_AMPLITUDE }, // Amplitude for the three channels
MILLISEC_TO_ENVELOP_PERIOD(960), // Envelope period
ENVELOPE_SHAPE_ONE_SHOT_DECAY, // Envelope shape
0, // Dummy1
0 // Dummy2
},
// Special
{
{ 100, 97, 98 }, // Tone period for the three channels
4, // Noise period
ENABLE_ALL_CHANNELS, // Enable
{ VARIABLE_AMPLITUDE, VARIABLE_AMPLITUDE, VARIABLE_AMPLITUDE }, // Amplitude for the three channels
MILLISEC_TO_ENVELOP_PERIOD(1280), // Envelope period
ENVELOPE_SHAPE_ONE_SHOT_DECAY, // Envelope shape
0, // Dummy1
0 // Dummy2
},
// Explosion
{
{ 0, 0, 0 }, // Tone period for the three channels
16, // Noise period
ENABLE_CHANNEL(NOISE_CHANNEL_A), // Enable
{ VARIABLE_AMPLITUDE, MIN_AMPLITUDE, MIN_AMPLITUDE }, // Amplitude for the three channels
MILLISEC_TO_ENVELOP_PERIOD(3000), // Envelope period
ENVELOPE_SHAPE_ONE_SHOT_DECAY, // Envelope shape
0, // Dummy1
0 // Dummy2
}
};
static tMockingSoundRegisters gGemLandSound = {
{ 0, 0, 0 }, // Tone period for the three channels
30, // Noise period
ENABLE_CHANNEL(NOISE_CHANNEL_A), // Enable
{ VARIABLE_AMPLITUDE, VARIABLE_AMPLITUDE, VARIABLE_AMPLITUDE }, // Amplitude for the three channels
MILLISEC_TO_ENVELOP_PERIOD(20), // Envelope period
ENVELOPE_SHAPE_ONE_SHOT_DECAY, // Envelope shape
0, // Dummy1
0 // Dummy2
};
static uint8_t gSpeakGood[] = {
0xE8, 0x7B, 0x88, 0x3A, 0xE9, 0xE8, 0x7B, 0x88,
0x3A, 0xE6, 0xE8, 0x7B, 0x88, 0x3A, 0x52, 0xE8,
0x7B, 0x88, 0x3A, 0x52, 0xEA, 0x7F, 0x68, 0x4A,
0x65, 0xEA, 0x7F, 0x68, 0x4A, 0xC0
};
static uint8_t gSpeakGo[] = {
0xE8, 0x7B, 0x88, 0x3A, 0xE9, 0xE8, 0x7B, 0x88,
0x3A, 0xE6, 0xE8, 0x7B, 0x88, 0x3A, 0x11, 0xE8,
0x7B, 0x88, 0x3A, 0x63
};
static uint8_t gSpeakLevelComplete[] = {
0xE8, 0x7B, 0x88, 0x3A, 0x60, 0xE8, 0x7B, 0x88,
0x3A, 0x0A, 0xE8, 0x7B, 0x88, 0x3A, 0x33, 0xE8,
0x7B, 0x88, 0x3A, 0xEC, 0xE8, 0x7B, 0x88, 0x3A,
0x4A, 0xE8, 0x7B, 0x88, 0x3A, 0x4A, 0xE8, 0x7B,
0x88, 0x3A, 0x60, 0xE8, 0x7B, 0x88, 0x3A, 0x29,
0xE8, 0x7B, 0x88, 0x3A, 0xAD, 0xE8, 0x7B, 0x88,
0x3A, 0x5A, 0xE8, 0x7B, 0x88, 0x3A, 0x5A, 0xE8,
0x7B, 0x88, 0x3A, 0x37, 0xE8, 0x7B, 0x88, 0x3A,
0x27, 0xE8, 0x7B, 0x88, 0x3A, 0x60, 0xE8, 0x7B,
0x88, 0x3A, 0x01, 0xE8, 0x7B, 0x88, 0x3A, 0x68,
0xE8, 0x7B, 0x88, 0x3A, 0xC0
};
static uint8_t gSpeakGetReady[] = {
0xE8, 0x7B, 0x88, 0x3A, 0xE6, 0xE8, 0x7B, 0x88,
0x3A, 0xC0, 0xE8, 0x7B, 0x88, 0x3A, 0x0A, 0xE8,
0x7B, 0x88, 0x3A, 0x68, 0xE8, 0x7B, 0x88, 0x3A,
0xC0, 0xE8, 0x7B, 0x88, 0x3A, 0x1D, 0xE8, 0x7B,
0x88, 0x3A, 0x4A, 0xE8, 0x7B, 0x88, 0x3A, 0x4A,
0xE8, 0x7B, 0x88, 0x3A, 0x25, 0xE8, 0x7B, 0x88,
0x3A, 0x01
};
static uint8_t gSpeakNoMoreMoves[] = {
0xE8, 0x7B, 0x88, 0x3A, 0x78, 0xE8, 0x7B, 0x88,
0x3A, 0x11, 0xE8, 0x7B, 0x88, 0x3A, 0x63, 0xE8,
0x7B, 0x88, 0x3A, 0x37, 0xE8, 0x7B, 0x88, 0x3A,
0x11, 0xE8, 0x7B, 0x88, 0x3A, 0x5C, 0xE8, 0x7B,
0x88, 0x3A, 0x37, 0xE8, 0x7B, 0x88, 0x3A, 0x16,
0xE8, 0x7B, 0x88, 0x3A, 0x33, 0xE8, 0x7B, 0x88,
0x3A, 0x2F
};
static uint8_t gSpeakExcellent[] = {
0xE8, 0x7B, 0x88, 0x3A, 0x4A, 0xE8, 0x7B, 0x88,
0x3A, 0x29, 0xE8, 0x7B, 0x88, 0x3A, 0x30, 0xE8,
0x7B, 0x88, 0x3A, 0x0A, 0xE8, 0x7B, 0x88, 0x3A,
0x4A, 0xE8, 0x7B, 0x88, 0x3A, 0x60, 0xE8, 0x7B,
0x88, 0x3A, 0x60, 0xE8, 0x7B, 0x88, 0x3A, 0x4A,
0xE8, 0x7B, 0x88, 0x3A, 0x4A, 0xE8, 0x7B, 0x88,
0x3A, 0x78, 0xEA, 0x7F, 0x68, 0x4A, 0x68, 0xEA,
0x7F, 0x68, 0x4A, 0xC0
};
static uint8_t gSpeakIncredible[] = {
0xE8, 0x7B, 0x88, 0x3A, 0x47, 0xE8, 0x7B, 0x88,
0x3A, 0x78, 0xE8, 0x7B, 0x88, 0x3A, 0x29, 0xE8,
0x7B, 0x88, 0x3A, 0x1D, 0xE8, 0x7B, 0x88, 0x3A,
0x0A, 0xE8, 0x7B, 0x88, 0x3A, 0x65, 0xE8, 0x7B,
0x88, 0x3A, 0x1B, 0xE8, 0x7B, 0x88, 0x3A, 0x64,
0xE8, 0x7B, 0x88, 0x3A, 0x60
};
static bool gSoundEnabled = false;
static bool gMockingBoardInitialized = false;
static bool gMockingBoardEnabled = false;
static bool gMockingBoardSpeechEnabled = false;
static tMockingBoardSpeaker gMockingBoardSoundSpeaker = SPEAKER_BOTH;
// Implementation
void soundInit(bool enableSounds, bool enableMockingBoard, bool enableSpeechChip)
{
gMockingBoardInitialized = mockingBoardInit();
gSoundEnabled = enableSounds;
gMockingBoardEnabled = ((gSoundEnabled) && (gMockingBoardInitialized) && (enableMockingBoard));
gMockingBoardSpeechEnabled = ((enableSpeechChip) && (gMockingBoardEnabled) && (mockingBoardHasSpeechChip()));
// When the speech chip is on, sound effects go out the right speaker
// only and the left speaker is used for speech. If the speech chip is
// off, then sound effects go to both speakers.
if (gMockingBoardSpeechEnabled) {
gMockingBoardSoundSpeaker = SPEAKER_RIGHT;
} else {
gMockingBoardSoundSpeaker = SPEAKER_BOTH;
}
}
void soundShutdown(void)
{
if (gMockingBoardInitialized) {
mockingBoardShutdown();
gMockingBoardInitialized = false;
gMockingBoardEnabled = false;
gMockingBoardSpeechEnabled = false;
}
gSoundEnabled = false;
}
static void playSound(int8_t startFreq, int8_t duration)
{
int8_t freq;
while (duration > 0) {
asm ("STA %w", 0xc030);
freq = startFreq;
while (freq > 0) {
freq--;
}
duration--;
}
}
void beginClearGemSound(void)
{
gSoundClearGem = CLEAR_GEM_SOUND_NORMAL;
}
void playSoundForExplodingGem(void)
{
if (gSoundClearGem < CLEAR_GEM_SOUND_EXPLODE)
gSoundClearGem = CLEAR_GEM_SOUND_EXPLODE;
}
void playSoundForStarringGem(void)
{
if (gSoundClearGem < CLEAR_GEM_SOUND_STAR)
gSoundClearGem = CLEAR_GEM_SOUND_STAR;
}
void playSoundForSpecialGem(void)
{
if (gSoundClearGem < CLEAR_GEM_SOUND_SPECIAL)
gSoundClearGem = CLEAR_GEM_SOUND_SPECIAL;
}
void playClearGemSound(uint8_t frame)
{
static uint8_t *clearGemSoundFreq;
static uint8_t *clearGemSoundDuration;
if (!gSoundEnabled)
return;
if (gMockingBoardEnabled) {
if (frame == 0) {
mockingBoardPlaySound(gMockingBoardSoundSpeaker, &(gClearGemMockSounds[gSoundClearGem]));
}
} else {
if (frame == 0) {
clearGemSoundFreq = &(gClearGemSoundFreq[gSoundClearGem][0]);
clearGemSoundDuration = &(gClearGemSoundDuration[gSoundClearGem][0]);
}
playSound(*clearGemSoundFreq, *clearGemSoundDuration);
clearGemSoundFreq++;
clearGemSoundDuration++;
}
}
void playLandingSound(uint8_t numLanded)
{
if (!gSoundEnabled)
return;
if (gMockingBoardEnabled) {
if (numLanded == 0) {
mockingBoardPlaySound(gMockingBoardSoundSpeaker, &gGemLandSound);
}
} else {
playSound(1, 1);
}
}
void speakGo(void)
{
if (!gMockingBoardSpeechEnabled)
return;
if (mockingBoardSpeechIsBusy()) {
while (mockingBoardSpeechIsPlaying())
;
}
mockingBoardSpeak(gSpeakGo, sizeof(gSpeakGo));
}
void speakLevelComplete(void)
{
if (!gMockingBoardSpeechEnabled)
return;
if (mockingBoardSpeechIsBusy()) {
while (mockingBoardSpeechIsPlaying())
;
}
mockingBoardSpeak(gSpeakLevelComplete, sizeof(gSpeakLevelComplete));
}
void speakGetReady(void)
{
if (!gMockingBoardSpeechEnabled)
return;
if (mockingBoardSpeechIsBusy()) {
while (mockingBoardSpeechIsPlaying())
;
}
mockingBoardSpeak(gSpeakGetReady, sizeof(gSpeakGetReady));
}
void speakNoMoreMoves(void)
{
if (!gMockingBoardSpeechEnabled)
return;
if (mockingBoardSpeechIsBusy()) {
while (mockingBoardSpeechIsPlaying())
;
}
mockingBoardSpeak(gSpeakNoMoreMoves, sizeof(gSpeakNoMoreMoves));
}
bool speakGood(void)
{
if (!gMockingBoardSpeechEnabled)
return true;
if (mockingBoardSpeechIsBusy())
return false;
mockingBoardSpeak(gSpeakGood, sizeof(gSpeakGood));
return true;
}
bool speakExcellent(void)
{
if (!gMockingBoardSpeechEnabled)
return true;
if (mockingBoardSpeechIsBusy())
return false;
mockingBoardSpeak(gSpeakExcellent, sizeof(gSpeakExcellent));
return true;
}
bool speakIncredible(void)
{
if (!gMockingBoardSpeechEnabled)
return true;
if (mockingBoardSpeechIsBusy())
return false;
mockingBoardSpeak(gSpeakIncredible, sizeof(gSpeakIncredible));
return true;
}

40
a2bejwld/sound.h Normal file
View File

@ -0,0 +1,40 @@
//
// sound.h
// a2bejwld
//
// Created by Jeremy Rand on 2016-12-18.
// Copyright © 2016 Jeremy Rand. All rights reserved.
//
#ifndef __a2bejwld__sound__
#define __a2bejwld__sound__
#include <stdbool.h>
#include <stdint.h>
#include "mockingboard.h"
extern void soundInit(bool enableSounds, bool enableMockingBoard, bool enableSpeechChip);
extern void soundShutdown(void);
extern void beginClearGemSound(void);
extern void playSoundForExplodingGem(void);
extern void playSoundForStarringGem(void);
extern void playSoundForSpecialGem(void);
extern void playClearGemSound(uint8_t frame);
extern void playLandingSound(uint8_t numLanded);
extern void speakGo(void);
extern void speakLevelComplete(void);
extern void speakGetReady(void);
extern void speakNoMoreMoves(void);
extern bool speakGood(void);
extern bool speakExcellent(void);
extern bool speakIncredible(void);
#endif /* defined(__a2bejwld__sound__) */

18
a2bejwld/text.h Normal file
View File

@ -0,0 +1,18 @@
//
// text.h
// a2bejwld
//
// Created by Jeremy Rand on 2020-01-22.
// Copyright © 2020 Jeremy Rand. All rights reserved.
//
#ifndef __a2bejwld__text__
#define __a2bejwld__text__
// API
extern unsigned __fastcall__ videomode(unsigned mode);
extern unsigned __fastcall__ cout(char ch);
#endif /* defined(__a2bejwld__text__) */

94
a2bejwld/text.s Normal file
View File

@ -0,0 +1,94 @@
;
; text.s
; a2bejwld
;
; Created by Jeremy Rand on 2020-01-22.
; Copyright © 2020 Jeremy Rand. All rights reserved.
;
.export _videomode
.export _cout
.include "apple2.inc"
.CODE
.proc _cout
; This is a thin wrapper around the standard Apple // cout routine. It switches
; the ROM back in, calls cout and then switches the 16k RAM space back in as
; expected by the cc65 environment. Because the standard library routines with
; the apple2 cc65 target converts all lowercase to upper case, I don't want to use
; printf(), etc. Instead, I have written my own print routines and at its root is
; this cout wrapper.
bit $C082
jsr $FDED
bit $C080
rts
.endproc
.proc _videomode
; I grabbed this code from the cc65 library and modified it to work on the 6502
; (vs the 65c02 it was written for). I am trying to get this game to work on an
; unenhanced //e which means it must be compiled for the apple2 (vs the apple2enh)
; cc65 target. When that is selected, the videomode() function, among other things
; is no longer available.
;
; So, this comes from the apple2enh library and is slightly modified to avoid 65c02
; instructions.
; Get and save current videomode flag
bit RD80VID
php
; If we are in 80 column mode then the 80 column firmware is
; known to be active so we can just print the ctrl-char code
; (even if this only means staying in the current videomode)
bpl :+
jsr _cout
clc
bcc done
; If we are in 40 column mode and want to set 40 column mode
; then we explicitly do nothing as we neither know about the
; current state of the 80 column firmware nor want to fix it
: cmp #$11 ; Ctrl-char code for 40 cols
beq done
; If we are in 40 column mode and want to set 80 column mode
; then we first presume the 80 column firmware being already
; active and print the ctrl-char code (this causes a garbage
; char to be printed on the screen if isn't already active)
jsr _cout
; If we successfully switched to 80 column mode then the 80
; column firmware was in fact already active and we're done
bit RD80VID
bmi done
; The 80 column firmware isn't already active so we need to
; initialize it - causing the screen to be cleared and thus
; the garbage char printed above to be erased (but for some
; reason the cursor horizontal position not to be zeroed)
lda #0
sta CH
; Initializing the 80 column firmware needs the ROM switched
; in, otherwise it would copy the F8 ROM to the LC (@ $CEF4)
bit $C082
; Initialize 80 column firmware
jsr $C300 ; PR#3
; Switch in LC bank 2 for R/O
bit $C080
; Return ctrl-char code for setting previous
; videomode using the saved videomode flag
done:
lda #$11 ; Ctrl-char code for 40 cols
plp
bpl :+
lda #$12 ; Ctrl-char code for 80 cols
: rts ; X was preserved all the way
.endproc

View File

@ -8,6 +8,7 @@
#include <conio.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -19,21 +20,43 @@
#include "joystick.h"
#include "machine.h"
#include "mouseWrapper.h"
#include "sound.h"
#include "text.h"
// Defines
#define SAVE_OPTIONS_FILE "a2bejwld.opts"
#define VERSION "v1.2"
#define SAVE_OPTIONS_FILE "A2BEJWLD.OPTS"
#define VERSION "v2.7"
#define OPTIONS_VERSION_UNSAVED 0
#define OPTIONS_VERSION_V2 2
#define OPTIONS_VERSION 3
#define OPTION_JOYSTICK_ENABLED (1 << 0)
#define OPTION_MOUSE_ENABLED (1 << 1)
#define OPTION_SOUND_ENABLED (1 << 2)
#define OPTION_MOCKINGBOARD_ENABLED (1 << 3)
#define OPTION_MOCKINGBOARD_SPEECH_ENABLED (1 << 4)
// Typedefs
typedef struct tGameOptions {
bool optionsSaved;
typedef struct tGameOptionsV2 {
uint8_t optionsVersion;
bool enableJoystick;
bool enableMouse;
bool enableSound;
bool enableMockingboard;
bool enableMockingboardSpeech;
} tGameOptionsV2;
typedef struct tGameOptions {
uint8_t optionsVersion;
uint8_t flags;
char upChar;
char downChar;
char leftChar;
char rightChar;
} tGameOptions;
@ -73,7 +96,11 @@ static tGameCallbacks gCallbacks = {
beginDropAnim,
dropSquareFromTo,
dropSquareFromOffscreen,
endDropAnim
endDropAnim,
speakGood,
speakExcellent,
speakIncredible
};
@ -93,38 +120,50 @@ static tMouseCallbacks gMouseCallbacks = {
static bool gShouldSave = false;
static tGameOptions gGameOptions = {
false,
false,
true,
true,
OPTIONS_VERSION_UNSAVED, // optionsVersion
(OPTION_MOUSE_ENABLED | OPTION_SOUND_ENABLED | OPTION_MOCKINGBOARD_ENABLED | OPTION_MOCKINGBOARD_SPEECH_ENABLED), // flags
'I', // upChar
'M', // downChar
'J', // leftChar
'K' // rightChar
};
// Implementation
void badThingHappened(void)
static void printChar (char ch)
{
if (gGameOptions.enableSound)
printf("\007");
if (ch == '\n')
ch = '\r';
ch |= 0x80;
cout(ch);
}
static void printString(char * buffer)
{
char ch;
while (*buffer != '\0') {
ch = *buffer;
printChar(ch);
buffer++;
}
}
void playSound(int8_t startFreq, int8_t duration)
static void printInteger(uint16_t val)
{
int8_t freq;
if (!gGameOptions.enableSound)
return;
while (duration > 0) {
asm ("STA %w", 0xc030);
freq = startFreq;
while (freq > 0) {
freq--;
}
duration--;
}
static char buffer[7];
snprintf(buffer, sizeof(buffer), "%u", val);
printString(buffer);
}
static void badThingHappened(void)
{
if ((gGameOptions.flags & OPTION_SOUND_ENABLED) != 0)
printString("\007");
}
@ -135,19 +174,19 @@ static void showAndClearDblLoRes(void)
}
void saveOptions(void)
static void saveOptions(void)
{
FILE *optionsFile = fopen(SAVE_OPTIONS_FILE, "wb");
if (optionsFile != NULL) {
gGameOptions.optionsSaved = true;
gGameOptions.optionsVersion = OPTIONS_VERSION;
fwrite(&gGameOptions, sizeof(gGameOptions), 1, optionsFile);
fclose(optionsFile);
}
}
bool loadOptions(void)
static bool loadOptions(void)
{
FILE *optionsFile = fopen(SAVE_OPTIONS_FILE, "rb");
@ -162,80 +201,291 @@ bool loadOptions(void)
fclose(optionsFile);
// If we are upgrading from v1 to v2 of the options file, then:
// - Force the mouse option on. This option is now only used to disable the mouse when one is
// present. When no mouse is installed, this option does nothing.
// - There used to be a tSlot of the mockingboard where we now have the enableMockingboard boolean.
// Overwrite it with true, forcing mockingboard sound to be on if one is detected.
// - There used to be a boolean to enable/disable the speech chip on the mockingboard. It was only
// true if the user enabled it. Now that we can detect the speech chip, the value is default true
// and the user can disable speech if they want.
if (gGameOptions.optionsVersion < OPTIONS_VERSION) {
tGameOptionsV2 * oldOptions = (tGameOptionsV2 *)&gGameOptions;
if (oldOptions->enableJoystick)
gGameOptions.flags = OPTION_JOYSTICK_ENABLED;
else
gGameOptions.flags = 0;
if (oldOptions->enableMouse)
gGameOptions.flags |= OPTION_MOUSE_ENABLED;
if (oldOptions->enableSound)
gGameOptions.flags |= OPTION_SOUND_ENABLED;
if (oldOptions->enableMockingboard)
gGameOptions.flags |= OPTION_MOCKINGBOARD_ENABLED;
if (oldOptions->enableMockingboardSpeech)
gGameOptions.flags |= OPTION_MOCKINGBOARD_SPEECH_ENABLED;
if (gGameOptions.optionsVersion < OPTIONS_VERSION_V2)
gGameOptions.flags |= (OPTION_MOUSE_ENABLED | OPTION_MOCKINGBOARD_ENABLED | OPTION_MOCKINGBOARD_SPEECH_ENABLED);
gGameOptions.upChar = 'I';
gGameOptions.downChar = 'M';
gGameOptions.leftChar = 'J';
gGameOptions.rightChar = 'K';
gGameOptions.optionsVersion = OPTIONS_VERSION;
}
return true;
}
void applyNewOptions(tGameOptions *newOptions)
static void applyNewOptions(tGameOptions *newOptions)
{
bool oldEnableMouse = gGameOptions.enableMouse;
// If there is no change in game options, then nothing to do.
if (memcmp(newOptions, &gGameOptions, sizeof(gGameOptions)) == 0) {
return;
}
memcpy(&gGameOptions, newOptions, sizeof(gGameOptions));
gGameOptions.optionsSaved = false;
if (oldEnableMouse != gGameOptions.enableMouse) {
if (gGameOptions.enableMouse) {
gGameOptions.enableMouse = initMouse(&gMouseCallbacks);
}
printString("\n\n\n Saving options...");
if ((gGameOptions.flags & (OPTION_SOUND_ENABLED | OPTION_MOCKINGBOARD_ENABLED | OPTION_MOCKINGBOARD_SPEECH_ENABLED)) !=
(newOptions->flags & (OPTION_SOUND_ENABLED | OPTION_MOCKINGBOARD_ENABLED | OPTION_MOCKINGBOARD_SPEECH_ENABLED))) {
// If the sound parameters have changed, then re-init sounds
soundInit(((newOptions->flags & OPTION_SOUND_ENABLED) != 0),
((newOptions->flags & OPTION_MOCKINGBOARD_ENABLED) != 0),
((newOptions->flags & OPTION_MOCKINGBOARD_SPEECH_ENABLED) !=0));
}
memcpy(&gGameOptions, newOptions, sizeof(gGameOptions));
gGameOptions.optionsVersion = OPTIONS_VERSION_UNSAVED;
saveOptions();
}
void selectOptions(void)
static void showCursor(void)
{
cout(0x20);
}
static void replaceCursor(char ch)
{
cout(CH_CURS_LEFT);
printChar(ch);
}
static char getKey(void)
{
return toupper(cgetc());
}
static bool yorn(void)
{
char ch;
bool result = true;
showCursor();
while (true) {
ch = getKey();
if (ch == 'N') {
result = false;
break;
}
if (ch == 'Y')
break;
badThingHappened();
}
replaceCursor(ch);
return result;
}
static void getSoundOptions(tGameOptions *newOptions)
{
tSlot slot;
printString("\n\nEnable sounds? (Y/N) ");
if (yorn()) {
newOptions->flags |= OPTION_SOUND_ENABLED;
} else {
newOptions->flags &= ~OPTION_SOUND_ENABLED;
return;
}
// If no mockingboard present, don't bother to ask whether to enable/disable it.
slot = mockingBoardSlot();
if (slot == 0)
return;
printString("\nEnable MockingBoard sound found in slot ");
printInteger(slot);
printString("? (Y/N) ");
if (yorn()) {
newOptions->flags |= OPTION_MOCKINGBOARD_ENABLED;
} else {
newOptions->flags &= ~OPTION_MOCKINGBOARD_ENABLED;
return;
}
// If the mockingboard does not have a speech chip, do not prompt whether to
// enable/disable it.
if (!mockingBoardHasSpeechChip())
return;
printString("\nEnable speech on the Mockingboard? (Y/N) ");
if (yorn()) {
newOptions->flags |= OPTION_MOCKINGBOARD_SPEECH_ENABLED;
} else {
newOptions->flags &= ~OPTION_MOCKINGBOARD_SPEECH_ENABLED;
}
}
static char getKeyDirection(char *dir, char current, char other1, char other2, char other3)
{
char ch;
printString("\nKey for ");
printString(dir);
printString(" movement (current ");
printChar(current);
printString(") ");
showCursor();
while (true) {
ch = getKey();
if ((isalnum(ch)) &&
(ch != 'Q') &&
(ch != 'R') &&
(ch != 'O') &&
(ch != 'H') &&
(ch != other1) &&
(ch != other2) &&
(ch != other3))
break;
badThingHappened();
}
replaceCursor(ch);
return ch;
}
static void getKeyboardOptions(tGameOptions *newOptions)
{
printChar('\n');
newOptions->upChar = getKeyDirection("up", newOptions->upChar, 0, 0, 0);
newOptions->downChar = getKeyDirection("down", newOptions->downChar, newOptions->upChar, 0, 0);
newOptions->leftChar = getKeyDirection("left", newOptions->leftChar, newOptions->upChar, newOptions->downChar, 0);
newOptions->rightChar = getKeyDirection("right", newOptions->rightChar, newOptions->upChar, newOptions->downChar, newOptions->leftChar);
}
static void selectOptions(void)
{
tGameOptions newOptions;
unshowDblLoRes();
videomode(VIDEOMODE_80x24);
videomode(0x12);
clrscr();
memcpy(&newOptions, &gGameOptions, sizeof(newOptions));
while (true) {
bool enableSound = ((newOptions.flags & OPTION_SOUND_ENABLED) != 0);
bool enableMockingboard = ((newOptions.flags & OPTION_MOCKINGBOARD_ENABLED) != 0);
clrscr();
printf(
printString(
// 0000000001111111111222222222233333333334444444444555555555566666666667
// 1234567890123456789012345678901234567890123456789012345678901234567890
" Apple // Bejeweled\n"
" Options\n"
"\n"
" J - Joystick control - %s\n"
" M - Mouse control - %s\n"
" S - Sound - %s\n"
"\n"
" Type a letter to toggle a setting or any other key to save settings\n"
" and continue",
(newOptions.enableJoystick ? "Enable" : "Disabled"),
(newOptions.enableMouse ? "Enable" : "Disabled"),
(newOptions.enableSound ? "Enable" : "Disabled"));
" K - Keyboard control - ");
printChar(newOptions.upChar);
printChar('\n');
printString(" ");
printChar(newOptions.leftChar);
printChar(' ');
printChar(newOptions.rightChar);
printChar('\n');
printString(" ");
printChar(newOptions.downChar);
printChar('\n');
printString(
" J - Joystick control - ");
printString(((newOptions.flags & OPTION_JOYSTICK_ENABLED) != 0) ? "Enabled\n" : "Disabled\n");
if (hasMouse())
{
printString(
" M - Mouse control - ");
printString(((newOptions.flags & OPTION_MOUSE_ENABLED) != 0) ? "Enabled\n" : "Disabled\n");
}
printString(
" S - Sound - ");
printString(enableSound ? "Enabled\n" : "Disabled\n");
switch (cgetc()) {
case 'j':
if (enableSound) {
tSlot slot = mockingBoardSlot();
if (slot != 0) {
printString(
// 0000000001111111111222222222233333333334444444444555555555566666666667
// 1234567890123456789012345678901234567890123456789012345678901234567890
" MockingBoard - ");
printString(enableMockingboard ? "Enabled (Slot " : "Disabled (Slot ");
printInteger(slot);
printString(")\n");
if ((enableMockingboard) &&
(mockingBoardHasSpeechChip()))
{
printString(
// 0000000001111111111222222222233333333334444444444555555555566666666667
// 1234567890123456789012345678901234567890123456789012345678901234567890
" Speech - ");
printString(((newOptions.flags & OPTION_MOCKINGBOARD_SPEECH_ENABLED) != 0) ? "Enabled\n" : "Disabled\n");
}
}
}
printString(
// 0000000001111111111222222222233333333334444444444555555555566666666667
// 1234567890123456789012345678901234567890123456789012345678901234567890
"\n"
" Type a letter to change a setting or any other key to save settings\n"
" and continue");
switch (getKey()) {
case 'J':
newOptions.enableJoystick = !newOptions.enableJoystick;
if (newOptions.enableJoystick) {
newOptions.enableMouse = false;
}
newOptions.flags ^= OPTION_JOYSTICK_ENABLED;
break;
case 'm':
case 'M':
newOptions.enableMouse = !newOptions.enableMouse;
if (newOptions.enableMouse) {
newOptions.enableJoystick = false;
}
break;
case 's':
case 'S':
newOptions.enableSound = !newOptions.enableSound;
getSoundOptions(&newOptions);
break;
case 'K':
getKeyboardOptions(&newOptions);
break;
case 'M':
if (hasMouse()) {
newOptions.flags ^= OPTION_MOUSE_ENABLED;
break;
}
// Fall through. If no mouse, then pressing m is a fall through into the save code.
default:
applyNewOptions(&newOptions);
clrscr();
@ -250,15 +500,26 @@ void printInstructions(void)
int seed = 0;
unshowDblLoRes();
videomode(VIDEOMODE_80x24);
videomode(0x12);
clrscr();
printf(
printString(
// 0000000001111111111222222222233333333334444444444555555555566666666667
// 1234567890123456789012345678901234567890123456789012345678901234567890
" Apple // Bejeweled (" VERSION ")\n"
" by Jeremy Rand\n"
"\n"
" Use I-J-K-M, the arrow keys, joystick or mouse to move your selection.\n"
" Use ");
printChar(gGameOptions.upChar);
printChar('-');
printChar(gGameOptions.leftChar);
printChar('-');
printChar(gGameOptions.rightChar);
printChar('-');
printChar(gGameOptions.downChar);
printString(
" the arrow keys, joystick or mouse to move your selection.\n"
" Hold either apple key, joystick or mouse button and move your selection\n"
" to swap two jewels and match 3 or more jewels. When you match three\n"
" jewels, they disappear and new jewels will drop from the top.\n"
@ -286,8 +547,7 @@ void printInstructions(void)
srand(seed);
switch (cgetc()) {
case 'o':
switch (getKey()) {
case 'O':
selectOptions();
break;
@ -327,9 +587,10 @@ static void drawBoard(void)
static void quitGame(void)
{
unshowDblLoRes();
videomode(VIDEOMODE_40x24);
videomode(0x11);
clrscr();
shutdownMouse();
soundShutdown();
uninitMachine();
@ -474,33 +735,34 @@ static bool swapDir(tDirection dir)
}
static bool isAppleButtonPressed(void)
{
return (isButtonPressed(JOY_BUTTON_0) || isButtonPressed(JOY_BUTTON_1));
}
static void endGame(void)
{
videomode(VIDEOMODE_80x24);
char ch;
videomode(0x12);
mixedTextMode();
cputsxy(0, 0, " No more moves - GAME OVER!!");
gotoxy(0,1);
cprintf( " You made it to level %u", getLevel());
cputsxy(0, 3, " Play again (Y/N)?");
speakNoMoreMoves();
printString(" No more moves - GAME OVER!!\n"
" You made it to level ");
printInteger(getLevel());
printString("\n"
" Play again (Y/N)? ");
showCursor();
while (true) {
switch (cgetc()) {
case 'y':
ch = getKey();
switch (ch) {
case 'Y':
replaceCursor(ch);
printString("\n");
return;
case 'n':
case 'N':
case CH_ESC:
case 'q':
case 'Q':
replaceCursor(ch);
quitGame();
break;
@ -526,12 +788,15 @@ static void refreshLevel(tLevel level)
{
bool waiting = true;
videomode(VIDEOMODE_80x24);
videomode(0x12);
mixedTextMode();
speakLevelComplete();
gotoxy(0, 0);
cprintf( " Completed level %u!!", level);
cputsxy(0, 2, " Press space to continue to the next level...");
printString("\n"
" Completed level ");
printInteger(level);
printString("!!\n"
" Press space to continue to the next level...");
while (waiting) {
switch (cgetc()) {
@ -545,7 +810,9 @@ static void refreshLevel(tLevel level)
}
}
printString("\n");
showAndClearDblLoRes();
speakGetReady();
}
@ -562,30 +829,22 @@ static void getHint(void)
void initUI(void)
{
bool optionsLoaded;
bool mouseInitialized;
initMachine();
optionsLoaded = loadOptions();
initGameEngine(&gCallbacks);
mouseInitialized = initMouse(&gMouseCallbacks);
soundInit(((gGameOptions.flags & OPTION_SOUND_ENABLED) != 0),
((gGameOptions.flags & OPTION_MOCKINGBOARD_ENABLED) != 0),
((gGameOptions.flags & OPTION_MOCKINGBOARD_SPEECH_ENABLED) != 0));
// If we couldn't initialize a mouse and it was enabled on the options, then disable it.
if ((!mouseInitialized) &&
(gGameOptions.enableMouse)) {
gGameOptions.enableMouse = false;
gGameOptions.optionsSaved = false;
// If there were no options loaded, then let's turn on the joystick instead.
if (!optionsLoaded) {
gGameOptions.enableJoystick = true;
}
}
initGameEngine(&gCallbacks);
initMouse(&gMouseCallbacks);
initJoystick(&gJoyCallbacks);
if (!gGameOptions.optionsSaved) {
if (gGameOptions.optionsVersion == OPTIONS_VERSION_UNSAVED) {
saveOptions();
}
}
@ -649,8 +908,7 @@ static bool joystickChangedCallback(tJoyState *oldState, tJoyState *newState)
if (oldState->position != JOY_POS_CENTER)
return false;
if ((newState->button0) ||
(newState->button1)) {
if (newState->button) {
switch (newState->position) {
case JOY_POS_UP:
return swapDir(DIR_UP);
@ -678,10 +936,7 @@ static bool joystickChangedCallback(tJoyState *oldState, tJoyState *newState)
static bool joystickNoChangeCallback(tJoyState *oldState)
{
if (oldState->button0)
return false;
if (oldState->button1)
if (oldState->button)
return false;
joystickMove(oldState->position);
@ -697,84 +952,78 @@ static bool pollKeyboard(void)
if (!kbhit())
return result;
ch = cgetc();
ch = getKey();
if (ch == gGameOptions.upChar)
ch = 0x0b;
else if (ch == gGameOptions.downChar)
ch = 0x0a;
else if (ch == gGameOptions.leftChar)
ch = CH_CURS_LEFT;
else if (ch == gGameOptions.rightChar)
ch = CH_CURS_RIGHT;
if ((ch < 128) &&
(isButtonPressed()))
ch += 128;
switch (ch) {
case 'i':
case 'I':
case CH_CURS_UP:
if (!isAppleButtonPressed()) {
moveDir(DIR_UP);
break;
}
// Fallthrough...
// case CH_CURS_UP:
case 0x0b:
moveDir(DIR_UP);
break;
case 139:
result = swapDir(DIR_UP);
break;
case 'j':
case 'J':
case CH_CURS_LEFT:
if (!isAppleButtonPressed()) {
moveDir(DIR_LEFT);
break;
}
// Fallthrough...
moveDir(DIR_LEFT);
break;
case 136:
result = swapDir(DIR_LEFT);
break;
case 'k':
case 'K':
case CH_CURS_RIGHT:
if (!isAppleButtonPressed()) {
moveDir(DIR_RIGHT);
break;
}
// Fallthrough...
moveDir(DIR_RIGHT);
break;
case 149:
result = swapDir(DIR_RIGHT);
break;
case 'm':
case 'M':
case CH_CURS_DOWN:
if (!isAppleButtonPressed()) {
moveDir(DIR_DOWN);
break;
}
// Fallthrough...
// case CH_CURS_DOWN:
case 0x0a:
moveDir(DIR_DOWN);
break;
case 138:
result = swapDir(DIR_DOWN);
break;
case CH_ESC:
case 'q':
case 'Q':
if (gShouldSave) {
videomode(VIDEOMODE_80x24);
videomode(0x12);
mixedTextMode();
gotoxy(0, 0);
cprintf("Saving your game so you can continue\r\n later...");
printString("\nSaving your game so you can continue\n later...");
saveGame();
}
quitGame();
break;
case 'r':
case 'R':
refreshScore(0);
startNewGame();
gShouldSave = false;
return true;
case 'o':
case 'O':
selectOptions();
showAndClearDblLoRes();
drawBoard();
break;
case 'h':
case 'H':
getHint();
break;
@ -803,33 +1052,17 @@ void playGame(void)
gScoreBar = 0;
gShouldSave = false;
printf("\n\nChecking for a saved game...");
printString("\n\nChecking for a saved game...");
if (loadGame()) {
bool gotAnswer = false;
bool loadSavedGame = false;
printf("\n\nYou have a saved game!\n Would you like to continue it (Y/N)");
while (!gotAnswer) {
ch = cgetc();
switch (ch) {
case 'y':
case 'Y':
printf("\n\nLoading your saved puzzle");
gotAnswer = true;
gShouldSave = true;
gameLoaded = true;
break;
case 'n':
case 'N':
gotAnswer = true;
break;
default:
badThingHappened();
break;
}
printString("\n\nYou have a saved game!\n Would you like to continue it (Y/N) ");
loadSavedGame = yorn();
if (loadSavedGame) {
printString("\n\nLoading your saved puzzle");
gShouldSave = true;
gameLoaded = true;
}
}
@ -838,7 +1071,16 @@ void playGame(void)
startNewGame();
}
drawBoard();
speakGo();
while (true) {
if (gameIsOver()) {
endGame();
showAndClearDblLoRes();
refreshScore(0);
startNewGame();
gShouldSave = false;
}
resetStarAnim();
while (true) {
@ -848,23 +1090,15 @@ void playGame(void)
break;
}
if ((gGameOptions.enableJoystick) &&
if (((gGameOptions.flags & OPTION_JOYSTICK_ENABLED) != 0) &&
(pollJoystick())) {
break;
}
if ((gGameOptions.enableMouse) &&
if (((gGameOptions.flags & OPTION_MOUSE_ENABLED) != 0) &&
(pollMouse())) {
break;
}
}
if (gameIsOver()) {
endGame();
showAndClearDblLoRes();
refreshScore(0);
startNewGame();
gShouldSave = false;
}
}
}

View File

@ -10,7 +10,7 @@
#define __a2bejwld__ui__
#include <stdint.h>
#include <stdbool.h>
// API
@ -21,7 +21,5 @@ extern void printInstructions(void);
extern void playGame(void);
extern void playSound(int8_t startFreq, int8_t duration);
#endif /* defined(__a2bejwld__ui__) */

View File

@ -38,7 +38,10 @@ RDVBLBAR := $C019
.proc _vblIRQCallback
stz vbl2cByte
pha
lda #0
sta vbl2cByte
pla
rts
.endproc
@ -61,4 +64,4 @@ compType:
.BYTE $7e
vbl2cByte:
.BYTE $00
.BYTE $00