BigEd wrote:
BigDumbDinosaur wrote:
Note the comment about invalid addresses.
But we don't have to be frightened. The behaviour of the machine is predictable and even specified. What you had was two back-to-back accesses which your peripheral couldn't deal with. Knowing that, you had several options:
- change the logic to avoid accessing on the dead cycle
- change the clocking so the back-to-back accesses were not a problem
- index from the previous page so the unwanted access does not select the peripheral
- avoid indexed accesses to sensitive periperals
I used number 1: change the logic. It proved to be trivial—
cut a couple of chip legs and add a few pieces of wire. This arrangement guarantees that I/O device selection will only occur when the '816 is actually emitting a valid address. On my next design I will extend this feature to RAM access as well.
What was interesting was that while the DUART was clearly unhappy with the address bus diddling that was going on during the intermediate cycles of the STA $ABS,X operation, the watchdog apparently wasn't in the least perturbed. Be that as it may, my patch affects the 74AC138 decoder, which assures that neither watchdog or DUART will be selected until A0-A15 are stable.
Quote:
For future adventurers, it's useful to know that these choices are available. Sometimes the software fix will be preferable, sometimes the hardware fix.
While VPA and VDA can be very useful especially in a sophisticated system, I'm anxious that the beginner can have confidence in making a simple system without worrying about them.
Qualifying access with VDA and VPA is not at all complicated. The logic equation is simple:
Code:
valid_data_memory = VDA & !VPA
Here's how I did it in my design.
A more generalized approach could be used that affects the entire system, but I/O hardware is where I'd think most of the trouble would appear.
Monkeying with the clocking would actually be more complicated—more silicon would be needed, and would exact a performance penalty, not to mention possibly raising issues with hardware timers driven by Ø2. Also, any software workaround, e.g., indexing from the previous page, would make for possibly obtuse code. STA DEVICE,X makes more sense to the casual reader than STA DEVICE-1,X with .X adjusted to deal with the address shift. Also, that approach wouldn't be practical with software that accesses I/O hardware via STA ($ZP,X).
As for avoiding device access with STA $ABS,X, that would be okay if only a few registers needed to be set up or if the device had only one channel. If more than a few registers have to be configured, however, the resulting linear code would be wasteful and harder to maintain. It gets even more onerous if the device has multiple channels. For example, the NXP 2682B octal ACIA has four times as many registers to configure as the DUART I'm using in my design. Done in linear code, it would stretch for several pages and would be a nightmare to organize. Organizing the registers and associated parameters into data tables makes more sense but requires the use of some kind of indexing to select the correct device registers.
My opinion is, since WDC provides the VDA and VPA outputs to tell the system when the MPU is ready to access hardware, those outputs should be used.