alex_79 Posted April 1, 2020 Share Posted April 1, 2020 45 minutes ago, Thomas Jentzsch said: But then, why did this not happen more frequently before? The pattern (wait for timer, vertical sync, start new timer) is pretty common. Good point. Maybe the chance for the write to happen at the exact cycle are low. Or, simply, the problem is elsewhere. I just tried to write a value to TIM64T and enabling the RIOT interrupt, and then keep the cpu in an infinite loop without ever reading back the timer. I connected the logic analyzer to the RIOT IRQ pin and it just stays low. So the interrupt flag doesn't get cleared on subsequent wraparounds and I guess the divide ratio stays at 1 clock. And that's how Stella behaves too. I'm out of ideas... Quote Link to comment Share on other sites More sharing options...
RevEng Posted April 2, 2020 Share Posted April 2, 2020 My NTSC console+CRT doesn't roll for either "roll" or "non roll" versions of the program, but the "roll" version does look quite different - the bar normally displayed at the top of the screen is mostly hidden off the top of my screen. So this issue does indeed affect NTSC consoles, in my case a 7800. The screen just doesn't roll as readily here. If I load INTIM immediately after the TIM64T write in the overscan routine, and later display it's value in PF1, the value displayed is 27. This output is identical in Stella and real hardware, and is one down from the value we wrote in TIM64T (28) which is reasonable. If I load INTIM immediately after the TIM64T write in the vertical blank routine, and later display it's value in PF1, the value displayed is 32. This disagrees with Stella (36) and is implausibly far from the value written in TIM64T. (36) 2 Quote Link to comment Share on other sites More sharing options...
RevEng Posted April 2, 2020 Share Posted April 2, 2020 Hah, pretty sure I have it. I added a NOP between the vblank TIM64T write and my load of INTIM, and the returned value changed to 30. (2 less than the result without the NOP delay.) Then I put 2 NOPs between the TIM64T write and INTIM read, and the returned value became 28. It seems that if you happen to update TIM64T (and presumably the other resolutions) on that very last cycle remaining, RIOT stores your new value correctly, but it still changes the timer over to single-cycle resolution as part of the usual time-out housekeeping, instead of using the timing resolution you selected. That's quite the bug. 4 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted April 2, 2020 Author Share Posted April 2, 2020 That explains it, yes. But it doesn't explain why that bug has never been noticed before. The coincidence is not that big. Quote Link to comment Share on other sites More sharing options...
alex_79 Posted April 2, 2020 Share Posted April 2, 2020 3 hours ago, RevEng said: It seems that if you happen to update TIM64T (and presumably the other resolutions) on that very last cycle remaining, RIOT stores your new value correctly, but it still changes the timer over to single-cycle resolution as part of the usual time-out housekeeping, instead of using the timing resolution you selected. That's quite the bug. This behaviour is described in the 6532 datasheet, altough not very clearly, and only referred to read accesses: Quote After the interrupt, whenever the timer is written or read the interrupt is reset. However, the reading of the timer at the same time the interrupt occurs will not reset the interrupt flag. And from previous research, we know that the interrupt flag is what determines if the timer counts at 1 clock rate or uses the previously stored divider (so if you read the timer after the flag has been set, that is after it has counted past to 0, it normally resumes counting with the previously set divider. The exception would be if the read happens at the wraparound cycle. To sum up, I think this is what's going on: - If the interrupt flag (bit 7 of TIMINT) is set, the programmed divider is ignored and the timer counts at 1 clock rate. - Whenever the timer wrapsaround from 0 to $FF, the interrupt flag is set. (if it was already set, it stays that way) - Writing or reading the timer clears the interrupt flag, unless the read/write happens at the exact wraparound cycle, in which case the flag is set afterwards. So If you read INTIM at wraparound, the result is $FF, the flag is set and the timer counts down at 1T rate If you write to TIM64T at wraparound, the timer is updated with the correct value, but the flag is set and it counts at 1T So a read access at the exact wraparound cycle stills needs to be confirmed. (This might already be implemented in stella, as it's part of the datasheet). It's also worth checking the behaviour on subsequent wraparounds (when the interrupt flag is already set) 3 1 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted April 2, 2020 Author Share Posted April 2, 2020 Can you please create an issue for this? Quote Link to comment Share on other sites More sharing options...
alex_79 Posted April 2, 2020 Share Posted April 2, 2020 Sure, but I think it would be better to confirm that this is the actual behaviour first. After this has been fixed, a developer option to break on timer accesses at the wraparound cycle would save future headaches. Quote Link to comment Share on other sites More sharing options...
RevEng Posted April 2, 2020 Share Posted April 2, 2020 1 hour ago, Thomas Jentzsch said: That explains it, yes. But it doesn't explain why that bug has never been noticed before. The coincidence is not that big. Assuming even distribution (which I don't think is quite correct) it would be a 1 in 256 chance that your code timing aligns with the one crucial cycle, from the time one INTIM test loop has finished (and begun counting down in single cycles) to the next time you try setting a RIOT timer. Since the bug is easily perturbed, I think if someone has run across it before, they've probably "fixed" it and moved on. [edit - and that 1 in 256 chance is assuming the bug is still possible, even when the interrupt has already been triggered once.] 1 Quote Link to comment Share on other sites More sharing options...
Thomas Jentzsch Posted April 2, 2020 Author Share Posted April 2, 2020 4 minutes ago, alex_79 said: Sure, but I think it would be better to confirm that this is the actual behaviour first. Sure, but this can be part of the issue. 4 minutes ago, alex_79 said: After this has been fixed, a developer option to break on timer accesses at the wraparound cycle would save future headaches. Good idea. Quote Link to comment Share on other sites More sharing options...
alex_79 Posted April 2, 2020 Share Posted April 2, 2020 17 minutes ago, Thomas Jentzsch said: Sure, but this can be part of the issue. Done! 1 3 Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted April 3, 2020 Share Posted April 3, 2020 I believe I have run into this issue before! In this thread I converted Alien 8K to PAL60, and went through several versions until I fixed the rolling. Rolling roms are in posts 12, 17, 19. The fixed rom is in this post: Please note, the title screen is fine. The roll only occurs in the game screen every 1 or 2 seconds. 2 Quote Link to comment Share on other sites More sharing options...
+batari Posted April 3, 2020 Share Posted April 3, 2020 I’m amazed. A hardware bug in a chip discovered some 45 years after its release. And such an onerous bug too, I am surprised it’s never been identified before. Just when we are sure we know everything there is to know about the 2600, new stuff still gets found. 3 Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted April 3, 2020 Share Posted April 3, 2020 3 hours ago, batari said: I’m amazed. A hardware bug in a chip discovered some 45 years after its release. And such an onerous bug too, I am surprised it’s never been identified before. Just when we are sure we know everything there is to know about the 2600, new stuff still gets found. Atari should do a recall of all '2600 units ASAP. 1 4 Quote Link to comment Share on other sites More sharing options...
JetSetIlly Posted April 3, 2020 Share Posted April 3, 2020 (edited) I've been playing with these ideas this evening and they seem to fix the timing issues I was seeing in https://github.com/stella-emu/stella/issues/108 . I now get the correct values as reported to be seen on the real hardware. Just as a point of note, when setting a new timer, the bit pattern that is used to clear TIMINT seems to differ depending on whether TIMINT is already off or not. As far as I can tell, if TIMINT is currently on, it is cleared with but pattern 0x00. If it has already been cleared it is given the bit pattern 0x40 You can see this difference in test2.bas.bin and testTIMINT_withDelay.bin In test2.bas.bin if TIMINT is cleared with 0x00 then the incorrect value is written to RAM register 0xd7. When 0xd7 is later tested for the overflow bit it will never reach the correct branch. This results in the incorrect number on the display (000249 instead of 064249) It would be nice to see the schematics for the RIOT chip to see what's going on and whether it matches the observations. on edit: this is of course, wrong. the difference is to do with PA7 interrupt. more edit: if we say the pa7 flag is set at startup (ie. before TIMINT is ever read) and only reset when TIMINT is read for the first time, then that satisfies all the timer test cases. Edited April 5, 2020 by JetSetIlly 1 Quote Link to comment Share on other sites More sharing options...
alex_79 Posted April 5, 2020 Share Posted April 5, 2020 On 4/4/2020 at 1:21 AM, JetSetIlly said: more edit: if we say the pa7 flag is set at startup (ie. before TIMINT is ever read) and only reset when TIMINT is read for the first time, then that satisfies all the timer test cases. The PA7 flag value reported in that Stella issue is likely the result of loading the roms from the Harmony menu. Since you use the left joystick to navigate the files and directories in the SD card, the flag gets easily set before starting the rom. I tried again those roms ensuring not to move the joystick to the right, and the result I got is that flag is cleared. So it might be always cleared on startup, or maybe its status is undefined and varies depending on the specific console. I tried compiling an up to date version of Gopher2600 and the results with the test rom posted in this thread matches my observations (238 scanliines). Too bad that my PC seems to be too old to run the emulator at full speed. 1 Quote Link to comment Share on other sites More sharing options...
JetSetIlly Posted April 5, 2020 Share Posted April 5, 2020 Quote The PA7 flag value reported in that Stella issue is likely the result of loading the roms from the Harmony menu. Since you use the left joystick to navigate the files and directories in the SD card, the flag gets easily set before starting the rom. I tried again those roms ensuring not to move the joystick to the right, and the result I got is that flag is cleared. Ahh. Okay. That makes sense. My next step then, is to add the code that will set the PA7 when the correct conditions are met. 24 minutes ago, alex_79 said: I tried compiling an up to date version of Gopher2600 and the results with the test rom posted in this thread matches my observations (238 scanliines). Too bad that my PC seems to be too old to run the emulator at full speed. Yeah. It is slow. That's partly a consequence of the choice of language (garbage collecting etc.) Sorry about that ? The project began as a learning exercise (for both the language and the 2600) and I never expected it to get to the stage it is. Thanks for trying it out though, that pleases me greatly. 1 Quote Link to comment Share on other sites More sharing options...
alex_79 Posted April 6, 2020 Share Posted April 6, 2020 (edited) On 4/2/2020 at 8:05 AM, Thomas Jentzsch said: That explains it, yes. But it doesn't explain why that bug has never been noticed before. The coincidence is not that big. Turns out it has, but apparently passed under the radar... This is from the "Kim-1/6502 User's notes" newsletter, issue 12 (July 1978). (Note tha the KIM-1 uses a 6530 RRIOT (Rom, Ram, I/O, Timer) and the timer part works the same as the 6532.) Note tha the proposed workaround is to write the timer twice, as suggested by @RevEng Edited April 6, 2020 by alex_79 6 Quote Link to comment Share on other sites More sharing options...
JetSetIlly Posted April 6, 2020 Share Posted April 6, 2020 (edited) 12 hours ago, alex_79 said: Turns out it has, but apparently passed under the radar... This is from the "Kim-1/6502 User's notes" newsletter, issue 12 (July 1978). (Note tha the KIM-1 uses a 6530 RRIOT (Rom, Ram, I/O, Timer) and the timer part works the same as the 6532.) Also this post from AtariAge in 2008. on edit: my mistake. on second reading, that post is talking about reading rather than writing. Edited April 6, 2020 by JetSetIlly 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.