Yellowstone Option Configuration Design
The Yellowstone disk controller’s whole reason for existence is its ability to control any type of Apple II disk drive, but for a few Apple II programs, this universality causes problems. Yellowstone handles standard 5.25 inch drives just fine, but some software gets confused when it doesn’t find the ROM for a standard Disk II Interface Card in slot 6. For these rare cases, Yellowstone has an option to enable a “compatibility mode” where it emulates a plain vanilla Disk II Interface Card without any extra bells and whistles. The question is how does the user enable compatibility mode?
In the current version of the Yellowstone prototype, the choice is determined by a DIP switch. But as I’ve been refining the design, I’ve developed a strong dislike of DIP switches. They’re big and awkward, and not at all user-friendly. I’ve already managed to find ways to eliminate two of the four DIP switches on the board, and if I can find another solution for enabling compatibility mode then I can eliminate a third DIP switch.
My first thought was to check the keyboard immediately after the computer is powered-on, before loading anything from the disk. If the ‘C’ key is held down (c for compatibility), I could enable compatibility mode, otherwise I could proceed normally. On the Apple II it’s easy to check for keypresses by examining memory address $C000. If there’s a keypress waiting, the MSB will be 1 and the lower seven bits will hold the ASCII value of the key. So I could check for the value $C3 ($80 plus $43) and everything would be peachy.
Unfortunately, I quickly discovered that one of the first things the Apple II ROM does after a reset is to clear the keyboard buffer. This happens before control is transferred to Yellowstone’s ROM, so by the time my code checks the keyboard buffer, it’s too late. What to do?
Rely on the Buffer’s Lower Bits
From testing on my Apple IIe, the keyboard buffer isn’t actually zeroed when it’s “cleared”. The MSB is set to 0, but the other seven bits still retain the ASCII value of the key. So perhaps my code could just check $C000 for $43 instead of $C3 to detect the ‘C’ key, and it would work as originally intended.
This seems slightly dubious, since I’m not sure if this is documented behavior, or if other models of Apple II will clear the keyboard buffer in the same way. There’s also a small bug this introduces: if ‘C’ was the last key typed, and you then turn off the computer and turn it on again within 1-2 seconds, $C000 will still hold the value $43 during power-up. This may lead to accidentally detecting non-existent keypresses and enabling compatibility mode when the user didn’t intend to.
Delay Booting and Poll the Buffer
Another option is for Yellowstone to sit in a busy loop after the computer is first powered-on, and continuously poll the keyboard buffer looking for the value $C3. If the keyboard has a key repeat behavior, then $C3 will appear in the buffer after roughly 0.75 seconds if the ‘C’ key is continuously held down. Or the user could be instructed to quickly tap-tap-tap the ‘C’ key when the computer is powered-on, instead of holding it continuously down. This would eliminate any dependency on the keyboard’s key repeat behavior. At least one modern Apple II peripheral card uses this method.
The main drawback of this approach is that it would introduce a busy-waiting delay every time the computer is turned on. To reliably detect a key repeat or a tap-tap-tap, Yellowstone would need to insert a startup delay of about one second, every time the computer powers-on or resets. It sounds like a small thing, but I think I’d find this delay very annoying. Furthermore, the key repeat behavior might not work on the original Apple II or Apple II+ keyboard, so tap-tap-tap is probably the only reliable solution.
Check the Open Apple Key
A third alternative is to check whether the Open Apple key is held down, instead of the ‘C’ key or any other standard key. The behavior of the Open Apple key is very different from the other keys. Open Apple is just a duplicate of the first button on the first game controller, and its current status can be read at memory address $C061. As long as Open Apple is held down, the MSB of $C061 will be 1.
The Closed Apple key works identically, and its state can be read at address $C062. But holding the Closed Apple key during power-up will trigger the Apple II’s built-in diagnostics, so that key isn’t a good candidate for triggering Yellowstone behavior changes.
For now I’ve implemented Yellowstone’s compatibility mode enable using the Open Apple key, and it works well on my Apple IIe. Unfortunately, earlier models of Apple II computers don’t have an Open Apple or Closed Apple key. Users with those computers would need to attach a game controller and press its button during power-on, which is far from ideal. There’s also a risk that some other third-party peripheral cards might use Open Apple in the same way, which would make it impossible to trigger Yellowstone’s compatibility mode without also affecting the other card. But I don’t know of any specific cards that use Open Apple, so maybe I shouldn’t be concerned.
Something Else
I could stick with the DIP switch, despite its awkwardness. Or I could ask users to perform some voodoo in the Apple II monitor, and write a magic value to a special address in the card’s memory to enable compatibility mode. Or some other solution I haven’t thought of yet. Opinions?
Read 27 comments and join the conversation27 Comments so far
Leave a reply. For customer support issues, please use the Customer Support link instead of writing comments.
Not being a hardware guy, that is lazy to open the hood – pull the card – flip the DIP, I would rather see the magic number in the monitor, AND your best shot at one of the key presses you stated as the solution.
IIRC, the CFFA 3000 uses the “M” key being pressed, and it has worked for me…. mostly, because I also have the FASTCHIP and the VidHD which requires some voodoo (pressing and holding CTRL-RESET to allow VidHD to warm-up properly).
Do you know if CFFA 3000 asks you to hold M while powering-on, or if you power-on and then quickly press M?
I think I’m going to use “Rely on the Buffer’s Lower Bits”, holding down Control-D while powering-on or resetting to enable Disk II mode. It turns out the retention of the lower buffer bits *is* documented behavior, all the way back to the original Apple II. Thanks Woz! And the accidental detection of non-existent keypresses can be avoided on the Apple IIe and later by checking the Any Key Down flag. The Apple II+ and earlier don’t have that flag, so there’s still a remote chance of phantom keypresses there. But Yellowstone will probably be of little interest to Apple II+ users anyway. If necessary, the ROM code can detect the specific computer model and use a different behavior if it’s an Apple II+ or an original vanilla Apple II.
From the CFFA 3000 manual on installation and startup steps:
6. For Apple IIgs or Enhanced IIe: Turn on your Apple II and quickly press the ‘M’ key to enter the CFFA3000 menus. Go to step 8.
7. For older Apple II, II+, IIe computers you will have to turn on computer and enter PR# . Example: PR#7. Then press the ‘M’ key to enter the CFFA3000 menus. To get these Apple IIs to boot automatically, go to “Other Settings” menu and change “Autoboot Older Apples” to “Yes”.
Step 8 just mentions how to select an emulation slot once in the CFFA 3000 menu.
I’ve used my CFFA 3000 in both a II+ and IIgs and can confirm that’s how it works in those systems.
I had a super-advanced multi-drive controller in the past that supported all the 5.25 and 3.5 drive types that had this behavior built in (a fallback “pure” Disk II controller mode that disabled/bypassed all of the advanced features). It was *incredibly* simple to use/activate: it was invoked by way of an “IN#x”, where x was the slot the controller was in, in place of using a “PR#x”.
This made it not require any interception of anything including key or button presses at boot, no requirement for any loaded software (IN# and PR# are available in the built-in Applesoft ROM), no physical DIP switches, and it was available to the user no matter what the state of the machine was. Even if you’d been left crashed to the monitor, 6 (the monitor’s equivalent of “IN#6”) did exactly the same thing. It was simple, intuitive, and amazing.
The comment software stripped part of my comment. There was supposed to be a “control-i” after the “6” there in the part about the monitor. From the * monitor prompt, “6 control-p enter” was the same as PR#6 and “6 control-i enter” was the same as IN#6. And a “6 control-i enter” from the monitor would work to activate the controller in question’s “fallback” mode.
My recollection is that IN#x simply jumps to a specific address in the ROM of slot x. But this is one of those topics that’s literally impossible to Google because Google ignores the # character and “in” is a rather common word. 🙂
I could definitely see including IN#x as a fallback, but since it relies on having already tried and failed to boot a disk, it doesn’t seem as friendly of a solution as holding a key to enable pure Disk II mode.
From what I could tell of the design of the controller I’m referring to (it’s the OKS MultiCache if you’re wondering), the expectation was that any software that *required* such a legacy/fallback mode of the controller was going to need to be booting directly from the Disk II, and you were probably going to be manually invoking a “PR#6” to do that anyway. The ROM on the controller was able to differentiate between an IN#6 and a PR#6, and an IN#6 would kill all the advanced features before such a boot. The cool part was that if it was in that “fallback” mode, and you invoked a “PR#6”, it would re-activate all the advanced features and boot from whichever attached drive was appropriate. You didn’t even have to power-cycle the machine.
As far as keypresses – if a hypothetical Yellowstone is in Slot 6, and your Apple is set to boot from, say Slot 7 using a SCSI card or MicroDrive/Turbo, or some other large-capacity storage, the ROM on the Yellowstone isn’t going to get a chance to intercept such a keypress anyway, is it? You’re going to have to type “PR#6” to invoke the YS’s ROM and then press a key, aren’t you?
Yes if you’re booting from a card in Slot 7, then Yellowstone in slot 6 wouldn’t get a chance to intercept a keypress. But if you’re not booting from Yellowstone, then there’s also no need to reconfigure it for Disk II mode – at least not that I can think of. Anyway, I agree having some kind of fallback that’s available from BASIC or the monitor would be helpful.
It looks like both PR#x and IN#x will vector to address $Cx00, so it’s not clear how the ROM code at that address should know whether it’s intended to do output or input. Maybe one of the 6502 status flags is used? Or maybe it examines the CSW and KSW vectors in RAM?
I would also submit that the use of the OpenApple is a poor choice. OA-ctrl-reset is the standard way to “warm restart” an Apple //e or IIgs, and the normal method of doing that requires releasing the OA key well after the system has reset, at least in computer time.
This has the potential to put the YS into the “fallback” mode pretty much constantly, and the “fallback” mode is presumably the exception, not the rule?
Back to the PR#/IN# – yes, both will cause the ROM of the device in the designated slot to get invoked at $Cx00 the next time character output or input occurs, respectively. Presumably the ROM of the OKS controller examined the vectors you mention (or possibly examined the stack? Not really sure) But it was somehow able to tell the two invocations apart and adjust its behavior as a result.
And I guess the important question that I didn’t see asked or answered (and I maybe missed it?) was whether a fallback Disk II compatibility mode was expected to be a _persistent_ toggle or a _transient_ toggle.
Do you expect the YS to go back to being an advanced/smart/uber-controller all on its own if it’s power cycled, or reset, or …? Or is the Disk II compatibility mode expected to persist even across power cycling until the end user of the computer *explicitly* toggles it back into super-advanced mode?
It’s a transient option for a rare case (I’ve only found two programs that need it), and it’s cleared whenever the computer is reset or power cycled.
IN#x redirects the Apple’s character input routine to point to Cx07 in the card’s ROM so that at the next input, the Apple will call that address instead of the normal keyboard input routine.
Never mind what I just wrote. It’s definitely going to Cx00 but it’s common for a lot of ROMS to point the input vector to Cx07.
Ok, how about this:
You don’t like the idea of having to wait for a keypress on every boot cycle (the delay, the polling, the potential for errors, etc) and I agree. There are controllers that do this (like the BOOTi) and it’s not perfect.
I don’t like the idea of the OA causing an immediate change in behavior. I think that’s a recipe for frustration, especially for people that DON’T have a bootable device in a higher slot. OA-ctrl-reset is going to have those people in “fallback” mode constantly when they didn’t want it.
So maybe neither of those options is the best choice. Is there a third?
Let’s take a lesson from the MicroDrive/Turbo. It’s the second-best implementation of a transient behavior toggle I’ve seen (I still like the PR#/IN# the best, but I digress).
If an MD/T’s ROM is invoked at $Cx00 for whatever slot it’s in, AND the OA key is not pressed, the MD/T *immediately* boots from the configured boot device. It doesn’t wait for anything, there’s no delay, there’s no toggles. Instantaneous boot. HOWEVER…
If an MD/T’s ROM is invoked at $Cx00 and the OA key IS pressed, it does something different. But what it does isn’t immediate. It goes into a “holding” state, and outputs a short message, telling you that you can press a number to boot an alternate device.
If you RELEASE the OA at this point, without doing anything else, the MD/T immediately proceeds with the normal boot from the default device – exactly the same as if you’d never touched the OA to begin with.
But if you KEEP HOLDING DOWN the OA, and press a number from 1-9, it IMMEDIATELY boots from that boot device as if it were the configured one.
Besides the CFFA3000, the RamFAST SCSI supports holding down numbers 1 to 7 to select a different boot partition on a drive and “0” boots to the onboard setup tool. The boot ROM likely has code to scan the keyboard right at execution. Technically this is the “proper” way to handle this situation, but that requires modifying ROM code.
Proposal:
If you don’t hold down the OA key, the YS boots up perfectly normally, immediately, with no delays and no checks of anything else.
If you HOLD DOWN the OA key, the YS HALTS and outputs a small message on the screen saying:
“Release OA to boot normally.
Press 2 for Disk II controller compatibility mode.”
If you release OA at that point, the YS immediately proceeds to boot in the normal, uber-smart advanced mode and it’s the same as if you never touched OA.
If you KEEP HOLDING the OA and press “2” on the keyboard, the YS immediately drops into Disk II compatibility mode and starts a boot in that mode.
Feasible? Reasonable?
James, you might have missed my comment above where I mentioned that I’d switched away from Open Apple for the same reasons you mentioned.
I don’t think the Apple II monitor input remapping routine works as described. It looks like it should be Control-K (for keyboard) rather than Control-I, but even still I can’t get “6 Control-K Return” to do anything from within the Apple II monitor. It just prints another * prompt when I try it. But “6 Control-P Return” reboots from slot 6 as expected. I must be doing something wrong.
Mystery solved: it appears that the monitor’s Control-K command doesn’t work if you’ve booted from a DOS3.3 or ProDOS disk, it only works if you boot without a disk. With DOS or ProDOS, I think the monitor is changing KSW but then DOS/ProDOS immediately changes it back. Unfortunately that probably rules out the idea of using this as a way of enabling Yellowstone’s Disk II mode. James are you sure that the OKS card will disable its special features if you boot DOS3.3 and then do “6 Control-K Return” from the monitor? Or does it only work with IN#6?
Sorry, it’s been too long since the OKS was working and available – you’re right, the monitor command for the input hook is “N ctrl-K”, not “N ctrl-I”. And while I do recall being able to use the monitor’s hook to activate the OKS’s fallback/bypass mode, I can’t say I recall specifically doing so *after* booting DOS3.3 or ProDOS. And at this point, I no longer have a away to check.
And was the counter-proposal above about having the OA button/key enable a mode where a keypress could then be used to “confirm” or “choose” Disk II compatibility rather than activate it immediately and explicitly on JUST OA not an acceptable trade-off?
I take no credit for that idea, I just figured I’d bring attention to it, having used it via the MD/T’s implementation. It feels like it eliminates the shortcomings of the explicit OA-activation without being too additionally invasive.
“James N”, as Steve as mentioned, remember that there is no Open Apple on the II and II+. As for any repeat key remember that the II/II+ the repeat key needs to be held down. The MDT does notice the joystick button pressed so that is still an option (but MDT on the II/II+ requires the AppleSoft boot ROM fix in order to boot from it.) I have a booti as well and I do not mind the key press option. In fact, I like the ability to put up a menu on startup that can be expanded in the future if needed. I also think that the IN and PR are an option but require fancy entry point logic and switching and not sure how much space you have for code.
Yeah it’s all a bit more complicated than I’d realized, since there are different Apple II models to worry about, and at least four different ways of booting the computer (power-on, Ctrl-OpenApple-Reset, PR#6/IN#6, Ctrl-P/Ctrl-K).
The proposed scheme with Open Apple and a second keypress sounds like it could work in most cases, except for the Apple II and II+, which lack that key. I’d probably prefer something simpler though. I need to think more about it. A card that needs a menu of several options might want a different solution than a card that only needs a single enable for a special rare feature.
For the time being I’ve settled on Ctrl-D: if this key combination is held down during power-on or reset, you’ll get Disk II behavior. There’s nothing magic about the choice of Ctrl-D, except that it’s possible to do in combination with reset (Ctrl-OpenApple-D-Reset), and it’s a two key combo to reduce the chances of a collision with a key used by some other Apple II card.
At first I didn’t think about PR#6/IN#6 and Ctrl-P/Ctrl-K. There’s no way to hold Ctrl-D while typing those other commands, and since there’s intentionally no boot delay, it doesn’t work to type PR#6 and then quickly hit Ctrl-D afterwards. James’ suggestion of IN#6 seems like a helpful fallback for these cases. I’ve actually implemented the IN#6 behavior, and it works. But since the parallel Ctrl-K behavior doesn’t also work under DOS, I’m a little reluctant to rely on this. It also feels slightly confusing to have two different methods of enabling Disk II mode, one relying on keypresses and another relying on PR/IN.
Using PR#6 or Ctrl-P to exit Disk II mode and return to normal Yellowstone mode would be tricky. When in Disk II mode, the card’s ROM is replaced with the standard Disk II controller card ROM, so there’s no place for special code that could detect CSW/KSW and switch the ROM back. Maybe there is some clever work-around.
I’ve discovered some other tricky corner cases. My intention was for the card’s behavior to automatically switch back to normal Yellowstone mode whenever you reboot/reset, unless you hold the magic key(s). Whenever the FPGA sees the /RESET signal asserted, it switches the ROM to the normal Yellowstone ROM. But when you do PR#6, it reboots the computer without ever asserting /RESET, and the ROM doesn’t get switched. That doesn’t seem desirable. Another problem is if you press Ctrl-Reset (without also holding OpenApple), the computer asserts /RESET and the FPGA switches the ROM, even though the computer wasn’t restarted. That’s definitely not desirable and it will probably break ProDOS if you boot in Disk II mode and then press Ctrl-Reset and the ROM magically changes out from underneath ProDOS. All of this suggests that /RESET triggering may not be the right way to handle switching the ROM.
Perhaps Disk II mode should be a semi-sticky toggle: once enabled, it could stay enabled across reboots and resets until it’s explicitly disabled or the power is turned off. That might avoid some of this weirdness, though it would create other weirdness. FYI there’s no easy way to make Disk II mode persist across power off/on, even if I wanted to, because Yellowstone doesn’t have any non-volatile storage for saving settings except for the FPGA itself.
So many things to consider for such a simple-seeming feature! As usual I’m probably overthinking it. It’s important to remember that this will be a rarely-used feature only needed for a few troublesome programs, so it’s probably OK if it’s not perfect or doesn’t handle every case. My main goals are to provide at least one clear way of enabling Disk II mode, and also make it obvious when it’s enabled, so you’ll know you’ve done it correctly and will also know if you do it accidentally. Everything else beyond that is “would be nice” territory.
On the Apple //e and later machines, there is a location that can be polled to determine whether a key is presently held. That won’t work on the Apple ][ and Apple ][+, however.
Otherwise, how about having the unit start out with a “standard” Disk II ROM banked in at $Cs00, but watch for consecutive accesses to addresses $Cs00 and $Cs01. If those are observed, switch to an enhanced ROM mode until the enhanced boot loader does something to switch back to normal mode before running code.
If a program attempts to jmp directly or indirectly to $Cs00, it will run the enhanced boot loader. But if a program tries to inspect ROM at $Cs00, it will see the old one.
Did you see my suggestion about auto-switching based upon consecutive accesses? The only ways the 6502 will perform consecutive accesses to $Cs00 and $Cs01 would be if it is executing code at that address, or if code performs a (nonsensical) JMP ($Cs00). Thus, it would be fairly simple to have a state machine which could run arbitrary code when executed by jumping to $Cs00, but would otherwise make the card appear as though its ROM contents match those of a Disk II controller. This approach would make it easy for a card to distinguish between actions which should reboot versus actions which perform a reset but should leave the card in whatever mode it’s in.
When using the card in the “newer” mode, what is the minimum time required to read a boot sector? For cases where the card is set to emulate an older controller, but the user might want to switch to newer mode, it would be possible to check for a keystroke between the track-0 head seek and the attempt to read the sector; I would think something similar might be practical to allow switching from new mode to old mode.
Sorry, I wasn’t certain what problem was meant to be solved by the “consecutive accesses to $Cs00 and $Cs01” suggestion. Executing code at those locations would switch the card from Disk II mode back to normal Yellowstone mode? That might work. I’ve moved on from this question for the moment, but I need to circle back again later and think harder about all the reboot/reset avenues and what the user would probably expect to happen in each case.
I don’t think it would be practical to check/change between Disk II and normal mode after seeking, for several reasons. I’d prefer to make the determination at the very beginning during the boot process, before the card even begins talking to any disk drives.
It sounded like you wanted a way to distinguish between situations where the system was being rebooted (which might or might not involve a reset), from situations where the user might push the reset button without rebooting the system. Consecutive accesses to $Cs00 and $Cs01 would indicate that the system is being rebooted.
I don’t know how SmartPort booting process works, but if when booting a disk while emulating a Disk II, there would be no particular need to start out running the same code as would seem to be in the Disk II ROM. One could easily, for example, start with a ROM banked in that would perform a seek on drive 1, check for a keystroke, and if none is seen look to see if a disk seemed to be present, and then either bank in the normal ROM and jump there to load the boot track, or else select drive 2, perform a seek, try to boot that, and if that fails shut down the drive motor, show an error message, and await a keystroke.
BTW, is there any boot disk image or other means that could be used to allow a Floppy Emu to behave as a hard drive when used with an original-ROM Apple IIC?