|
Post by bob on Jun 30, 2018 13:34:13 GMT -5
Hi,
I'm running into a crash in a program. I've put a logic analyzer on the 6809's address and data lines to see what's going on.
The game runs for a long time - sometimes an hour or more - before crashing. When it crashes, the problem is that I'm stuck in an infinite loop in Wait_Recal. The 6809 is waiting for Timer 2's interrupt flag to go to 1, but the flag is stuck at zero. I don't understand how this is even possible. Looking back in the logic analyzer's data, I see the most recent write to the 6522's ACR ($D00B) is $98, so Timer 2 is in one-shot mode as it should be. The reads of the Interrupt Flag register ($D00D) are getting $44, so the Timer 2 interrupt flag is zero. But if the flag is zero and the timer is counting clocks, how could the interrupt flag stay zero forever? Wouldn't it eventually turn to 1?
This happens on more than one Vectrex, so I don't think it's a defective 6522.
Any idea what's going on?
Thanks, Bob
|
|
|
Post by Malban on Jul 1, 2018 11:48:18 GMT -5
Actually the manual is pretty clear in this point.
That means if for any reason - you are too late for your timer2, the interrupt did already occur, and if you additionaly "accidently" cleared the interrupt flag anywhere - it will NOT be set again.
Actually this happened to me quite a few times in the past - so I know exactly what you "feel" - something like - frustration - I did not do anything wrong - why me?
Hehe
Regards Malban
|
|
|
Post by gauze on Jul 1, 2018 23:42:49 GMT -5
so is the solution write your own Wait_Recal that has some kind of "watchdog" logic and use that instead?
I assume it's looping forever on this bit:
LDA #$20 LF19E: BITA <VIA_int_flags ;Wait for timer t2 BEQ LF19E
put something between BITA and BEQ lines that could bail if t2 doesn't hit after (for 50hz refresh) 30000/(5+3+7+7+3 cycles) iterations?
LF19E: LDA #$20 DEC something ; probably need more than 8bits though, add some "artificial" cycles just so it can do it with 255 or less iterations? TST something BEQ _bail BITA <VIA_int_flags ;Wait for timer t2 BEQ LF19E _bail:
I think you get the idea. I probably am not considering something here though, but it was a thought.
|
|
|
Post by Malban on Jul 2, 2018 5:24:30 GMT -5
Best thing usually is: do not clear the interrupt :-)
|
|
|
Post by bob on Jul 2, 2018 8:05:20 GMT -5
But the Wait_Recal routine flows into Set_Refresh, so that will always reset the flag and re-arm the timer.
How else can the interrupt flag be cleared? Is there a way to clear the flag that does not re-arm the timer?
Thanks, Bob
|
|
|
Post by Malban on Jul 2, 2018 8:48:54 GMT -5
Clear T2 interrupt:
a) read T2 low byte b) write 0x20 to IFR c) write T2 high byte (not relavant - see your point above)
When it happened to me I usually did something terribly wrong and cleared the flag one way or the other accidently. But once cleared after the T2 timed out - WaitRecal is a deathtrap.
|
|
|
Post by Malban on Jul 2, 2018 8:58:35 GMT -5
gauze Usually this happens after some "bug" - there is nothing that should reset the IFR of T2. Otherwise the WaitRecal would have been done differently. But anyhow - if you deem it neccessary to double check, easier than counting down some additional test-value would be to just check the hi byte of t2 (see other T2 thread) e.g.:
tst <VIA_t2_hi bmi time_out_occured (assuming the default refresh counter of $3075 - the $75 is positive and each count down value therefor also)
|
|
|
Post by bob on Jul 3, 2018 12:47:06 GMT -5
I've had a breakthrough. While checking whether I was incorrectly accessing any of the 6522's registers per your advice, I remembered that those registers are accessible at any address from $D000-$D7FF. And sure enough, my code accesses that extended range. Why? Because it's already gone off into the weeds.
So my search for the ultimate source of my bug continues, but you helped through a roadblock. Thank you Malban.
- Bob
|
|