Rybags Posted August 23, 2009 Share Posted August 23, 2009 Well, the CIA on the C-64 holds NMI low indefinately, until it's status is cleared by the user program. In Atari's case, you don't want that because DLI usage on a 1 per scanline basis is reasonably common. The other thing is that Antic's original design also needed to cater for System Reset which could occur anywhere. I think it's already been established that it's (S-Reset's) NMI only occurs at a certain cycle on the scanline. It could be that Antic needs to do things that way - there's some breathing space between DList Instruction and PMG fetches and the screen/refresh DMA burst, which in many cases keeps it busy for most of the remainder of the scanline. All that aside though, you'd think they would have tested for contention issues like we're having, and likely could have implemented the simple fix of extending /NMI by a couple of cycles. Quote Link to comment Share on other sites More sharing options...
Bryan Posted August 23, 2009 Share Posted August 23, 2009 Well, the CIA on the C-64 holds NMI low indefinately, until it's status is cleared by the user program. In Atari's case, you don't want that because DLI usage on a 1 per scanline basis is reasonably common. The other thing is that Antic's original design also needed to cater for System Reset which could occur anywhere. I think it's already been established that it's (S-Reset's) NMI only occurs at a certain cycle on the scanline. It could be that Antic needs to do things that way - there's some breathing space between DList Instruction and PMG fetches and the screen/refresh DMA burst, which in many cases keeps it busy for most of the remainder of the scanline. All that aside though, you'd think they would have tested for contention issues like we're having, and likely could have implemented the simple fix of extending /NMI by a couple of cycles. The funny thing is that it doesn't really matter how long NMI is, as long as it's cleared before the next one. Inverting NMI makes Chris' sound code work great, so that way NMI is asserted for all but 2 cycles of each line. With one chip it could be extended by resetting a counter that counts for 8 or 16 cycles (74LS190 type with TC routed into /CE, and /NMI into /PL), but the inversion method works too. Atari may have been trying to leave as much room as possible on the NMI line for other devices to use it since they can't be stacked like IRQ requests (edge vs level triggering). Quote Link to comment Share on other sites More sharing options...
Rybags Posted August 23, 2009 Share Posted August 23, 2009 But, by inverting NMI, won't that delay them by 2 cycles? Problem is - there's a fair bit of code that does near the limit of stuff before STA WSYNC and 2 cycles extra wait could be enough to cause it do the WSYNC too late and miss a scanline. Quote Link to comment Share on other sites More sharing options...
Bryan Posted August 23, 2009 Share Posted August 23, 2009 But, by inverting NMI, won't that delay them by 2 cycles? Problem is - there's a fair bit of code that does near the limit of stuff before STA WSYNC and 2 cycles extra wait could be enough to cause it do the WSYNC too late and miss a scanline. Yes, they'd be delayed 2 cycles but it's interesting that it worked. Quote Link to comment Share on other sites More sharing options...
Rybags Posted August 23, 2009 Share Posted August 23, 2009 Sounds fair that it does work... all that's happening is the 1->0 transitions are 2 cycles late. Unsolicited NMIs on the XL/XE are just assumed to be VBlanks, I guess if one was to sneak through on powerup it might upset things a little. But, since they rely on the transition and not the level, I doubt you'd be getting any dubious behaviour other than that 2 cycle delay. Quote Link to comment Share on other sites More sharing options...
atariksi Posted August 23, 2009 Share Posted August 23, 2009 Here's /NMI vs phase2 clock (ph2). The 6502 datasheet states that /NMI will be sampled during the ph2 interval (ph2 high). So, NMI properly falls and rises during the ph1 part of the clock. The problem must be that the 6502 requires not only a falling edge (one high sample followed by one low sample of /NMI) but NMI must also remain low until the some part of the CPU's interrupt sequencer is ready (not tied up in the early stages of an IRQ). I bet other 6502-based computers have longer NMI assertions, or ones that must be cleared. Perhaps, the C64 doesn't have the problem because the interrupt/NMI handling is at 1.023Mhz and in making a 1.79Mhz version the circuitry wasn't sped up to deal with it (or wasn't debugged at that speed). Quote Link to comment Share on other sites More sharing options...
atariksi Posted August 23, 2009 Share Posted August 23, 2009 When I hit warm reset, I get the same color pattern so previous INIT settings didn't have any impact in that case (this is reset when I'm not hitting the NMI cycle with the IRQ). And this is an Atari 800 so it's not a chip reset. When you hit Reset, it doesn't much matter if it's a chip or soft Reset. The OS warmstart clears all the Hardware Registers, so any previous syncing of Timers is lost. But... that only becomes apparent to someone using Timers if you've taken measures to change their alignment in the first place. Like I theorized before, you should get the same Timer alignment on a given machine every time because the warmstart clear-register routine hits WSYNC as well as putting Pokey into Init, so it causes a "default" alignment that should be the same on any machine using the same Operating System revision. I thought you were talking about INIT state having a memory of previous setting so even with one WARM RESET-- you have initialized it twice with same cycle position. Quote Link to comment Share on other sites More sharing options...
Rybags Posted August 23, 2009 Share Posted August 23, 2009 I don't think the clock speed on the 6502 would have bearing on NMI handling. But, the number of cycles NMI is held low might. The C64's differing case seems to be that CIA NMIs at least are held low until cleared by the program. No idea what the Restore key NMI does, maybe it's a momentary thing too, like Atari ? It's yet to be shown if in fact the C64 has the same issue when using CIA NMI vs IRQs, I guess I should try and test that out. At least it might help prove once and for all if the Atari's problem is Antic, or it's just a generic 6502 issue that can potentially crop up on any machine. Quote Link to comment Share on other sites More sharing options...
atariksi Posted August 23, 2009 Share Posted August 23, 2009 I don't think the clock speed on the 6502 would have bearing on NMI handling. But, the number of cycles NMI is held low might. The C64's differing case seems to be that CIA NMIs at least are held low until cleared by the program. No idea what the Restore key NMI does, maybe it's a momentary thing too, like Atari ? It's yet to be shown if in fact the C64 has the same issue when using CIA NMI vs IRQs, I guess I should try and test that out. At least it might help prove once and for all if the Atari's problem is Antic, or it's just a generic 6502 issue that can potentially crop up on any machine. Yeah, but even if NMIs are held down low for long time the fact that both occurred on same cycle and IRQ getting serviced first would flip priorities at least and if IRQ cleared the NMI request the NMI would never occur. Quote Link to comment Share on other sites More sharing options...
atariksi Posted August 23, 2009 Share Posted August 23, 2009 I don't have source with me on this disk I'm traveling with, I'll post the source code when I get home but I am getting a case where 3 consecutive cycles where I set INIT produce the same color patterns meaning the phase didn't move at all. (This is on Atari 800). I don't see why it would make any difference when doing this on 800 or 800xl. What would be nice is if you could post a .xex or .atr of the test prog when you get home. One difference on 800 vs 800XL is the CLD instruction is missing from NMI/IRQ handlers on 400/800 OSes. [it's been raining here in Tolland, MA and signal quality sucks-- finally got to log-in tonight; blackberry phones seem to be working fine though.] Quote Link to comment Share on other sites More sharing options...
analmux Posted August 23, 2009 Share Posted August 23, 2009 One difference on 800 vs 800XL is the CLD instruction is missing from NMI/IRQ handlers on 400/800 OSes. OK, but then we can emulate the same effect on 800xl as on 800xl we can redefine IRQ handler. Anyway, if it is just a 2-cycle difference (due to the extra CLD), it won't change the idea. Maybe some shift in the results. Quote Link to comment Share on other sites More sharing options...
Bryan Posted August 23, 2009 Share Posted August 23, 2009 (edited) I'm going to test this circuit for stretching NMI. It only involves one chip and no extra parts. EDIT: Results attached (stretched pulse on top). Works perfectly when playing sample. Edited August 23, 2009 by Bryan Quote Link to comment Share on other sites More sharing options...
atariksi Posted August 24, 2009 Share Posted August 24, 2009 I've just confirmed the behaviour using similar technique (enable SEROC IRQ at known times). Burn 5 cycles after WSYNC then Store 8 to IRQEN. It blocks any DLI, except those types that are on single scanline modes. To block single-scanline DLIs, strangely enough, you just need to burn 4 cycles after the DLI. Might be just the way Antic does DLIs... if it's a single scanline mode line then it must start the NMI one cycle earlier. I also tried the same technique but executing a 7-cycle 6502 Instruction... no problematic effects caused there at all. Also tried varying the delay after WSYNC - no effect. It would seem that you need to store to IRQEN exactly on cycle 112 (or cycle 111 if dealing with single-line modes). But it could be that POKEY has some delay before triggering the IRQ once we've enabled it. What mode/width are you using? WSYNC can be delayed by up to two cycles if playfield or refresh DMA extends to the end of a scanline. I've also suspected that you may encounter yet another cycle delay if the cycle immediately after STA WSYNC is contended, but unfortunately, I can't find my test app to confirm this. Can we have some test code that shows best/worst case of WSYNC cycle delays? I have just been doing double WSYNCs when there is probability of DMA cycles to get exact positioning on the scanline. Quote Link to comment Share on other sites More sharing options...
Rybags Posted August 24, 2009 Share Posted August 24, 2009 The Antic Timings text document would help there. Delays of WSync extending it beyond the normal restart should only occur in widescreen width or standard + scrolling. DMA Contention immmediately following a WSync store? I think it doesn't matter - the 6502 should still fetch the first byte of the following instruction. Quote Link to comment Share on other sites More sharing options...
atariksi Posted August 24, 2009 Share Posted August 24, 2009 The Antic Timings text document would help there. Delays of WSync extending it beyond the normal restart should only occur in widescreen width or standard + scrolling. DMA Contention immmediately following a WSync store? I think it doesn't matter - the 6502 should still fetch the first byte of the following instruction. I was in normal 40 column graphics 0 text mode and my timer starting position was going off by one cycle and sometimes correct until I started doing two consecutive WSYNCs. Now it always starts at a constant position. Quote Link to comment Share on other sites More sharing options...
Rybags Posted August 24, 2009 Share Posted August 24, 2009 Well, when you have a badline, the number of cycles available drops considerably... also you have the DList Instruction at the very start of it. There's also the consideration that if you store to WSync too late, it misses the boat and you end up a scanline later than you'd hoped for. Quote Link to comment Share on other sites More sharing options...
Bryan Posted August 24, 2009 Share Posted August 24, 2009 One thing I previously tried was connecting Antic's /NMI to its reset interrupt input. I was thinking that perhaps I could trick it into doubling up the NMI pulse, but of course it didn't work since reset is only sampled at certain intervals. Anyway, I don't think we can count on anyone implementing a hardware fix. The best solution is a fool-proof set of interrupt timing routines. Quote Link to comment Share on other sites More sharing options...
Rybags Posted August 24, 2009 Share Posted August 24, 2009 Agreed... I can't see people doing a hardware fix for the sake of having maybe half a dozen games (that don't yet exist) work. Plus there's always the possibility that it might break existing stuff that's out there. Quote Link to comment Share on other sites More sharing options...
Bryan Posted August 24, 2009 Share Posted August 24, 2009 (edited) Agreed... I can't see people doing a hardware fix for the sake of having maybe half a dozen games (that don't yet exist) work. Plus there's always the possibility that it might break existing stuff that's out there. I doubt it would break anything because as far as we know, the 6502 will always be oblivious to when the rising edge of /NMI happens and it would be very strange to rely on the /NMI dropping behavior for anything. Too bad Atari didn't catch this bug when they modified Antic with the extra refresh row for the XL machines. Edited August 24, 2009 by Bryan Quote Link to comment Share on other sites More sharing options...
atariksi Posted August 24, 2009 Share Posted August 24, 2009 Agreed... I can't see people doing a hardware fix for the sake of having maybe half a dozen games (that don't yet exist) work. Plus there's always the possibility that it might break existing stuff that's out there. I doubt it would break anything because as far as we know, the 6502 will always be oblivious to when the rising edge of /NMI happens and it would be very strange to rely on the /NMI dropping behavior for anything. Too bad Atari didn't catch this bug when they modified Antic with the extra refresh row for the XL machines. Here's a fix that seems to work (swap 6502 with 65c02) with one jumper: Quote Link to comment Share on other sites More sharing options...
Bryan Posted August 28, 2009 Share Posted August 28, 2009 Well, I was reading the old 1976 datasheet on the 6502 and discovered this tidbit on page 51: The /NMI signal must be low for at least two clock cycles for the interrupt to be recognized, whereupon new program count vectors are fetched. (shouldn't that be program counter?) So, Atari followed the minimum requirement of the official spec and MOS didn't know about the bug. Quote Link to comment Share on other sites More sharing options...
atariksi Posted August 28, 2009 Share Posted August 28, 2009 Well, I was reading the old 1976 datasheet on the 6502 and discovered this tidbit on page 51: The /NMI signal must be low for at least two clock cycles for the interrupt to be recognized, whereupon new program count vectors are fetched. (shouldn't that be program counter?) So, Atari followed the minimum requirement of the official spec and MOS didn't know about the bug. Unknowingly they seem to have fixed it in some variations of the 6502. Quote Link to comment Share on other sites More sharing options...
Bryan Posted August 29, 2009 Share Posted August 29, 2009 Unknowingly they seem to have fixed it in some variations of the 6502. Are you referring to your 65C02 test? The 65C02 is a totally reworked chip made years after the NMOS 6502 so that's not surprising. Quote Link to comment Share on other sites More sharing options...
atariksi Posted August 29, 2009 Share Posted August 29, 2009 Unknowingly they seem to have fixed it in some variations of the 6502. Are you referring to your 65C02 test? The 65C02 is a totally reworked chip made years after the NMOS 6502 so that's not surprising. I need to get my hands on some other variants of 6502 to try out... Quote Link to comment Share on other sites More sharing options...
Rybags Posted August 29, 2009 Share Posted August 29, 2009 Do you have any Release Notes or other technical manuals for the 65C02 ? Maybe they have mention of it. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.