GARTHWILSON wrote:
I suppose if you had corrupted non-I/O pointers and you hoped that in their corrupted state they pointed to an unused place in the memory map so you can keep going (if that's possible), then it might make sense. I think usually a corrupted pointer will be accompanied by other problems anyway, and will mean it's time to re-start the program.
Yes. More often than not, those "other problems" you speak of are
caused by memory writes that go to wrong addresses (things not appearing on the screen, state variables not being updated, etc.; instead, the desired values COULD end up on the VIA ports).
While RAM is often at least 16x as large as I/O spaces, at least, and thus memory corruption is far more prevalent than I/O corruption, the chances of it occuring still isn't zero.
Quote:
If my adderss-decoding scheme didn't take up a whole 16K for I/O, I'd take advantage and use most of that space for more RAM, which means an errant pointer could still write trouble into something I'm using
OK, before I get taken to the burning post again for commandeering another thread, I want to make this clear:
I only said that there is a tradeoff between really fast, relatively fragile address decoding, and slower, more robust address decoding. Yes, a stray pointer can, and by Murphy's law
will, potentially affect I/O in a perfect address decoding system too. But the odds of it happening are that much more narrow.
Corrupting RAM is
far more preferable than I/O corruption, particularly when you're potentially corrupting disk I/O registers, or nuclear reactor controls, or, ...
Quote:
it'll just be corrupting data or a program in RAM instead of I/O. I see what you're saying, but it just has not been a problem in the 15 years I've been doing it this way.
I'm just saying, to the reader, be careful.
Because you haven't had the experience doesn't mean others won't either. I, for example,
have had this experience, and
continue to do so to this day, despite being a professional coder for the last 10 years, and coding in an amateur capacity for the last 20.
Quote:
I was trying to imagine a situation where you might have I/O pointers like to say, "Set these VIA registers up this way" and not assign which VIA it is until later; but my VIAs and ACIAs are connected to different things, so the hardware dictates that you have to know in advance which VIA or ACIA you'll be using, which means you won't really have any indirects there, only absolute addresses.
OK, but now you're forgetting about a
hhuuggee class of errors all deriving from, e.g., off-by-one errors, and more.
Consider the following chunk of Forth code:
Code:
create ringBuffer
4 cells allot
variable nextPointer
: placeItem
ringBuffer nextPointer @ + !
1 cells nextPointer @ + -4 cells and nextPointer ! ;
As long as nextPointer remains properly aligned, nothing bad will ever happen. But, what happens if someone accidentally forgets a @ or something while debugging interactively? As in,
xyz /something $DD fill or whatever. Doing this has a high likeliness of corrupting nextPointer so that it has, e.g., an odd value. Worst, it's value
plus the address of ringBuffer could very well point into I/O space, where the item stored could corrupt an I/O register.
Never underestimate the power of human error, particularly with powerful programming systems like assemblers or Forth.
I've run into this problem constantly. Even on GForth under Linux, where it exploits memory protection hardware to guard itself as much as it can, I still manage to crash GForth utterly such that I need to physically kill the process and restart it from the shell. In embedded systems terms, this is equivalent to physically cutting power and rebooting it.
To re-iterate: yes, you can use an amazingly small amount of logic to decode your addresses for I/O. Doing so necessarily makes the "I/O space" larger in proportion to memory spaces, and thus, makes sensitivity to stray, errant pointers that much greater. If you do this,
be aware, and take particular care to minimize pointer corruption.