Sunday, November 8, 2015

CoCo Conversion for SMS Joypad

I've never been a huge fan of gaming with a joypad, but many people are. With that said, I do agree that a digital gaming input can certainly be more effective than the CoCo's analog joysticks for any number of games. My preference for digital joysticks on the CoCo was strong enough to lead me to build a CoCo joystick from arcade components for use when showing Fahrfall to the general public. I even published the schematic I used for building the internals of that joystick in an earlier post on this blog.

Using an arcade stick for playing (most) CoCo games is great! But an arcade stick can be a bit large and unwieldy, and it certainly does not travel well. Having a joypad is a nice alternative, but making one from scratch is a lot to manage. Using a donor joypad is an attractive option, but which one? The NES controller fits OK, but it has more buttons than the CoCo can use. It turns-out that the SEGA Master System controller is also a good fit, and it has the same number of buttons as are supported by the CoCo3.

Part of me hates destroying one vintage device to enhance another. However, there are a lot of SMS controllers out in the wild. So, I made the call to sacrifice an SMS controller in order to make the world better for CoCo users! If you think this was a bad choice, well, then I hope you'll forgive me and move on... :-)

Peeking Inside

As a first step, we must open the SMS controller. Inside (at least for the ones I have seen), there are a couple of small PCBs with conductive pads for all the buttons.

The wires from the joystick cable connect to the edge of the PCB holding each button, and a small wire connects the two PCBs for a shared ground signal. This is about as simple as things get..

Cut and Splice

Removing the wires on the direction pad made room for installing the resitors needed for the circuit that turns the button inputs into the analog signals needed by the CoCo. The existing PCB had most of the connections needed, but one problem is that the original SMS controller circuit had each button designed to pull a signal to ground when pressed. As a result, there was one trace that connected to all four direction buttons.
Direction PCB w/ central ground connection
The CoCo circuit needs two of the buttons to connect to Ground, but it needs the other two buttons to connect to +5V. As a results, the PCB needed to be modified to accommodate that connection. A hobby knife was useful here both for breaking the connections and for scraping away enough solder mask to allow for new connections to be made.
Direction PCB w/ modification
Once the direction PCB was modified, it was a trivial (if somewhat tedious) operation to attach the eight resistors need to implement the switched voltage divider circuit used to feed the CoCo's analog joystick inputs.

"Big" resistors connected
One axis completed

Both axes completed
Twist and Tuck

With the resistors added to the direction PCB, all that is left are the finishing touches. The existing cable was retained, but the connector was removed and replaced with the CoCo's 6-pin DIN joystick connector. The wires were connected to the existing PCB holes for the two buttons and ground, and directly to the resistor leads for power and the direction axes. A little creative twisting and some nip and tuck made everything fit neatly back into the original SMS housing.


With everything sealed-up, I used a standard label maker to indicate what I had done. Maybe you can dress yours up more nicely?



That is pretty much it! Please refer to the joystick schematic from my earlier posting for more information about the switched voltage divider circuit. Thanks for reading, and happy CoCo-ing!

Saturday, November 7, 2015

Vectrex CRT Replacement

NOTE: Handling a CRT of any size is a potentially dangerous proposition. Not only are CRTs driven by very high voltages and capable of storing a high voltage charge for long periods of time (even after being turned-off and/or disconnected), but they are also glass tubes containing a powerful vacuum and therefore pose the risk of serious injury associated with implosion. Any attempt to replicate the actions described below is done completely at your own riskTHIS MEANS YOU!

Twenty years or so ago I was fairly deep into arcade collecting, including the "elite" world of collecting vector arcade games. Vector games are a breed apart, using a display technology that is in many ways more closely related to oscilloscopes than to televisions. When I first started arcade collecting, I had never heard of the Vectrex. But it wasn't long before I heard talk from the other vector arcade collectors regarding the Vectrex. Soon I was not only aware of the Vectrex but I was desperate to have one...

In the days before eBay, it was often very difficult (or just extremely lucky) to find any sort of rare item. This was even more true for an item with any age on it. While this was a long time ago, the Vectrex still was more than a dozen years old! Plus, those that I knew who had a Vectrex just weren't interested in parting with it. Finally I came across someone who had two non-working Vectrex machines, which I acquired in hopes of making at least one working machine.

Some of my friends may have seen that back in December of 2013 (after a long hiatus) I succeeded at that goal by swapping the logic boards between the two broken Vectrex machines. Around that time, I also determined that the CRT in the (still) non-working machine had a broken neck. The resulting lack of vacuum in the CRT rendered it completely useless. I had done some research into possible donor CRTs that might be available, but I mostly put the project aside until one day not too long ago I stumbled upon an interesting video on YouTube...


Inspiration!


I had long ago heard that no one was making CRTs any longer, and it had not occurred to me to search for a NOS supplier. In my excitement, I ordered a tube and waited for it to arrive. In less than a week I was in possession of a brand new (or at least NOS) CRT that was a perfect match for my Vectrex. Or was it?

Original CRT w/ Mounting Ears

Replacement CRT -- No Ears!

(Not) All Ears

A closer look at the video might have prevented my dilemma. You see, the original CRT is constructed in such a way that the steel band around the edge (which is supposed to limit the possible effects of an implosion) holds in place four mounting lugs for securing the CRT in place. The new CRT has the anti-implosion band but it lacks the mounting lugs. In retrospect, had I realized that this would be the situation then I might not have ordered the replacement CRT at all. In this case, I am glad my excitement was enough to put me in this predicament. :-)


Strap Up!

Inspriation struck when I thought of the strapping material that plumber's use for hanging pipes and a number of other utilitarian purposes. Although I considered using the traditional metal variety, the modern plastic version seemed like it would be easier to fit to the purpose. Plus, I thought that it might be a bit less likely to present an electric shock hazard to anyone that might be poking around inside the Vectrex (e.g. me)...

The Vectrex in question still has the logic board problems that led me to the original logic board swap. So, in order to test the CRT replacement I connected a working logic board to the newly serviced monitor section of the Vectrex in question and I was able to play a rousing game of Minestorm. Overall, the machine is still in the non-working category, but at least the vector monitor is saved!

So, the point is that if you have a Vectrex and the CRT is busted or just worn-out, there is no need to despair. At least for now there are still workable NOS replacements that can save the day. With that said, do make sure that you handle the CRT and other high voltage electronics properly. Otherwise, the dead Vectrex will be the least of your family's worries!







Saturday, August 1, 2015

Down and Out

Hmmm...well, the RetroChallenge 2015/07 event ended yesterday and I have made essentially no progress since my previous post. I guess it is time to acknowledge defeat!

That is not to say that I didn't enjoy any good "retro" time this month. Not only did I (along with my pal Neil Blanchard) record and release our third episode (i.e. "episode 2") of The CoCo Crew Podcast, but I also made it to KansasFest, where I gave talks on the CoCo and on Fahrfall. Unfortunately, travel takes a lot out of me and I just never got back into the swing with my RetroChallenge project this month.

I still want to explore some CoCo cartridge port expansions in the future. When I do so, I will likely be documenting that here. Chances are that there will be some other stuff here from time to time as well! I might even be back for another RetroChallenge in the future. So if you want to keep up with any of that, then I hope you will subscribe to the feed and stay tuned!

Tuesday, July 7, 2015

Not Quite Dead

I was feeling a bit defeated yesterday, perhaps a bit too much. I may be down, but I'm not totally out! Without a breakout board, my circuits may be a bit more tedious to make and they will require more care in transport. Nevertheless, I can still make a little noise...

Optimistic Tone

I started with a simple circuit, a 555 timer wired as an astable multivibrator. I am feeding the output into the CART line on the CoCo cartridge port, which is intended for use as an interrupt signal. As such, it is tied to the PIA which drives the FIRQ signal on the 6809. This circuit gives me a new timing source to use for programs on the CoCo!

I configured the 555 circuit to generate a continuous square(-ish) wave at approximately 4800 Hz. This would require quite a bit less service than the ~15.7 KHz Hsync signal provided by the CoCo's video chip, and it would still be fast enough to generate a wide range of useful tones and/or sound effects. To illustrate the point, I have a test program using this time source to service the 1-bit audio output on the CoCo in order to produce a lovely 2400 Hz tone.


Extended Play

So, at least I have the basis for some Retrochallenge play. With the current circuit, I might build a more flexible synthesizer or sound effects generator, or I might even expand to playback of sampled sound through the CoCo's DAC. Perhaps a simple game is in order? The possibilities are endless! There are at least a few possibilities, anyway...

So, what is next for my now improvised Retrochallenge entry? I'm unsure...I guess you'll just have to stay tuned!

Monday, July 6, 2015

Breakout Breakdown

Disaster! My cleverly contrived apparatus to break-out the CoCo cartridge port to a breadboard doesn't work!  In fact, it could even damage the CoCo...

Short Circuit

The apparatus I described in the previous post included a breakout board designed for use with the Raspberry Pi 2. This board includes a 40-pin IDC connector and pins in the footprint of a 40-pin DIP. This seemed to be a perfect match for the 40-pin CoCo cartridge port.

Unfortunately, the designer of the breakout board has "helpfully" used his knowledge of the Raspberry Pi 2 GPIO port in order to tie all of the Ground lines together on the breakout board. This might have only been an avoidable nuisance, but it turns-out that the layout of the pins on the board is such that when adapted to the CoCo cartridge port, +5V power is shorted to ground. The traces responsible for the short are not visible, so I don't think the board can easily be modified. Fortunately, at least I don't seem to have damaged any CoCo in the making of this mess!

Retreat

Time was already a bit short for me this month, as I have plans to be at KansasFest. I'm not sure I have time to order any new parts either. I'm not sure where this leaves me.

Maybe I can come-up with a way to save this project? Or perhaps I can hatch another one? I will have to take some time to consider my options.

Stay tuned...

Friday, July 3, 2015

Holiday Weekend

Well, the Retrochallenge 2015/07 event started a couple of days ago. As usual I'm off to a slow start. This weekend started a day early, giving me a little time to get going on my project. So far I've done very little, but I thought it might be useful to review the outline of the project and discuss some possibilities...

Outline

The point of this project is to exploit some features of the CoCo cartridge port for the potential benefit of game cartridges. Therefore it is reasonable to question what such features are available. This includes interrupt signals, address decoding signals, and audio input.

I have discussed the interrupt-based timing sources available on the CoCo in my other blog posts over the years. The Hsync and Vsync signals are a bit inflexible and difficult to use for audio playback in particular. Vsync is too slow to drive the DAC, and Hsync is much faster than needed -- especially since it connects through the PIA that feeds the IRQ signal on the 6809. The CART line on the CoCo cartridge port is actually tied to the PIA that feeds the FIRQ (i.e. "fast IRQ") signal on the 6809, potentially making it a great candidate for an audio playback timer signal.

The cartridge port provides two separate address decoding signals. One is the standard ROM chip select used to access program code on cartridges. The other is designed for accessing the floppy drive controller hardware. But since a game cartridge typically is used without other cartridges, that signal can be used for whatever purpose a cartridge likes. In particular, it can be used to provide access to other hardware bits that a game might need.

The CoCo cartridge also has a line that can feed an audio signal directly back into the CoCo. This could be used to enable audio generation hardware directly in the cartridge itself.

Apparatus

(Note: the apparatus does not work -- do not attempt to replicate this from the picture!)

Breakout Circuit for CoCo Cartridge Port

The purpose of this experiment is really just "proof of concept", so I won't be bothering for now with building PCBs or any other permanent design artifacts. Instead, I only want to have electrical access to the CoCo cartridge port as a means of interfacing to hand-built circuits on a breadboard.

Some time back another CoCo person produced some simple PCBs that breakout the cartridge port to a 40-pin IDC connector. More recently, the popularity of the Raspberry Pi platform has led to the availability of some small PCBs that adapt between a 40-pin IDC connector and a 40-pin DIP connector compatible with a breadboard. I combined these two items to adapt from the CoCo cartridge port to a solderless breadboard.

I often like to use a "monitor" program plugged into the the cartridge port when doing CoCo development. In order to facilitate that, I have added a "Y cable" to the mix. This should allow me both to use the "monitor" program and to have access to the cartridge port signals for circuit development.

Ideas

If I haven't lost you yet, then I probably don't need to tempt you further! Nevertheless, I will provide a couple of teasers to whet your appetite...

In order to facilitate audio playback on the CoCo, a reasonably paced signal is needed. Use of the FIRQ line is desirable, since that can be the most efficient mechanism for handling high frequency events. The more flexible interrupt and timing mechanisms of the CoCo3 illustrate that a moderately paced FIRQ signal can provide pleasing audio playback. So, a simple idea is to use a simple timer circuit (e.g. a 555 wired as an astable multivibrator) to provide such an FIRQ signal.

A normal CoCo cartridge can provide almost 16Kb of program storage. That may seem like plenty(!), but larger programs can easily consume that with graphics assets, audio samples, map data, and even just program code. One approach to extending available storage is bank switching. This can be done by using the I/O address range in the cartridge to control the bank switching hardware in order to multiplex the ROM address range onto a larger memory.

Adding audio hardware to the CoCo seems like a simple way to extend its gaming capabilities. This may have been expensive in the past, but for today's hobbyist I think this option seems quite reasonable and could make for a very collectible game cartridge. Anyway, I hope to conduct the exercise of building such a circuit as the month progresses.

If I get this far, I may have one more idea that would have seems a bit ahead of it's time when the CoCo was in stores. Still, it might be a cool option in today's market. For now I'll keep this last one under my hat...stay tuned!

Thursday, June 18, 2015

RC2015/07 Competition Entry

June is halfway gone, and another RetroChallenge event is just around the corner. July is going to be busy for me, including my first ever attendance at KansasFest. That combined with some external things had me wondering if I had time to participate in this round of RetroChallenge, but I do enjoy the events and the cadence they provide for my retrocomputing hobby. So, what to do?

The Struggle Is Real

I often have trouble coming-up with projects for these things. It is important to "size" things properly to fill a month's time without running long enough to elude completion. It should also be interesting for readers (or viewers) at a variety of technical skill levels. Of course, it also needs to be interesting for me as well! Finding the "perfect" project is probably impossible, but it is hard not to try... :-)

Spit It Out!

OK, OK...while I have at least some interest in a number of retrocomputer and retrogaming systems, there is no denying that I'm in love with the CoCo. Recently I even produced the first cartridge-based game release for the CoCo in decades. While Fahrfall cartridges only hold an EPROM, there are other capabilties of the CoCo expansion port that could be exploited for more advanced gaming possibilities.

So, for my RetroChallenge 2015/07 project I will be exploring some hardware possibilities for CoCo cartridges that might be interesting for games in particular. This will include both some existing (i.e. documented) circuits and hopefully some new ones as well.

Want to learn more?  Then you will just have to stay tuned... :-)

Saturday, June 6, 2015

Digital Joystick for a CoCo?

From time to time, we see requests on the CoCo mailing list for ways to use digital joysticks with the CoCo. You see, the CoCo is designed to use analog joysticks for pointing, like the Apple II or the IBM PC. Joysticks like that are good for applications requiring precise positioning, like Flight Simulator or the old game Doubleback. But for action-oriented arcade games like Pac Man, Frogger, or Donkey Kong, the brute force choice of a simple direction is usually preferred over precise positioning. Worse, like the Atari 5200, the original CoCo joysticks weren't even self-centering...

Adapt

While the later "deluxe" CoCo joysticks addressed the self-centering issue, analog joysticks still feel a bit sloppy for most arcade games. One option is to build an adapter that allows the use of common 9-pin digital joysticks like those used on the Atari 2600, the Commodore 64, and other machines from that era. Such adapters are built around a single integrated circuit, are relatively simple to build, and allow the use of unmodified digital joysticks with the CoCo. Tim Lindner has a YouTube video of him building just such an adapter.


Improvise

The other option involves either hacking an existing joystick to work with the CoCo or building your own to do so. These options are essentially the same, each requiring a circuit to convert switch closures into analog voltages that are meaningful to the CoCo. A hand-drawn schematic of such a circuit is shown above.

Unlike the Apple II and IBM PC, the CoCo does not use an RC timing circuit for measuring joystick position. Instead, the potentiometers in the CoCo joysticks are wired as voltage dividers. This allows for less precision in the exact choice of components, since there is no need to match-up against anything internal to the CoCo. The biggest concern would be choosing resistor values so small that the joystick burns-out the CoCo power supply. Caveat emptor!  But if you stick to the values in the schematic above, I think you will be fine...hopefully... ;-)

Overcome

The original idea for the circuit came from a post about the Vectrex, which uses a similar design for its joysticks. On each axis, the resistors are wired in an "H" configuration. The resistors on one side (the side always connected to power and ground) are significantly larger in value than the resistors on the other side of the "H". The switches are connected across the top and bottom of the "H". When a switch is closed, the equivalent resistance of the large and small resistors connected in parallel is much smaller than the value of the single large resistor on the other end of the "H". This causes the voltage at the center of the "H" to swing accordingly, fooling the CoCo into thinking that the (non-existant) potentiometer has been moved in the corresponding direction.

It would be tempting to eliminate the smaller resistors in the "H" configuration, causing the switch closure to pull the axis voltage directly to the rail voltage. The problem is that if a mechanical failure allows a pair of opposing switches to be closed at the same time, then you will have a short circuit that could damage the CoCo. Keeping resistors in the path should limit the possibilities for damage. I strongly urge any circuit builders to keep both sets of resistors.


I hope that others will find the information useful. I know of at least one other person that has used this schematic to build a CoCo joystick out of arcade components, much like I had previously done for my Fahrfall joystick. If you have any questions about the schematic, then feel free to leave them for me below. Also, you can download the PDF of the circuit if the picture of the schematic above is too small to be useful.

Enjoy!

Sunday, February 1, 2015

Final Thoughts for RC2015/01

The end of January has past, and thus came the end of another RetroChallenge event. As usual there were a number of interesting projects started, several completed, and a few derailed along the way. Count my port of Fahrfall to the Apple II in the completed category! Of course, no software is ever finished... :-)

Alpha Release

I want to make a binary available for my Apple II version of Fahrfall, but my "real world" knowledge of using an Apple II is still lacking in several ways. One of the things I don't know how to do is making disk images! In fact, I'm not even sure what sort of binary format is needed for an Apple II machine language program to be loaded from diskette...

While developing Fahrfall, I have been using the built-in monitor program on the Apple II in conjunction with a Super Serial Card and the "IN #2" and "PR #2" commands in BASIC. I used a 6502 assembler running on my Linux laptop to generate the machine code for Fahrfall, and I used a script to convert the binary output from the assembler into a series of monitor commands that I could send over the serial port. I am now making this file available as "fahrfall.txt" in the directory below:

http://www.tuxdriver.com/download/fahrfall/apple2/alpha-1/

In order to load the program, start the monitor (CALL -151 at the BASIC prompt) and upload the file through the serial port (assuming that you have already done the "IN #2" and "PR #2" as described above). Once the upload is complete, start the program executing at location $0C00 (C00G at the monitor prompt). In order to play with a joystick, just press the joystick button to start the game and use the joystick to move left and right. If you want to play with a keyboard, just press the spacebar to start the game and use the "open apple" and "closed apple" keys for left and right.

A Tale Of Two Platforms

At this point, I am tempted to make some comparisons between the CoCo and the Apple II and/or between the 6809 and the 6502. Instead, I'm going to avoid feeding the trolls and just say that both machines have (sometimes hidden) strengths and (often obvious) weaknesses that probably influenced the types of software that were historically available on each machine. There are differences between the CoCo and Apple II versions of Fahrfall, many of which are due to the strengths and weaknesses of the respective platforms. I hope that both versions feel like "native" games to the users of those platforms, as long as that doesn't interfere with making Fahrfall fun!

Moving Forward

As for what is next, that is hard to say. I like the colorful, moving background in the CoCo version of Fahrfall and I would love to bring something like that to the Apple II version, if possible. Some amount of music might be a nice addition to the Apple II version as well. Plus, there might be a better way to handle keyboard input? I'm not sure...

For some time I have wanted to go to KansasFest, a yearly Apple II convention. By all reports it is a great event, but my limited Apple II experience made me feel like too much of an outsider to be sure of having a good time. Now that I have an Apple II version of Fahrfall, at least I would have something to discuss with other KansasFest attendees! So, this may be the year I make the trip.

Anyway, I guess that is all I've got for now. I would like to thank the organizers of the RetroChallenge event as well as all of the other participants. As usual, the past month proved to be a great learning experience, a source of great reading material, and an excuse to have some good retro-fun. I hope these events keep coming until the end of time, and I intend to be involved whenever possible. I suspect that you, Dear Reader, feel the same way!  So as alway, I expect you to stay tuned... :-)

Saturday, January 31, 2015

Feature Sweep

The end of RetroChallenge 2015/01 is nigh! But is Fahrfall running on the Apple II? Well, sure it is (at least for the IIe and above)! The last couple of days have seen a flurry of feature development, but I think the result is looking fairly good...


Urge To Merge

My last post talked about adding color patterns to the platforms and using another LFSR to change the platform colors. While writing that code, I discovered that I was close to the edge of a performance barrier for drawing during the vertical blanking interval. I thought that was resolved by some code optimization, but the issue returned when I attempted to merge the changes into the main game code. Fortunately I was able to find a few more minor tweaks that allowed me to merge the color changes and to still draw everything within the allotted time constraints.


Making Introductions

Games generally have a starting and an ending, and it is appropriate to mark those points prominently. Like any game, Fahrfall needs to introduce itself to the player and it needs to tell the player how well they performed. The Apple II offers a video mode that allows for graphics on most of the screen while providing four lines of text at the bottom of the screen. Fahrfall now uses this mode to display some colorful graphics while communicating to the player through text at the bottom of the screen both before and after a game is played.


Keeping Score

With the "intro" and "game over" screens in place, it was finally time to add scoring. The score itself increments as a timer while the game is in progress. Since the score is displayed as a decimal number, this seems like a perfect application for the BCD support built into the 6502! This allows for maintaining the score just like any other binary number, while making conversion of the score into screen data almost painless.

I have been using a joystick while developing the Fahrfall code, and using a joystick is the preferred method of play. Not everyone will have a joystick, so supporting the keyboard is desirable as an alternative. Unfortunately, the keyboard repeat rate is too slow to support use of the arrow keys for controlling Fahrve. (Maybe I just don't know how to get around relying on the keyboard to report repeated keys?) However, unlike most of the keys on the Apple IIe keyboard the "Open Apple" and "Closed Apple" keys are accessed directly through "soft switches". This lets me poll those keys directly at any time, so I am using those keys for "left" and "right" when keyboard access is selected. (FWIW, the keyboard access selection happens when the <spacebar> key is used to start the game.)

The game ending "sizzle" is like a Fahrfall trademark. Some people hate it, but it always gives me a chuckle to watch a new player nearly jump out of their skin the first time they end a game! The sound itself is just a short burst of noise, implemented by using the LFSR to determine when the speaker is toggled. This addition is a nice "final touch" to make Fahrfall seem complete.

Well, I think that is "pencils down" for my RetroChallenge 2015/01 entry. I now know a lot more about programming the Apple II and the 6502 processor, and I have an Apple II port of Fahrfall to show for my efforts. I reckon this counts as a success! I'll probably be back later today or tomorrow with a wrap-up post, so I hope you will stay tuned... :-)

Monday, January 26, 2015

Over The Wall

We are now in the final lap of the Retrochallenge 2015/01 event! Time is short, and Fahrfall still lacks some key features (like keeping score)... Worse, I got a bit distracted while chasing a performance issue!!

Candy Canes Aloft

In Fahrfall, as the game progresses the color of new platforms changes periodically. I enjoy this feature, as it is both an indicator of how far the game has progressed (almost like a score...), and it rewards the player with something new in return for playing a bit longer. The graphics in the Apple II version won't allow for the "checker board" patterns available on the CoCo, but it will allow for both solid colors and a striped pattern that looks a bit like a "candy cane".

The existing code for drawing platforms only worked with single-colored platforms. I made the necessary modifications to allow for multi-colored platforms, and added some scaffolding to feed random color patterns to Fahrfall. This resulted in multi-colored platforms, but it also resulted in Fahrve's head disappearing before he reached the top of the screen!


Crossing The Line

For a while, I struggled to find the cause of this issue. I carefully checked the code changes, and I even went so far as to rewrite and test the changes in a step-by-step manner. I was almost at a loss as to the cause of this problem, until I noticed that Fahrve's head seemed to make it slightly higher up on the far right of the screen than on the far left. That observation led me to believe that I was overrunning the end of the vertical blank interval before finishing with drawing Fahrve.

With that suspicion in hand, I applied a trick for checking the timing of my vertical blank drawing work. When I start the vertical blanking period, I switch the video mode to showing text instead of low-resolution graphics. (These modes share the same video buffer on the Apple II, and the background data for the graphics screen displays as visible characters in text mode as well.) I switch the video mode back to graphics after Fahrve is drawn, which would be indetectable if done before the end of the vertical blanking interval. But as suspected, it was clear that my drawing code was not completing in time.

Redemption

Up until now, the code in the Apple II port of Fahrfall has largely grown organically. Heeding the axiom that premature optimization is the root of all evil, I have largely focused on getting things working rather than making them run as fast as possible. Unfortunately, at some point things that run too slowly simply aren't working, whether they are correct or not. Drawing during the vertical blanking interval is, in fact, a "real time" programming task! :-)

In my game loop, I was erasing the old platforms and the old Fahrve, calculating movement and detecting collisions, then drawing the new platforms and the new Fahrve. As an optimization, I delayed the movement calculations and collision detection until after drawing the new objects. This bought a little time, but not enough to meet the required deadline.

Something else I was doing sloppily was erasing the platforms. For this I was actually using the same routine I use to draw the platforms but with the data changed to use the background color. The new multi-color platform drawing code takes longer to do its job, and using that routine for erasing the platforms made that take longer as well. I replaced the platform erasing code with a simpler loop, and this was enough to meet the drawing deadline.


So, there you have it -- multi-colored platforms are possible on the Apple II port of Fahrfall. There isn't much time left during the vertical blanking interval for any other drawing tasks, but right now what is needed are less time-sensitive measures -- like scoring! I don't think I'll be able to reach a totally finished game by the end of the month, but I hope to get a bit closer than I am now. If you are curious to see where I end-up, then you will just have to stay tuned!

Sunday, January 25, 2015

Fahrve Lives!

We are still barreling towards the end of Retrochallenge 2015/01, and the Apple II port of Fahrfall is still progressing nicely. We must be getting close, as the star of our show has finally started showing-up for dress rehearsals. Yes, ladies and gentleman, Fahrve now joins our party!

Low-Res Perspective

Representing Fahrve on the Apple II is a little tricky, at least when using the low-resolution video mode. The CoCo version of Fahrfall uses a video mode with a resolution of 64x96, while the Apple II low-resolution mode is 40x48. Obviously some scaling is required, but at such low resolutions scaling inevitably leads to distortions. Fahrve was already only slightly better than a "stick figure", and on the Apple II that is more true than ever. In particular, cutting the vertical resolution in half forced some compromises in the shoulder details and the thickness of the feet. The extra horizontal thickness of the blocks forced spreading the Fahrve graphics a bit wider as well, in order to get separation for the arms and legs.

A Tale Of Two Fahrves

Another quirk of the Apple II low-resolution mode required some consideration. The color of each pixel is encoded with 4-bits of data and two pixels are encoded in each byte, but the two pixels encoded are on different lines. This means that two pixels encoded in the same byte when plotting a figure on an even numbered line are suddenly encoded in different bytes when plotting the same figure on an odd numbered line!

This problem is not really any different from the problem of plotting a figure in a mode where multiple horizontal pixels are encoded in the same byte. One option is to use shift and rotate operations to transform a source image into a properly adjusted set of values in the video buffer. But that method is slow, and already awkward when dealing with horizontally encoded pixels. Using bit manipulations on vertically encoded pixels seems potentially even more awkward.

A better performing option is to use a different version of each sprite for each data alignment option. This increases the amount of memory required for sprite handling, but in this case we only require two versions of each sprite, one version for even-numbered lines and a second version for odd-numbered ones. Since I already have to keep track of Fahrve's vertical position anyway, choosing which sprite to display is reduced to a simple odd/even check on that number.

Sidestep: The Issue

When Fahrve moves from side to side, I depict him with one foot up and the other arm up as if he is shuffling to the side. The foot/arm up combination alternates between left/right and right/left as Fahrve continues to move on the platforms. Obviously, each of these sprites needs odd- and even-numbered line versions as well. That is four versions of Fahrve for horiztontal movment alone!

Along with the sideways-moving versions of Fahrve, there are odd and even versions of Fahrve standing still on the platform. There are also odd and even versions of Fahrve falling through the air with his feet pulled up and his hands above his head. Altogether there are eight versions of Fahrve for Fahrfall. For maximum performance, these are implemented directly in code rather than as bitmaps in data. In truth, this extra code nearly doubled the size of Fahrfall. Of course, that took it from slightly more than 1K of code to just under 2K... :-)


As you can see, the game is really coming together. I have to admit that despite the lack of scoring, I can now occupy a few enjoyable moments of my time playing with Fahrfall on the Apple II. Still, it doesn't really look a lot like a game just yet. If you want to see how that turns-out then you'll still have to stay tuned!

Friday, January 23, 2015

Make Some Noise

There is a bit more than a week to go in the RetroChallenge 2015/01 event, with just this weekend and the next remaining.  It is getting to be crunch time! :-)  Fahrfall is far from complete, but it is shaping-up fairly well...

Where Am I?

Fahrfall does screen updates during the vertical blanking interval. This provides for smooth, well timed, and glitch-free animation. Only the Apple IIe and later Apple II models provide hardware support for this sort of timing, but I don't think that is a major limitation. A bigger problem is that while the IIe, IIc, and IIgs all provide support for synchronizing to the vertical blanking interval, they each do so in a slightly different (and incompatible) manner. In order to run on all of these Apple II machines, Fahrfall needs to be able to figure out which kind of machine is running it and to adapt accordingly.

Fortunately, it is not too difficult to identify the host machine. In fact, a pertinent Apple Technical Note ("Apple II Family Identification") is readily available on the Internet. Executing a simple ROM routine quickly identifies whether or not a IIgs is in use. If not a IIgs, then a couple of additional memory accesses to known ROM locations quickly distinguish between the IIc, the IIe, and older machines as well. All that remains is to make use of this information.

A single bit within the IIe indicates whether or not vertical blanking is active, so the IIe code simply polls that bit. The bit value for active vertical blanking is reversed on the IIgs, so a complimentary routine is provided for use on the IIgs. On the IIc the vertical blanking indication is tied to an interrupt source, so the IIc routine instead checks for an active interrupt and clears the interrupt source before returning. An indirect jump through a pointer in memory is used to choose the appropriate vertical blank synchronization routine at runtime. This should be sufficient to enable Fahrfall to support all of the later members of the Apple II family.

The older II and II Plus are also detected during Fahrfall initialization. Lacking any support for vertical blank synchronization, detection of these early Apple II machines currently leads to an early exit from Fahrfall. When Fahrfall is more complete, I may experiment with a more static delay loop for use on these early machines.  It won't be perfect, but it might be better than not running at all? Alternatively, it looks like the mouse interface card might be able to provide the necessary timing (if one is installed). Are there enough II or II Plus machines (with or without mouse cards) to make the effort to support those machines worthwhile? I have no idea...

Read The Fine Manual

Most programming of Apple II hardware is done through some sort of "soft switch" access. These are memory-mapped hardware registers that change and/or reflect the state of various bits of hardware on the Apple II. Most "soft switches" are accessed in such a way that the change of state occurs based on the location accessed rather than whether that access is a read or a write. However, "most" and "all" are different things...

The vertical blanking interval detection routine for the Apple IIc enables generation of a vertical blanking interrupt, but disables interrupts at the CPU. The interrupt is detected by polling a "soft switch" until the vertical blanking interval is indicated. During setup, another set of "soft switch" locations is accessed to enable the generation of that interrupt. But when I first ran Fahrfall on a IIc, the program simply hung.

I speculated that my polling loop was checking for the wrong condition, so I changed it to look for a '0' rather than a '1'. That stopped Fahrfall from hanging, but now the game ran too fast as it always thought an interrupt was pending. Ultimately, I figured out that my attempt to enable vertical blanking interrupt generation with read operations was not working. Changing those to write operations made the interrupt detection work as expected. Sometimes it pays to read the manual carefully!

Hear Me Roar

One of my favorite bits of Fahrfall on the CoCo is the simple sound effect used to simulate footfalls during player movement on the platforms. This effect uses the square wave audio output on the CoCo, following a pattern triggered during the vertical blanking interval. The Apple II audio hardware is similar to the square wave audio hardware on the CoCo, so I implemented an equivalent audio pattern triggered during the vertical blanking period while the player is moving horizontally on a platform. The sound effect on the Apple II sounds virtually identical to the effect on the CoCo version of Fahrfall. Fahrve still looks like a big, blue box, but now you can hear him coming!


I guess that covers the state of things for now. Hopefully I can find some time this weekend to add scoring, or to give Fahrve some shape, or... Well, I guess you'll just have to stay tuned!

Tuesday, January 20, 2015

Game On

A few more days have passed in the RetroChallenge 2015/01 event, and there is a bit more progress to report!  Step by step, Fahrfall is coming together on my Apple II.  Soon I will have a real game... :-)


Collision Detection

The main point of Fahrfall is to fall down the screen, land on a platform, and ride the platform back up the screen before you repeat the process.  For that to happen, the program needs to know when the player is in contact with a platform.  That problem is known as collision detection.

Collision detection in Fahrfall is fairly simple.  Each platform is represented in the computer's memory by a bitmap, with a '1' representing each section of the platform and a '0' representing each gap.  A variable keeps track of the horizontal position of the player on the screen, and that value is used as an index into a table containing bitmaps that represent the platform sections with which the player might collide in that horizontal position.  When the player's vertical position is immediately above a platform, a simple bitwise AND operation between the two bitmaps is done.  A non-zero result represents a collision (i.e. the player is standing on a platform).

Hidden Platform

As indicated, the collision check is done between the player and the platform on the line beneath the player.  This presents a problem when the player is all the way at the bottom of the screen, since all three platforms will be above it.  Without some accommodation, the platform data array will underflow and problems will be inevitable.

There are many potential solutions.  There could be an explicit check for this situation, with the result being either to skip the collision check or to immediately end the game.  Alternatively, a fourth entry could be added to the platform data array.  The fourth entry could contain an all-zero bitmap (so that no collision would ever occur), or it could contain the data for the next platform.

The latter option is what I chose to do.  This may seem silly, since only three platforms are displayed on the screen.  But adding a fourth (off-screen) platform introduces an interesting gameplay feature.  If the next platform would catch them, a player can be saved at the last minute through sheer luck when falling off the bottom of the screen!  This only happens if the fourth platform is just about to emerge, but it still adds an element of fun for those who reallly enjoy Fahrfall.


Moving On Up

With collision detection all sorted, making the player ride the platforms is a simple matter.  When a collision is detected and the platforms move up, the player is moved up at the same time.  Similarly, if a collision is detected then the player does not move down.  To make this work properly, collision detection must be run whenever there is movement of either the player or the plaforms (i.e. sometimes twice in a frame).  Aside from that, making the player ride the platforms was just a simple matter of programming.

So the basic gameplay mechanics of Fahrfall are complete in this Apple II port of the game.  At this point you can "play" using the joystick, so long as you don't care about keeping score.  Nevertheless, there are still plenty of features and embellishments missing.  So there is still more to come...I hope you will stay tuned!

Sunday, January 18, 2015

Halftime for RC2015/01

We are now roughly half way through the Retrochallenge 2015/01 event!  I am still making progress, but I don't have a very cohesive topic for a blog post at the moment.  Since it has been a few days since the last update, I will just touch on a few random bits here and there...

Line By Line

In an earlier post, I mentioned that the video memory in the Apple II has a peculiar layout.  For example, the data for line six is offset in memory from the data for line seven by a different amount than the offset between the data for lines seven and eight.  This makes moving an object on the screen from line to line more complicated than simply adding or subtracting a fixed offset from the previous address.

Previously I wrote a routine that would convert a screen line number to a base address in video memory.  I have since rewritten that routine by replacing a shift-and-add multiplication with some bitwise operations, thereby improving its performance.  Nevertheless, the routine is long enough that I would like to limit how much it is used.

I was able to implement somewhat simpler routines for moving up or down one line at a time.  These routines combine simple offset adjustments with checks and adjustments for crossing 8-line boundaries.  The results are somewhat simpler than the direct calculation routine, with corresponding performance improvements.  A single-line offset is simple enough to be practical and common enough to be useful, especially for Fahrfall.


Point Break

The 6502 only has a handful of registers for use by the programmer, none of which are large enough to hold an actual address.  Addresses for data access can be embedded in the program code, but either that would limit a given function to accessing only predetermined memory locations or it would require the use of self-modifying code that rewrites the addresses whenever different memory locations are used -- ugh!

Fortunately, the 6502 does provide a couple of means for storing an address in memory and then using that address as the object of an indirect memory access.  Unfortunately, those options require storing the address somewhere within the 256-byte "zero page".  Those locations are in high demand, and the Apple II firmware pre-allocates most of that memory for its own use.  Fortunately I was able to find enough space to fill my immediate need for a drawing pointer.

When I only had platforms on the screen, I could get by with a single drawing pointer.  Even though there are three rows of platforms, their relative positions makes it easy to adjust the drawing pointer to point to each platform in turn.  Unfortunately, the player object needs its own drawing pointer value which is independent of the platform drawing pointer.  Of course, the player drawing pointer needs the same sorts of manipulations as the platform drawing pointer needs.

One option would be to use separate "zero page" locations for each pointer and to duplicate the pointer manipulation routines for the player object drawing pointer.  A better alternative is to use a single "zero page" location for the active drawing pointer and to save/restore this value to/from separate memory locations for different uses.  The second option effectively treats the "zero page" drawing pointer as a 16-bit register, providing me with the flexibility I need for what I want to do.


Ode To Joy

Fahrfall is an arcade-style game, so it makes sense to use a joystick to play the game.  The joysticks on the Apple II use an analog circuit based on an RC time delay.  The actual timing is done at the CPU by counting the number of cycles that are spent executing a tight loop while a capacitor is charged.  Coding such a loop seems simple enough, but doing so is unnecessary -- the Apple II firmware already contains such a function at a well-known location.

Reviewing the actual code of the firmware's joystick reading function reveals that there is little opportunity for improving its performance.  Consequently, I used the Apple II firmware to read the Y-axis of the joystick.  This returns an 8-bit number which represents the position of the joystick on that axis.  Fahrfall only needs to know the general direction for movement, not the actual position.  So, I added code to take the number representing the joystick position and to test it for left and right ranges.  I also included a dead zone in the middle to represent "no movement".

Well, that covers a few micro-topics related to my port of Fahrfall to the Apple II.  I also finished reading Assembly Lines: The Complete Book, so I guess I am now a trained Apple II programmer...

Things are coming together, but there is still more to come.  I hope you will stay tuned!

Tuesday, January 13, 2015

Trivial Triumph

Today I did something clever on the Apple II.  I applied some recently acquired knowledge to address a gap in the random number generation for my Fahrfall port, and I was proud of it.  Unfortunately, I may have solved a problem that didn't exist...

Standing Start

Previously I discussed the use of a software-based linear feedback shift register (LFSR) for generating pseudo-random number sequences.  The LFSR is really just an equation that generates a sequence of numbers, each based upon the value of the previous number in the sequence.  Given a fixed starting point, the LFSR will always generate the exact same number sequence.  Consequently it is important to "seed" the LFSR so that it starts at an unpredictable point in its sequence.  A common technique for seeding an LFSR would be to use a rapidly changing variable (such as a time-based counter) to seed the LFSR.  Since the Apple II lacks any timing source, I looked for other options.

Clever Display

After a while, I recalled learning about a quirk of the Apple II hardware that allows a program to read the byte of video data currently being displayed on the screen by reading from one of the "soft switches".  Others have used this mechanism to synchronize a program for the proper timing of video updates by writing appropriate "sentinel" data to the video buffer.  That method of synchronization relies on precise cycle counting and seems unsuitable for a game or other interactive program.  But maybe the mechanism it uses could be pressed into service here?

It is very difficult for a human to know what portion of the video buffer is being displayed at any given moment, so reading the displayed video data during program setup should yield the data from a more-or-less random position in the video buffer.  Of course, the video buffer will often contain largely uniform values (e.g. spaces on the text screen).  For best results, steps should be taken to minimize the duplication of data values within the video buffer.  Consequently, I wrote an ordered sequence of values to the video buffer.  During program initialization I read from a video "soft switch" to retrieve values to use for seeding the LFSR.  This yielded satisfactorily random sequences across multiple program starts.

Reality Bites

With my LFSR getting a reasonable seed value, I was feeling rather pleased with myself.  After just a couple of weeks of playing with the Apple II, I may have just invented a new technique for generating a random number seed!  Even if it turns out that others have done this before me, I still discovered this all on my own!  Nevertheless, I wondered if I could find any evidence of someone else doing something like this?

For what its worth, I did not find any documentation of anyone using this technique for generating a random number seed on an Apple II.  That doesn't mean that no one has ever done it, and it doesn't even mean that no one ever wrote it down.  It only means that I didn't find any evidence of that in a few minutes with Google -- YMMV!

However, in my search of Apple II random number generation techniques I did find another interesting tidbit.  Apparently the firmware on the Apple II updates a loop counter in the zero page (at locations $4e and $4f) every time the keyboard is checked for input.  While the value of this number might be predictable if a program is automatically started after boot (perhaps when using an emulator?), in the real world this method is just as good and it is a lot easier to use.

So, I guess I'll just seed the LFSR the easy way -- at least I got to feel smart for a little while!  This is the sort of stuff that makes the Retrochallenge lots of fun, so I wanted to post this update for everyone's enjoyment.  There will still be more to come, so I hope everyone will stay tuned!

Sunday, January 11, 2015

Any Port In A Storm

Well, I guess by now the jig is up...  Having so far demonstrated a lack of imagination in the Retrochallenge 2015/01 event, I am falling back to something familiar.  I am porting Fahrfall as an exercise in learning to program the Apple II.  At least that lets me concentrate on learning Apple II software architecture and 6502 assembly language rather than toying with game design...?


Random Patterns

Almost any game needs a source of random numbers.  The most obvious use of random numbers in Fahrfall is the generation of randomized platforms, but they are also used in the "game over" audio and for a few behind the scenes functions.  Of course, computers really have no way to pick truly random numbers, so some technique must be used to generate "pseudo random" number sequences that are not easily predictable by humans.

There are several techniques available for generating "pseudo random" numbers.  The one that I tend to use is a software implementation of a linear feedback shift register (LFSR).  In the CoCo version of Fahrfall, I implemented a "Fibonacci" LFSR.  This time I implemented a "Galois" LFSR because it seemed a bit easier for the 6502 to process.  The code is so simple and fast, I may go back and reimplement a "Galois" LFSR for the CoCo version of Fahrfall as well!

Step By Step

I am using the low resolution graphics mode on the Apple II.  This mode provides a broad array of colors while minimizing the amount of data required to paint a screen.  The resolution is lower than the video mode used on the CoCo version of Fahrfall, but I think it is adequate to provide enjoyable gameplay.

The encoding of pixel data in the low resolution mode is a bit easier to wrap one's mind around than the encoding used for the other Apple II video modes, but it is still a bit odd.  Sixteen colors are available and two pixels are encoded in a single byte -- so far, so good.  What is weird is that the two pixels represented by a single byte are stacked vertically rather than horizontally, so the two pixels in a byte represent parts of different lines.  Weirder still (at least to me), the most significant nibble of the byte represents the lower line.

In any case, this pairing of pixel data caused me to implement my earlier "moving platforms" code experiment using 24 line pairs rather than 48 separate lines.  This code structure seemed a bit awkward, since I will likely want to process player inputs and do other things in between platform movements without having to duplicate code for odd and even platform locations.  So, I refactored the code to handle 48 different platform positions and to plot the platforms with properly encoded pixel data.

Refactoring

Continuing along the same path, I did more refactoring of the remaining bits of my code.  That code was developed organically as I initially toyed with the Apple II.  Now that the code is going to be a game, it needs to adopt a structure conducive to that end.  That means moving various bits of inline code into reusable subroutines, minimizing and/or removing duplicate code segments, changing labels here and there, etc.  This also includes beating the overall structure of the code into a traditional game loop.  As it now stands, the code forms a skeleton upon which I can hang the rest of Fahrfall.

Now that I've confirmed that I am working on a port of Fahrfall, it might make sense to move further coverage of this effort to the Fahrfall blog.  I considered doing that, but that might be a bit confusing for folks following the Retrochallenge contest.  I'll just keep the cover here for now.  If the effort is a success, then I'll move further coverage to the Fahrfall blog later.  So if you want to watch the progress of porting Fahrfall to the Apple II, then you just have to stay tuned!

Wednesday, January 7, 2015

Taking Shape

I'm still plodding along with the Apple II, and getting more comfortable with programming the 6502.  So far, I am having some good fun!  I'm still not committed to any specific programming goal, but an idea is starting to take shape...

Fill In The Blank 

Old-fashioned video monitors (including televisions) literally drew images one line at a time, sweeping across and down the screen in the process.  Image data in a computer generally is stored in RAM, and the contents of that memory is scanned by the video hardware as the video signal is generated and sent to the monitor.  Computer programs that do not account for the timing of those scans while updating image data in memory tend to generate transient video "glitches" when a screen in shown on the monitor while that screen is being updated.  A common technique for avoiding such glitches is to ensure that image data is updated during the vertical blanking interval.  This is a period in the video signal which is literally reserved for the time it takes to move the electron beams in a CRT from one corner of the screen to the other.  During this period, nothing is drawn on the screen.  This is an ideal time for updating image data in memory.

The original Apple II and Apple II+ hardware did not provide any mechanism intended for software to synchronize with the vertical blanking interval, but the later Apple II models were more accommodating.  Unfortunately, dealing with vertical blank synchronization seems to have been a creative outlet for the engineers at Apple back in the day -- the IIe, IIgs, and IIc all do it differently!  I even found a Google Groups discussion about the topic.  For now I am just going to use the method for the machine I am actually using in my coding experiments, the IIe.  Something more robust can come later, if necessary.

Oversize Load

The early coding examples in Assembly Lines: The Complete Book place code into memory starting at address 768, an open area of memory not used either by Applesoft BASIC or by the system monitor.  However, that unused chunk of memory is not unlimited.  As I added code in my own experiments, the size of that code crept slowly up.  At one point, the program would immediately crash when it was run from the monitor -- not cool.  Of course, the tail end of my code was overwriting something important to the proper functioning of the monitor program.  So the lesson is "know where your code lives"... :-)

Serial Killer

As I mentioned in an earlier post, my development environment includes a serial (i.e. RS-232 over Bluetooth) link between the Apple II and my workstation across the room.  This provides me with a number of conveniences, but it has the drawback that I can't touch the Apple II when I'm running code on it.  The only way to interact with a program (including telling it to stop) is over the serial port, which means my code experiments need to know how to talk to the serial port.  So, I figured-out how the 6551 on the Super Serial Card is addressed and I wrote some code to let me poll the serial port for input -- remote access problem solved.


Well, that wraps up this progress report.  I am having fun, and I am expanding my retro computing horizons.  There is still more to come, so I really hope you will stay tuned!

Sunday, January 4, 2015

Apple On The Bench

So, my annual goofing-off and retrocomputing bacchanalia is coming to an end.  Tomorrow I will have to reacquaint myself with the dayjob and starting being a lot more responsive to email and such.  But before I get buried by my email, I thought it would be worthwhile to post another update on my Retrochallenge progress so far...

Toying With Graphics

Using a monitor program makes experimenting with hardware really easy.  Manipulating memory or flipping bits in hardware registers is nearly trivial, making it very easy to fiddle with what the system offers.  I took advantage of this to experiment with the graphics modes on my Apple II.  I used the monitor program to experiment with setting different colors on the screen, to change between the text and graphics modes, etc.  This is a great way to get a feel for how things work.

During my experiments, I was reminded of the peculiar way that screen memory is arranged on the Apple II.  One might expect that the data for the first pixel on the second line of the display would immediately follow the data for the last pixel on the first line, but on the Apple II that is not the case at all.  This is a by-product of a simplification in the Apple II hardware design, but it certainly complicates things when writing software to plot graphics to specific lines on the screen.  If you have ever noticed the "window blinds" effect when loading a graphic on an Apple II screen, you are observing what it looks like to write to the Apple II screen when accessing memory locations in a straight linear fashion.

Clearing Lines In On-Screen Order
As a coding experiment, I wrote something to blank-out parts of the screen in the order of lines as they appear on the screen rather than how they are stored in memory.  The algorithm for this wasn't too tricky, but it did require a bit of code to do some bit manipulations and to simulate what are essentially a pair of multiplications.  Even after some optimization, the code to calculate the base address of a line, to write the data for that line, and to loop through the requested lines took almost 100 bytes!  In a game, this sort of thing may merit a look-up table for finding line base addresses in the video buffer...

Unobstructed View

As I mentioned in an earlier post, I am redirecting the Apple II console through the serial port so that I can drive the Apple II from my development machine.  This works fine, but by default the output continues to be sent to the screen too.  That is fine when I'm only accessing the monitor program, but it is a problem at least for low resolution graphics mode since the text and graphics screens share the same memory -- typing commands messes-up the low-res graphics screen!  What to do?

There might be a way to convince the Apple II to stop sending output from the monitor program to the screen, but right now I don't know how to do that.  Fortunately, the Apple II actually maintains two separate screen buffers and the monitor program only modifies one of them.  Which buffer gets used for graphics output is determined by a set of registers in the Apple II that are called "soft switches".  By using the right "soft switch" to change the graphics to use the other screen buffer allowed me to do graphics experiments from the monitor program without messing-up the graphics on the screen.

Reading Log

I am still working on Assembly Lines: The Complete Book.  I have completed reading volume 1 and the original appendices, which should be equivalent to reading Assembly Lines: The Book (i.e. the original version).  So as a 6502 programmer, I am now as qualified as a young John Romero!  At least, that is how I interpret his quotation from the back cover... :-)

But seriously, there is plenty more to read.  With that said, I am feeling a bit more qualified to code for the 6502.  Plus, I am learning a bit about Apple II architecture and such -- I found some interesting stuff online about timing code to the vertical blank interval on the Apple IIe, IIc, and IIgs (all done differently).  I'm still not sure what coding project I will do, but some options are coming into focus.  If you want to read more about it then I hope you will stay tuned!