It seems like no emulator is able to run all 4 of these games at once without some sort of issue:
-Druid Kyoufu no Tobira (status bar flickers every other frame)
-Kaettekita Mario Bros (graphical glitches in disk insert prompt screen)
-Lutter (freezes after pressing any button once in game)
-Putt Putt Golf (no sound, buggy scrolling in-game)
Of all the emulators I've tested, there is always at least 1 game that fails (I may have missed some):
Bizhawk - Kaettekita Mario Bros
FCEUX - Druid Kyoufu no Tobira
Mesen - Putt Putt Golf
Nestopia UE - Druid Kyoufu No Tobira, Lutter
Nintaco - Kaettekita Mario Bros
Nintendulator - Kaettekita Mario Bros
puNES - Lutter, Putt Putt Golf
I haven't been able to find any way to keep all 4 games working at once.
All of these seem to be linked to the behavior of the IRQ reload value ($4020 & $4021) when the IRQ reload flag is disabled (bit 0 in $4022). When & under what conditions the reload value gets reset to 0 has an impact on these games - some appear to expect the reload value to be preserved after writes to $4022 or after an IRQ is triggered, while others expect the reload value to reset to 0 in similar conditions. I haven't managed to find any pattern that makes sense between all 4 games.
The Wiki doesn't seem to mention the reload flag in $4022, and I am not really aware of any other FDS documentation that does (other than emulator sources) - the other FDS documents listed in the old nesdev homepage don't mention the irq reload flag either. There is an older thread by FHorse about Kaettekita Mario Bros on here, but I haven't really been able to find any other information beyond that.
So... any ideas?
my build nestopia,
-Druid Kyoufu no Tobira OK
-Kaettekita Mario Bros OK
-Lutter OK
-Putt Putt Golf no sound
if(_irqEnabled && !_irqReloadEnabled) {
//Needed by Kaettekita Mario Bros
//If done when _irqEnabled is false, Lutter breaks
if(_irqReloadValue & 0x0F)
_irqReloadValue = 0;
}
While that works (Kaettekita sets $6302 as the reload value, Putt Putt Golf uses $5400), it's essentially a patch on top of another patch (I'm fairly sure that the condition in Mesen's code that you modified here is incorrect, hardware-wise).
I'm mostly hoping to figure out how the FDS itself resets the value, since patches could just end up breaking any other FDS game.
working nestopia for all irq fds.
Sour wrote:
Of all the emulators I've tested, there is always at least 1 game that fails (I may have missed some):
(...)
So... any ideas?
Try my emulator RockNES and let me know.
Zepper wrote:
Try my emulator RockNES and let me know.
Same as Bizhawk, Nintendulator & Nintaco - 2 of the 3 random intro sequences to Kaettekita Mario Bros end with a glitchy disk switch message.
This is the behavior you get when you never reset the reload value to 0.
I guess only Kaettekita Mario Bros expects this to happen - maybe the actual issue is elsewhere.
Sour wrote:
Zepper wrote:
Try my emulator RockNES and let me know.
Same as Bizhawk, Nintendulator & Nintaco - 2 of the 3 random intro sequences to Kaettekita Mario Bros end with a glitchy disk switch message.
This is the behavior you get when you never reset the reload value to 0.
I guess only Kaettekita Mario Bros expects this to happen - maybe the actual issue is elsewhere.
I don't know such game. Is it original or... an hack of the FDS SMB?
Sour wrote:
Zepper wrote:
Try my emulator RockNES and let me know.
Same as Bizhawk, Nintendulator & Nintaco - 2 of the 3 random intro sequences to Kaettekita Mario Bros end with a glitchy disk switch message.
This is the behavior you get when you never reset the reload value to 0.
I guess only Kaettekita Mario Bros expects this to happen - maybe the actual issue is elsewhere.
Hardware not this bug.
Zepper wrote:
Sour wrote:
Of all the emulators I've tested, there is always at least 1 game that fails (I may have missed some):
(...)
So... any ideas?
Try my emulator RockNES and let me know.
Attachment:
20170919113841.png [ 7.89 KiB | Viewed 9458 times ]
The wiki page about FDS is lacking some information from Enri's page. Enri's page doesn't mention $4022.0 either though.
Quote:
$4022:(出力) [output]
Bit2:1=IRQタイマカウント開始、0=IRQタイマカウント停止 [1=IRQ Timer Count Start, 0=IRQ Timer Count Stop]
Enri's page differs from the wiki on this matter: $4022.2 controls timer state according to Enri. I guess Enri is wrong in this case?
Pokun wrote:
Enri's page differs from the wiki on this matter: $4022.2 controls timer state according to Enri. I guess Enri is wrong in this case?
I'm guessing this is probably a typo and meant to say Bit 1 (as in the 2nd bit).
On the other hand, this reminded me that I hadn't checked another Japanese source of information - VirtuaNES. And after checking, it actually plays all 4 games properly :)
Its source code implies that bit 0 of $4022 is not an irq reload flag, it's an irq repeat flag.
If bit 0 is not set, the IRQ is supposed to trigger a single time, and then the irqEnabled flag is set to false (but its reload value is not altered). The IRQ's timer is always reloaded with the reload value once it triggers.
Using this logic makes all 4 games work *if* you also add logic to disable the "irqEnabled" flag when the game writes to $4023 with bit 0 (disk registers enabled) cleared (this is also from VirtuaNES' code). Otherwise Kaettekita Mario Bros crashes with an illegal opcode.
At the very least, this logic fixes the issues in Mesen too, and seems to make sense. (still need to try running other games to make sure this works properly, though)
I see, all these emulators got it wrong because there's little accurate information of the FDS (at least in English). I think a mending of the wiki is in order. And proper test disk images so the behaviour can be verified on real hardware and emulators alike.
I'm assuming you've verified the behaviour of these 4 games against an actual FDS, but in case the hardware is scarce if you've got an FDS file you'd like tested I can do it.
Actually, I haven't - I don't own an FDS (or even a Famicom for that matter).
But, as far as I know, all 4 games are licensed games, so it seems unlikely that they would contain these obvious bugs that can be noticed within seconds of loading up the game?
And yes, the Wiki is pretty lacking in terms of information (I had to scavenge information from a lot of different emulators to implement FDS support in Mesen originally). But I'm also hesitant to update the wiki with information that may or may not be correct. Writing tests for the FDS would be ideal to validate some of its behavior, but FDS test roms is currently far beyond my (almost nonexistent) NES coding skills.
I made an example template, if you need one:
https://forums.nesdev.com/viewtopic.php?p=193241#p193241Sour wrote:
But, as far as I know, all 4 games are licensed games, so it seems unlikely that they would contain these obvious bugs that can be noticed within seconds of loading up the game?
It's a red flag, for sure, but usually worth verifying by whatever reasonable measures you can take. I think a lot of people here could provide a whole library of examples of "I thought it was an emulator bug, but it's actually in the game."
Just to verify, though, I found FDS files of the 4 games in question and spent some time playing them to test. They did not appear to have any of the problems listed:
Druid Kyoufu no Tobira seemed to have a lot of single frame glitches at transition points, like a lot of NES games do, but the status bar stays correctly in one place (though with the usual jittery line of transition).
Lutter I could only find an En translation patched version, but it also played fine. Some minor/brief visual attribute problems, but I would assume these are normal.
Kaettekita Mario Bros appeared normal.
Putt Putt Golf appeared normal.
Sour wrote:
Its source code implies that bit 0 of $4022 is not an irq reload flag, it's an irq repeat flag.
Same of Konami's VRC IRQs. ^_^;;
Quote:
(...)The IRQ's timer is always reloaded with the reload value once it triggers.
What do you mean??? Is the IRQ counter
always decrementing? or only if $4022:$02 is true? Plus, what happens when the IRQ counter is zero? A reload + IRQ trigger?
That template should be enough to get me started on writing some very basic tests when I get the chance.
Thanks for testing the games, too.
Druid does have a number of glitches in Mesen as well, but for the most part looks alright (except for the jitter on the first line of the status bar, like you said).
A note on Kaettekita Mario Bros: there are 3 random opening animations before the game asks to switch to side B. 1 of the 3 openings works correctly whether or not the IRQ logic in the emulator is correct, while the other 2 will display a glitchy screen.
Only the one that has 「お茶づけ海苔」 written (vertically) works. The ones written 「五目チャーハンの素」 and 「スーパーマリオブラザーズふりかけTM」 are the ones that start glitching on the following black screen that is supposed to ask for side B.
Zepper wrote:
Is the IRQ counter always decrementing? or only if $4022:$02 is true? Plus, what happens when the IRQ counter is zero? A reload + IRQ trigger?
Assuming VirtuaNES is correct:
The counter only decrements when $4022.1 (bit 1, e.g $02) is enabled. When the IRQ fires, the IRQ's timer is always reset to the value stored in $4020 & $4021. Then if $4022.0 is set, the irqEnabled flag ($4022.1) remains on. If $4022.0 is NOT set when the IRQ fires, the irqEnabled flag is disabled.
The reload value in $4020/$4021 is apparently never cleared (unlike what a lot of emulators currently implement)
Additionally, writing to $4023.0 with bit 0 clear (enable disk reg) also appears to clear the irqEnabled flag.
And yes, it's actually pretty similar to the VRC IRQs now that you mention it (except the FDS disables the IRQ enabled flag on its own after the irq is fired, rather than waiting for the code to acknowledge it manually by writing to a register)
What about the IRQ counter reload value? Can it be zero?
Sour wrote:
A note on Kaettekita Mario Bros: there are 3 random opening animations before the game asks to switch to side B. 1 of the 3 openings works correctly whether or not the IRQ logic in the emulator is correct, while the other 2 will display a glitchy screen.
Testing for this, all three appear to proceed to the game without issue.
Let me know now... please. I've updated my emulator.
I ended up making a handful of very primitive IRQ-related tests.
Test #1 - Validate that IRQ doesn't repeat when $4022.0 is cleared
Test #2 - Validate that IRQ repeats when $4022.0 is set
Test #3 - Validate that IRQ reload value is kept even when $4022.0 is cleared
Test #4 - Validate that writing $00 to $4023 clears IRQ enabled flag
Test #5 - Validate that writing $01 to $4023 acknowledges the IRQ
Test #6 - Validate that writing to $4020 acknowledges the IRQ
Test #7 - Validate that writing to $4021 acknowledges the IRQ
Test #8 - Validate that writing $00 to $4022 acknowledges the IRQ
Test #9 - Validate that writing $02 to $4022 acknowledges the IRQ
The results are displayed as a sequence of 9 "X" or "O" characters.
An actual FDS probably fails some of these (I wouldn't be surprised if some of the IRQ acks failed). If VirtuaNES is correct, tests 1, 2, 3, 4 and 8 should pass, the rest should fail.
I tested this on FCEUX, puNES, Nestopia UE, Nintendulator & Mesen - they pretty much all get different results, but the result screen does show up properly, so the test itself should be working correctly.
The test relies on being able to acknowledge the IRQ by reading $4030, which I assume should work on the FDS too.
If it doesn't, you'll get a blank screen.
Looking forward to seeing the results!
My FDS + Famicom gives the result: OOXOXXXOX
Thanks for testing!
I expected #3 to pass (this is needed to fix all 4 games) - I think I might know why it didn't, though.
I wrote $00 to $4022 before writing $02 to $4022 for the 2nd time to trigger a 2nd IRQ - writing $00 might have cleared the reload value.
I fixed the tests that failed so that they pass based on the results you gave and added test 10:
Test #1 - Validate that IRQ doesn't repeat when $4022.0 is cleared
Test #2 - Validate that IRQ repeats when $4022.0 is set
Test #3 - Validate that IRQ reload value is kept even when $4022.0 is cleared
Test #4 - Validate that writing $00 to $4023 clears IRQ enabled flag
Test #5 - Validate that writing $01 to $4023 doesn't acknowledge the IRQ
Test #6 - Validate that writing to $4020 doesn't acknowledge the IRQ
Test #7 - Validate that writing to $4021 doesn't acknowledge the IRQ
Test #8 - Validate that writing $00 to $4022 acknowledges the IRQ
Test #9 - Validate that writing $02 to $4022 doesn't acknowledge the IRQ
Test #10 - Validate that writing $00 to $4022 clears the reload value
Hopefully this gets all Os this time.
On my FDS + Famicom
FdsIrqTestsV2 result: OOXOOOOOOX
Edit: sometimes after power on that X in the third position is an O? after reset it always becomes an X. (This happened 4 times out of maybe 15)
Not sure if that difference could be cause by when specifically i trigger the "insert disk" from the FDSstick, but it seems to happen on both early and late inserts after power on, randomly.
My RAM Adapter with FDSStick produces the same results as Rainwarrior on both test programs. The third test of FdsIrqTestsV2 passes sometimes but never after a reset.
rainwarrior wrote:
Sour wrote:
A note on Kaettekita Mario Bros: there are 3 random opening animations before the game asks to switch to side B. 1 of the 3 openings works correctly whether or not the IRQ logic in the emulator is correct, while the other 2 will display a glitchy screen.
Testing for this, all three appear to proceed to the game without issue.
Note that there are many bad disk images on the internet. For example there is a Zelda 2 one that appears to be missing treasures even though you start a new game (this happens on real hardware as well as emulators). I think it's the no-intro dumped disk image that's missing items in Zelda 2. Try TOSEC dumps for hopefully better results.
Thanks for testing.
This is odd since test #3 in V1 is essentially the opposite of test #10 in V2 - I'm not sure how both could fail.
Since the results are a bit hard to debug, I made another version that draws the number of IRQs that are triggered by each test. That should give us a bit more info on what's happening when #3 fails/passes.
Attachment:
example_000.png [ 4.65 KiB | Viewed 3215 times ]
I also added test #11, which should be identical to test #3 in V1.
OK now it looks like this (if test 3 passes):
Code:
○○○○○○○○○×○
♥♥♥ ♥♥♥♥♥♥♥
♥♥ ♥♥♥ ♥♥♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥
♥
♥
♥
♥
And the cases where the third test fails, the heart pattern is a bit different:
Code:
○○×○○○○○○×○
♥♥♥ ♥♥♥♥♥♥♥
♥♥ ♥♥♥ ♥♥♥
♥♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥ ♥♥♥ ♥
♥
♥
♥
♥
♥
Attachment:
FdsIrqTestsV3.png [ 8.96 KiB | Viewed 3517 times ]
My results.
If I don't acknowledge the IRQ at $4022, I got a blank screen.
Can confirm the same results as Pokun. (The alignment of those diagrams is off, for me, I think that heart isn't properly monospaced, but it should be clear from context where the columns lie.)
Again, random after power on and load whether it's the 3=X or 3=O version. (Always 3=X after reset.)
BTW, two posts down from my example template there was a version that skips the licensing screen. Would help for faster iteration on tests if you used that (unless you think that would throw off the test). Didn't matter at first when doing just one test, but the power vs. reset variation seems to necessitate multiple tests.
So it seems like the IRQ is somehow triggered an extra time under some scenarios.
What I don't understand is that test #11 is virtually identical but appears to consistently trigger the IRQ only twice (as it should)
Code:
;TEST #3 - Validate that IRQ reload value is kept even when $4022.0 is cleared
jsr inittest ;set reload value to 200 cycles, write $00 to $4022
;start irq, without repeat
lda #2
sta $4022
;wait for a few cycles (pretty long wait, probably 1000+ cycles)
ldx #$FF
jsr wait_time
;in test #11, the following is also executed:
;lda #0
;sta $4022
;start irq again, without repeat
lda #2
sta $4022
;wait again
ldx #$FF
jsr wait_time
;at this point, the IRQ should have been triggered twice
cmp #02
bne test3fail
The IRQ handler is essentially this (ignoring all the conditions used for some of the tests):
Code:
irq:
sei
pha
lda $4030 ;ack irq
pla
inc irqCounter
cli
rti
It seems unlikely that writing $00 to $4022 before writing $02 again would change the behavior.
Either way, since the difference is between having 2 IRQs or 3 IRQs, it's pretty much confirmation that the irq reload value is never reset (which is the behavior Kaettekita needs).
Something else is triggering an IRQ (maybe the FDS' floppy drive?) or there must be something wrong with my code.
I'd be curious to see the behavior if I added a large delay before starting the tests (e.g a couple of frames maybe), and/or if I added a copy of the 3rd test as test #12. I think I'll try both and see how that goes.
There's also a few more test ideas I'd like to add to it and I'll try switching over to the version that skips the copyright screen, too.
The drive only uses IRQ while data is being loaded. It's stopped doing that before the code is even run. (After loading I could unplug the FDSStick and reset, doesn't change anything.) Though, you could put an additional test in that waits around and counts any spurious IRQs; I don't believe this is the case though.
All I would suggest is that something done in tests 4-10 is affecting the state of success for test 3. A state that's "random on power up".
I stared at the reset/init code for a while and couldn't really see anything that would be different between power on/reset (but I'm definitely not qualified for this).
I added some tests, removed some leftover unused code from the template (that should have no impact) and modified it to use the copyright screen skip technique.
#1 - Validate that IRQ doesn't repeat when $4022.0 is cleared
#2 - Validate that IRQ repeats when $4022.0 is set
#3 - Validate that IRQ reload value is kept even when $4022.0 is cleared
#4 - Validate that writing $00 to $4023 clears IRQ enabled flag
#5 - Validate that writing to $02 to $4023 does not acknowledge the IRQ
#6 - Validate that writing to $4020 does NOT acknowledge the IRQ
#7 - Validate that writing to $4021 acknowledges the IRQ
#8 - Validate that writing to $4022 acknowledges the IRQ when bit 1 is cleared
#9 - Validate that writing to $4022 acknowledges the IRQ when bit 1 is set
#10 - Validate that IRQ reload value is not cleared when $4022 is set to $00
#11 - (Copy of test 3) Validate that IRQ reload value is kept even when $4022.0 is cleared
#12 - Validate that writing $02 to $4022 while counter is running will reset counter
#13 - Validate that writing $02 to $4022 when irq reload value is $00 does not trigger an irq
#14 - Validate that no IRQ occurred before the tests started
Note: I deleted the old #10 test since it failed on the FDS (and it was essentially the opposite of another test).
Test #14 is the first one to run, I just didn't want to change the order of all the previous tests visually. It does:
Code:
lda #$C0
sta $101
cli
to enable IRQs, and then waits for ~400k cpu cycles - during which no IRQ should occur.
Test #11 is an exact copy of #3 - so they *should* get the same result (unless the state is inconsistent between both tests)
v4 does not boot for me. Just a black screen.
Maybe try it without the license screen skip just in case that's adding something weird to the equation.
Mostly same of before.
100% OK now.
rainwarrior wrote:
v4 does not boot for me. Just a black screen.
I made 3 versions to try and figure out what is causing the issue:
4b-14tests: Has copyright screen, same tests as v4
4b-12tests: Has copyright screen, missing tests 12 & 13 (the 2 new tests)
4b-11tests: Has copyright screen, missing tests 11, 12 & 13 (the 2 new tests + the delay loop at the start that checks for unexpected IRQs)
That should cover most of the changes between v3 and v4 - I don't believe I've done any other significant change (hopefully).
@Zepper, if you're testing this on your emulator - it's a bit too early for that. We're still trying to figure out what the FDS' behavior is exactly, so the tests aren't really something you can apply to an emulator just yet.
Code:
V4b-11: OOXOOOOOOOO > 1, 16, 3, 0, 11, 11, 11, 1, 11, 2, 2
OOOOOOOOOOO > 1, 16, 2, 0, 11, 11, 11, 1, 11, 2, 2 (power/load only, sometimes)
V4b-12: black screen
V4b-14: black screen
Will suggest one thing: in your IRQ routine you SEI and CLI? Why?
SEI is already implied/forced by the IRQ itself, and RTI will clobber the interrupt flag.
If there is a second IRQ here that $4030 does not ack, the CLI will end up retriggering it in an infinite loop?
Maybe relevant is this curious note about a delay in the BIOS after a disk IRQ ack?
;disk IRQ acknowledge routine ([$0101] = 10xxxxxx).
;don't know what this is used for, or why a delay is put here.
$E1EF PHA
$E1F0 LDA $4030
$E1F3 JSR Delay131
$E1F6 PLA
$E1F7 RTI
Ok, so v4b-11 confirms that test 3 is supposed to work (since test 11 is identical and does work). Also seems to confirm that it's the delay test at the start that is causing the black screen.
As for the sei/cli, the best answer I can give is: because I only have limited understanding of how to make programs for the NES :p
I removed both of them. I also changed the code so that NMI is disabled until after all the tests are done running, one less thing to worry about.
v5 has all 14 tests (including the delay test at the start), v5-nodelay is missing the delay test at the start. Both versions skip the copyright screen.
Sorry about the billion different tests, by the way :\
Code:
V5-nodelay: OOXOOOOOOOOOX 1, 15, 3, 0, 11, 11, 11, 1, 11, 2, 2, 0, 1
V5 : black screen with a single heart on it (i think 6th column from left of screen)
There seems to be no more variation at power on for these. The results are consistent? (Tested 20 or so times.)
I was interested in the idea that some unknown extra IRQ might fire some short period after boot/load, so I wrote a test that I think should catch it and log it.
My results were negative, though. I couldn't see any such IRQ (either with the license screen or skipping it).
Attached source code and FDS files.
Basically this test spins for a seconds or so after boot trying to log any IRQs that happen. It spits out the result starting with a number indicating the number of IRQs seen, then a series of log entries, each of 3 8-bit numbers in HEX. The first indicates the 'intended' value of $0101 for the IRQ, and the other 2 are just a timestamp.
There's an "APU" version of the FDS files, this uses $4017 to generate an IRQ for testing to see how a positive result should look. Gives a count of $3B with the corresponding timing logs.
Anyhow, was just trying to rule out the idea that maybe there's extra IRQs flying around shortly after boot, either normally or because of the FDSStick, etc. but I don't think it's the case based on this result. All quiet here. (It's possible I could have botched the test, though.)
Also this code has a simple BYPASS constant at the top of example.s that lets you quickly turn the license bypass on and off, as well as a tileset with ASCII characters and a row of hex numbers etc. in case that's useful.
I checked my code again for a half hour this morning and made some minor tweaks, but I would expect it will still probably generate a black screen.
I attached the source code as well, if you have a few minutes to take a look, maybe you'll notice something really obvious that I'm doing wrong.
Same as before: a single heart.
I'll take a look at the code a little later.
I'm actually in the process of rewriting the whole thing using the test you made instead, much easier to understand with actual numbers on the screen.
Also improving a lot of stuff code-wise - slowly getting the hang of how to deal with IRQs in general, using macros and etc.
Also trying to assume as little as possible about the FDS' behavior in each test - e.g the last test you ran implies that writing $02 to $4022 when the reload value is set to 0 actually triggers an IRQ. If true, this invalidates some of the other tests.
I'll probably be done with that at some point tonight, so you might as well ignore the old code for now.
Ok, here we go again.
Completely re-written from scratch based on your test (thanks for that, btw!), with an output that's actually readable.
I've tried this on virtually all the emulators I had (FCEUX, Mesen, Nestopia, Nintendulator, RockNES, Nintaco, puNES, VirtuaNES) and it displays the result screen properly in all cases - so at least that's a start.
First column is test #, 2nd is pass/fail (X or O), 3rd is the number of irqs triggered during the test, the rest is a short description of what the test is trying to validate.
Attachment:
output.png [ 22.85 KiB | Viewed 4421 times ]
The code is included along with the FDS file.
Edit: Pass/Fail column is obviously not really relevant until the test is validated on an FDS and updated to match.
Any chance of testing Disk IRQs?
V6 result::
Code:
01 O 00
02 O 01
03 X 01
04 O 02
05 O 00
06 O 00
07 O 20
08 O 20
09 O 01
0A O 20
0B O 01
0C O 20
0D O 01
0E O 00
0F O 01
10 O 00
11 O 01
12 O 04
13 O 04
Did not see any power-on variations over ~15 tests.
Awesome - finally some conclusive results! Thanks for taking the time to do all these tests!
Test 3 failing in this case is fine, since it was just me assuming the FDS' behavior.
Apparently writing $02 to $4022 will trigger an IRQ immediately if the reload value is $00 - so I guess the IRQ triggers whenever the timer is at 0, rather than when it reaches 0. One thing left to test might be checking if turning on the irq repeat flag when the reload is 0 makes the irq fire in an infinite loop (I'm assuming it would)
@Zepper I could be wrong, but I'm under the impression the FDSStick(?) is probably emulation the disk drive and its IRQs? (i.e the disk irqs probably can't be properly validated without actually writing the test rom to a FDS disk and loading that?)
I only have a vague understanding of how the disk loading & its irqs work, to be honest, so I probably couldn't write a test for it even if I wanted to.
I don't have a disk drive. (I used to, but I couldn't get it to work, so I gave it to someone else.)
I don't know much about the hardware, though. Does the disk drive itself generate IRQs or is that done internally? Is there actually any feasible way to differentiate FDSstick from a real disk?
The Disk Drive cable itself is just three digital signals from the base station (written to via $4025), three signals from the base station (read via $4032), the battery voltage (read via $4033), the serial transmit and receive streams, ground, +5V, and the twelfth pin is unused.
No, the drive itself doesn't generate IRQs. There should be no difference between using a FDSStick and a real drive for IRQ testing. You MIGHT want to load only your test rom onto fdsstick, removing any other games. This will bypass the boot menu and load your rom directly.
I'll leave
this here, it seems relevant.
I didn't realize there was a bootloader now! I was still using the original release.
I'll have to try that out.
I forgot about that thing with $4023, so my "spurious IRQ" test wouldn't have picked up on that since it doesn't mess with $4023. I should try again with it intentionally cleared...
Hm! Very curious. I tried modifying my IRQ logging program, in particular to skip calling the BIOS reset to start the program (which normally writes to $4023). I found if I wrote $00 or $83 to $4023 once, nothing unusual happened, but if I skipped writing to it altogether, I got a variety of things happening (sirq2_no_reset.fds):
1. Loads and runs normally.
2. Loads and runs, but disk activity never seems to stop. No IRQ, but the FDSstick keeps turning on the green light over and over. (Or in the plugged into USB mode, the progress bar keeps repeating from 0 to 100%.)
3. Hangs on black screen, disk activity never stops.
One time I even caught one IRQ in the log but I accidentally reset and I haven't been able to reproduce it. Not sure if I caused it accidentally by pressing buttons or moving my Famicom around too much etc.
So, at least one write to $4023 after the license bypass NMI seems to be needed to reliably stop the disk access, but sometimes it stopped normally anyway? I didn't managed to get any good leads on whether this can make an IRQ...
Anyhow, sorry this post isn't very good information but it feels like the function of $4023 is more complicated than just disable/enable? Does the BIOS really only write it twice on reset? And even then it makes a point of writing $00 before $83... is that more like a reset sequence?
I got identical results with FdsIrqTestsV6 as Rainwarrior as usual. But I only tested once, power cycling made the disk image corrupt somehow and it wouldn't start anymore (error 22).
I should mention that I also haven't updated my FDSStick so it's also not using the bootloader. Good to know that you can get around the bootloader by only writing one disk image though, I guess it's time for me to update it.
rainwarrior wrote:
(The alignment of those diagrams is off, for me, I think that heart isn't properly monospaced, but it should be clear from context where the columns lie.)
Yeah sorry about that, I failed to produce monospaced hearts somehow, lacking love I guess.
That could actually explain the difference with the old version of the test - each test writes $83 to $4023 before starting to reset any changes I make to the disk enabled register in some of the tests. Maybe that's why this one doesn't freeze up - the I flag doesn't get cleared until after that $83 write, so any disk irqs would essentially be ignored.
I made one final version to fix the expected result for the failed test, and add 2 more tests related to the behavior when the reload value is 0. I'm expecting these to pass on the FDS - if they do, this will probably be the last version of this for now. Disk IRQs can be in their own separate test, if I ever get around to looking at those.
I'll try to update the FDS page on the wiki with the information that was confirmed by these tests once I get a chance.
Care to explain each test with a "X", please?
Code:
01 O 00
02 O 01
03 O 01
04 O 02
05 O 00
06 O 00
07 O 20
08 O 20
09 O 01
0A O 20
0B O 01
0C O 20
0D O 01
0E O 00
0F O 01
10 O 00
11 O 01
12 O 04
13 O 04
14 O 04
15 O 40
I did a few power tests to see if there were variations (didn't see any) but a strange thing, though: after running sometimes a red light comes on for the FDSStick and never shuts off. If I power cycle while this is happening I think I end up corrupting the disk sometimes, and get an "err 32" trying to load after that.
rainwarrior wrote:
I did a few power tests to see if there were variations (didn't see any) but a strange thing, though: after running sometimes a red light comes on for the FDSStick and never shuts off. If I power cycle while this is happening I think I end up corrupting the disk sometimes, and get an "err 32" trying to load after that.
That sounds oddly similar to what Pokun mentioned, too. But I can't really see how the test could be causing it - it does absolutely nothing after displaying the results. Maybe a bug with the FDSStick itself?
Zepper wrote:
Care to explain each test with a "X", please?
All 3 should be caused by essentially the same thing: unlike what the wiki implies, the FDS's irq triggers whenever the counter is at 0 - not just when it reaches 0. So setting reload value to 0 and writing to $4022 to start the IRQ will trigger one immediately. If the repeat flag is enabled, this will cause a never-ending loop of IRQs.
I just removed a check of the irq latch value on 4022 write (non-zero only). I got a pass in all tests.
Sour wrote:
rainwarrior wrote:
I did a few power tests to see if there were variations (didn't see any) but a strange thing, though: after running sometimes a red light comes on for the FDSStick and never shuts off. If I power cycle while this is happening I think I end up corrupting the disk sometimes, and get an "err 32" trying to load after that.
That sounds oddly similar to what Pokun mentioned, too. But I can't really see how the test could be causing it - it does absolutely nothing after displaying the results. Maybe a bug with the FDSStick itself?
I feel like writing repeatedly to $4023 has consequences for disk activity, like it's causing the RAM adapter to send signals to the drive in some way. Maybe not important in terms of nailing this IRQ behaviour down but relevant to disk behaviour? It's weird how inconsistent it is, though.
Trying to check what the corruption was, I tried to read the "corrupted" disk back using the FDSStick program, and it was only 16 bytes long. (FDS,$1A header + 12 x $00) So... that's strange. Maybe it's just from powering off while it's trying to write?
I don't know what the held red light on the FDSstick means. Actively writing? Usually it turns on whenever I press the button, and the green one turns on any time the disk is being read, I think. (Similarly on my other test a few posts back, I'd get a repeating held green light on that one where it just never stops reading?
I do notice that in my example I zeroed out RAM, even though I was masking the value from $FA ($4025 write mirror) when applying mirroring to $4025. Maybe this put the disk into write mode? (There's also bit 5 that the wiki says "always set to 1", which is a direction this violates but I don't know if that's meaningful.) The default value for $FA should be $2E, which is the last thing the BIOS set it to on reset.
I should fix my example not to clobber those BIOS variables. I thought I tried to avoid that, but I missed the ZP ones.
Yeah, I patched V7 to fix that write to $4025 and now there's no more "weird" behaviour from the FDSstick. I can power cycle it with no problems at all.
So, yeah, I think the disk activity weirdness was my fault, a bug in my example (now fixed). Sorry.
I still think weird stuff can happen with the drive when writing to $4023, but seems well behaved/quiet as long as $4025 is properly set back to $2E beforehand? Anyhow, probably not relevant to the IRQ testing.
I also tried patching V5 to see if this affected that it hangs with only 1 heart displayed, but it's the same, so at least THAT wasn't my fault.
I guess it didn't like write mode being turned on? Odd that this would matter since it also meant the motor was turned off - hard to see how the FDS could corrupt a disk while the motor is disabled..
I'm guessing there is probably a reason for the BIOS to be writing $83 to $4023 instead of $03, but there is no mention of bit 7 in $4023 anywhere, from what I can see.
I updated the wiki with the information that was confirmed from these IRQ tests.
I might try writing another set of tests for the drive itself (though that will be trickier I'd imagine) - it would be nice to get a solid understanding of all the flags in in $4030/$4032 as well as the behavior of the disk IRQs.
I'm guessing the actual timing of the disk read/write operations can't really be tested with the FDSStick, though?
I guess there is still a possibility that the FDSStick behaves differently from the real disk drive and ignores the motor state. Maybe Loopy could answer that.
I tried googling in Japanese for more information about $4023 but found nothing that tells us more than the wiki or Enri. I guess information of the FDS is really scarce overall.
Hi all, I am trying to get these tests to work on BizHawk. The first problem I ran into is that the .FDS file indicates that there are 6 files on the disk, but looking over the file in hex editor I only see files 0-4. (Also, two files are both named FILE2, but that's not relevent to anything.)
I added in a blank file 5 to get it to run, but then it just repeatedly fires IRQ's and doesn't do anything else.
Am I missing something here?
Alyosha_TAS wrote:
Hi all, I am trying to get these tests to work on BizHawk. The first problem I ran into is that the .FDS file indicates that there are 6 files on the disk, but looking over the file in hex editor I only see files 0-4. (Also, two files are both named FILE2, but that's not relevent to anything.)
The high file count is intentional, used to skip the BIOS' license screen. The technique is described here:
http://forums.nesdev.com/viewtopic.php?p=194826#p194826The extra FILE2 is just a typo, should have been FILE1. (I need to fix that in my example template...)
You shouldn't need to add an extra file to get it to run... but a modified or high level replacement for the BIOS might break the license-skip technique?
Ah ok thanks for the info.
I went back and tried V3 which still had the copyright screen and I still just get a blank screen, so it looks like I have a bit of work to do here.
EDIT: Actually that wasn't so bad, got everything working.
Thanks for the valuable research Sour, rainwarrior, et al. !
Thanks for posting this up Sour! I would like to try to implement this fix into nestopia as well. I am taking the hot spot snippet from the Nestopia plus! SVN here. This was the last commit which fixed the freeze in Lutter but now makes the game putter have no sound.
Code:
bool enabled = (data & 0x02) == 0x02;
bool reload = (data & 0x01) == 0x01;
if (enabled && !reload)
{
unit.timer.latch = 0;
//ClearIRQ();
}
if (!unit.status)
{
//unit.timer.latch = 0;
ClearIRQ();
}
With this current code.
Putt Putt golf has NO sound but
Druid works as expected
Lutter does not freeze when starting a new game
Kaettekita Mario Bros works as expected on ALL 3 loading screens.
Anyone see anything I might can try?
Also the FDS game Aspic-Majaou no Noroi has issues sometimes when loading side b the system is unresponsive. IS this issue related to this?
After looking through the changelogs I found this:
"More accurate FDS disk drive emulation. Fixes "Aspic-Majaou no Noroi", But Apparently this got borked again somehow.
Anyways, this is awesome work guys. Hopefully this is fix of the trivial matter.
It's hard for me to get a screenshot so i will post the results. I ran the V7 FDS test against the FDS fixes from Nestopia plus! and got these results:
01 0
02 0
03 X
04 X
05 X
06 X
07 0
08 0
09 0
0A X
0B X
0C O
0D X
OE X
0F O
10 O
11 X
12 X
13 O
14 O
15 X
Can someone help me decipher what exactly is the issue. X meaning fail i am assuming right?
Nestopia Plus!Is dead, please use Nestopia UE or Mesen!
Attachment:
2017-10-28_10-28-09.jpg [ 115.17 KiB | Viewed 4451 times ]
Zxbdragon, can you share these fixes please? If Nestopia plus! is dead, then how do you explain everything passing on your build? WTF.
The text next to each test is essentially a summary of what the emulator should do.
As far as I remember:
03 Starting irq counter when reload value is 0 should still cause an irq
04 The irq reload value should never get reset (by anything other than $4020/$4021 writes)
05 Disabling disk registers while waiting for an irq should cancel that irq (it should never be triggered)
06 Starting an irq when disk registers are disabled should be impossible
0A Writing to $4022 with bit 1 set ($02) should not acknowledge the irq
0B Writing to $4023 with bit 0 set ($01) should not acknowledge the irq
0D Writing to $4022 to start the irq counter while the irq counter was already running resets the counter and delays the irq.
0E Writing to $4022 to start an irq while disk regs are disabled, and then enabling disk registers should not cause an irq
11 Writing $00 to $4022 should not reset the irq reload value
12 Writing $02 to $4022 4 times in a row (with a small delay between each write) when reload value is 0 should cause 4 irqs
15 Starting the irq counter with the repeat flag & a reload value of 0 should cause an infinite never-ending loop of IRQs
Some of these tests are a bit redundant since I was trying to test for every possible edge case I could think of.
Thank you for the clarification Sour. It's a little confusing but i see someone has it working in Nestopia.
Obviously ZxbDragon wants to throw it in my face that he has it working in his private modified build of Nestopia plus! so maybe he can help share this information, since he shared his other FDS fixes. So what do you say dragon, do you mind sharing your findings please? Since you already obviously have this working.
*Spitfire_NES* wrote:
Zxbdragon, can you share these fixes please? If Nestopia plus! is dead, then how do you explain everything passing on your build? WTF.
I not fixed! this test code,I didn't save on the computer~! Wait UE solution
zxbdragon wrote:
*Spitfire_NES* wrote:
Zxbdragon, can you share these fixes please? If Nestopia plus! is dead, then how do you explain everything passing on your build? WTF.
I not fixed! this test code,I didn't save on the computer~! Wait UE solution
Experimental or not, can you post this please here, so it can be tested? Makes no sense, this would help Rdanbrook as well. If it passes all the tests, then it safe to assume everything is fixed.
@Sour i will not derail this thread any longer. Apologies.