Without taking time to thoroughly analyze the code, I'll make some comments.
Quote:
Can the 6551 ever have two bytes in that state? From the datasheet I have it only ever indicates there will be one. If another comes in before you read out the buffer you hit the overflow error condition?
You can only have one byte in the ACIA's buffer and one on its way in. If the one in the buffer hasn't been read by the time the new one is done coming in, it gets replaced by the new byte and an overrun error is flagged.
Quote:
2- in your routines: "ACIA read buffer" & "ACIA buffer get character"; you manage buffer pointers and call the "ACIA_Buffer_Diff" routine. Note that the IRQ service routine also calls the "ACIA_Buffer_Diff" routine manages the same pointers. Yet, interrupts are enabled when running either of the two routines ("ACIA read buffer" & "ACIA buffer get character"). You should disable interrupts so you don't have the IRQ service routine change pointers when either of the above routines are being executed. You should set interrupts off (SEI) at the start of each routine then clear it (CLI) when exiting the routine.
There is no need to disable interrupts while reading the circular receive buffer, because since you "turn off the faucet" (by setting CTS false) with plenty of space left in the buffer to keep the write pointer from overruning the read pointer, there will be space between them, and incrementing either one while the other is being accessed will not cause problems. I have done it this way for 20+ years with no problems whatsoever. I do not disable interrupts to read the buffer. The write pointer is only altered by the ISR, and the read pointer is only altered by the routine reading the circular buffer. The ACIA_Buffer_Diff routine does not alter
either pointer, and each pointer is only one byte so there's no chance of getting a wildly wrong result from having an interrupt-caused rollover from say $4FF to $500 between reading the two bytes which would result in reading $400 or $5FF.
Quote:
What I am seeing though is the memory on the machine gets corrupted. I just don't see how.
Is unrelated memory getting corrupted, ie, not just what you're receiving?
If your ISR does not handle anything else, it will surely be done before the next byte is in; but if you were transmitting too, and running both on interrupts, then anytime you read the ACIA's status register, you better keep a copy and check
it (the copy) for both transmit buffer empty and receive buffer full (without re-reading the status-- just get it from your saved record); because otherwise, if you read it again in the same ISR (like you're doing), and testing for something else, the earlier thing you checked for could have gotten set in between the two readings and will never be serviced because the each reading of the status register clears the high bit so the ISR will not be re-entered when done in order to service the other part. (This is what I addressed in Tip #14 at the bottom of the page at
viewtopic.php?f=7&t=342.