-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
joystick_get() and JOY() are corruptable by irq handler in v39 [includes patch] #203
Comments
Could not replicate with x16-rom HEAD at 5496e0b and x16-emulator HEAD at 8852ddd, running the test program on warp mode for over a minute. Aside from a few errors being printed at the beginning of the program (as a result of the enter key being pressed), no incorrect inputs were detected. Looking at the code in joystick_get (located in kernal/drivers/x16/joystick.s), it seems unlikely that there could be a race condition, as all it does is retrieve values stored by joystick_scan. If there is an issue, it is likely in joystick_scan or the emulator itself. |
@Elektron72 yeah we found it's pretty timing critical in the basic program. @indigodarkwolf had to change the program around a little bit to trigger the error as well. I still have to isolate the issue from my game's code, where it pretty much always triggers consistently. I solved it (for now) by doing a SEI/CLI around joystick_get() so honestly I don't think the issue in is another routine |
@Elektron72 My theory is that This is a very small window of time, but small just means it's more sensitive to exact timing. Small does not mean impossible. |
I notice that KVARS_START and KVARS_END employ |
Either only a reversion to |
By the way, this faster program shows the "error" word more often, for me: 10 IFJOY(2)THENPRINT"ERROR",
20 GOTO10 |
I think it would be a good idea to add a warning to inc/banks.inc that KVARS_START_TRASH_NZ and KVARS_END_TRASH_NZ are not interrupt-safe. |
I finally isolated the issue into a small assembler program, you can find it below. It prints "!!!" without touching the joypad buttons pretty quickly on my emulator. ➡️ Interesting detail: the problem also doesn't occur if the ROM bank is not set to 0 (to enable kernal rom) but instead simply left at the default....!
|
I can try to make it into a PR but i'm not really familiar with those kernal source macro's.... |
thanks @Elektron72 for making the patch |
I discovered that there is a race condition in the joystick_get() kernal routine (and thus also in the basic JOY() function): it seems that when it gets interrupted by the system's irq handler, the values returned from the routine can be corrupted, thus sending fake joystick triggers to the program.
Here is an attempt to reproduce the problem in a basic program:
![image](https://user-images.githubusercontent.com/1771820/114772198-d1b18400-9d6d-11eb-8cd0-76efeefbeb35.png)
The result shown is the program running for about a minute while not touching the joypad or keyboard.
This is a tricky issue that we found is very timing sensitive. Sometimes it takes a LONG time before the first ERROR appears. Sometimes you need to tweak the program a bit for instance by introducing a variable. Enabling WARP mode speeds up the process. However in my own program that I work on, the issue almost always immediately and consistently pops up at a certain point int he program, so it is a real problem (for me at least).
The big difference we think from my code vs other people's code, is that I am not reading the joystick status from within my own irq handler but simply from the normal program flow (and system irq handler is still running normally) -- like the basic program above does too. That may explain the fact that nobody else ran into this yet. (assumption)
As far as I was able to test, the issue does not occur on the previous V38 version of the emulator + roms.
A possible fix revolves around disabling IRQ during the joystick_get(). Suggestion:
The text was updated successfully, but these errors were encountered: