Castlevania IIIe issues

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Castlevania IIIe issues
by on (#976)
I'm having a bit of trouble getting CV3 working. Currently, I know of two problems:

1. The intro switches CHR pages too early. i.e. it switches to the character pages for the next screen before it's finished with the current one. I suspect this is IRQ related, but I'm not quite clear on when the IRQ triggers (it says based on scanline, but at what point in the scanline? And is it scanlines since the value is set?)

2. In the first level, the vertical scrolling portion is messed up. It scrolls by tile instead of by pixel. This one, I'm clueless about.

Anyone happen to know the answers to any of these questions, or where to look?


Thanks,


Josh

by on (#977)
Tell me if you're trying to emulate the japanese version OR the american version... :)

I bet the USA version. This mapper might be 'a pain in the neck' to get it working correctly. Personally, I gave up, even with preliminary support... :(

by on (#978)
Ah, I typed "IIIe" in the title but not in the text...yeah, it's the MMC5 version, and I'm only currently interested in emulating the MMC5 as far as necessary to get Castlevania working. So no ExRam, etc. There's definitely SOMETHING wrong with my IRQ emulation, I've fixed part of that problem, but not all of it yet.


The vertical scrolling, though, I have no idea.

by on (#979)
Is there a value written to the MMC5 registers during the vertical scrolling parts that parallels what you think the fine scroll should be doing? It's possible that even without EXRAM, the MMC5 is interfering in something screen related.

by on (#982)
Hey Drillian, long time no see ya. Hopefully this will help you as much as it has helped me:

http://tripoint.org/kevtris/mappers/incoming/mmc5.txt

by on (#985)
Hyde: Yeah, that's what happens when real life catches up to me. I have the tendency to disappear for long periods of time. And I finally solved the Battletoads problem (though I am not entirely sure what fixed it, it's fixed and that's what matters :D )

Thanks to all of you for the help! Got it working really damned close to the real thing :) Well, at least Castlevania. Every other MMC5 game is going to be broken as all hell. But right now, I don't give a shit.

by on (#986)
Okay, for starters, never accidentally post as a guest. Because when you type something that you want to change "i.e. 'I don't give a shit,'" it's not changeable.

Secondly, yeah, that was me :)

by on (#994)
Anonymous wrote:
And I finally solved the Battletoads problem (though I am not entirely sure what fixed it, it's fixed and that's what matters :D )


Turns out all you have to do is "add" a few cycles between the time you set the VBlank and execute an NMI. I believe you also have to update the V counters on cycle 252 (rather than on cycle 256) to get it working right.

by on (#995)
...:|
You say before pixel 256, but I still can't understand (err... hi Anes!) about how to avoid the 1-pixel line distortion on screen... if my explaination makes any sense..? :P

by on (#999)
Not quite sure what you mean, Fx3. Hyde's referring to my comment about Battletoads, where level 2 would lock up if the timing were off. He'd been helping me try to solve it back on the old boards.

Yeah, I did change the V counters to cycle 251 to get it working, I remember now (it's been a while). But if I change it to 252 right now, it'll lock up when I'm almost through the level (like, right at the end it locks). Oh well, 251 doesn't seem to be hurting anything (though I'm sure it is, somewhere).

by on (#1002)
Fx3 wrote:
...:|
You say before pixel 256, but I still can't understand (err... hi Anes!) about how to avoid the 1-pixel line distortion on screen... if my explaination makes any sense..? :P


Dude, it's like macumba: you either believe that it works or that it does not... And no, I can't really understand what you are trying to say :D

by on (#1005)
I don't believe in 'macumba'... :P

When the scroll regs are refreshed, don't you do "ppu_refresh += 0x1000" (meaning the fine-Y scroll)? Is this is done before pixel 256, a 1-line distortion will appear. I might post a screenshot of what I mean.

Image Image

In fact, I render the screen by taking the scroll regs immediately.

by on (#1006)
I do the following in my emu:

- Increase X scroll every 4th cycle (4, 12, 20, 28, etc)
- Increase Y scroll on cycle 252
- Reset X scroll (LoopyV = (LoopyV & 0x7BE0) | (LoopyT & 0x041F); ) on cycle 256

That with the delay after the 2002.7 flag is raised before an NMI is triggered... and Battletoads runs wonderfully. No distortion in any games.. everything works great.


If you're having distortion troubles, Fx3, it might be because you're not doing the pixel pipeline properly? Remember that images are loaded 9-16 cycles before they're actually drawn to the screen. So changing scroll values on 252 changes the scroll -after- all the tiles have been loaded... the remaining pixels being drawn to the screen on the scanline are already in memory.

by on (#1010)
It's going off-topic... but anyways... :D

Okay, but one more thing... Does Rad Racer 2 work with no glitches at right of screen?

by on (#1011)
I see glitches in Rad Racer (1) when you go off to the left in my emulator, but nothing in RR2.

And there's no harm in this going off topic, I've solved my problems (thanks again for the help!) :)

by on (#1012)
I see Rad Racer 2 having about a 20 pixel distortion on the right side of the scanline where the horizon meets the road... but as far as I can tell that's a programming issue in the game, not an emulation issue. The glitching is not at all similar to the screens you posted... nothing like that is going on in RR2.

The glitching in Rad Racer 1 that Drilian mentioned when you go to the left side of the road is a similar problem.

Unfortunately, I don't own either of these carts, so I can't see how things look on the real thing.

edit: took a snapshot of what I mean

http://hypher.net/disch/rr2.png

by on (#1013)
I get the same results in my emulator.

Fx3: Your method of emulating the PPU must be different from what is described in Brad Taylor's doc then.

by on (#1014)
Ah, I wasn't looking far enough down the road in Rad Racer 2 :)

by on (#1015)
I just use tilecaching, instead of a tedious 2-byte fetching. This isn't real hardware for such nostalgic things. :)

by on (#1016)
Disch wrote:
- Increase X scroll every 4th cycle (4, 12, 20, 28, etc)


Can't you handle offset = x_scroll + (ppupixel >> 2) ?

by on (#1017)
I load and render tiles ahead of time to a temporary buffer... which I later render to the screen. I keep something like:

u8 nBGRender[256 + 16];
u8 nSprRender[256 + 8];

every 0th cycle on the scanline (0, 8, 16, 24, etc) I load and draw a tile and attributes to nBGRender. Later on the 4th cycle (4, 12, etc) I increment the counter. I do a similar thing with sprites... but I also store a special flag (0x80) if the sprite has low priority... and another (0x40) if it's sprite 0 (for sprite 0 hit detection)

When actually rendering pixels to the screen... I do something like:

Code:
a = nBGRender[ nHScroll + nScanlineCycle ];
b = nSprRender[ nScanlineCycle ];

if(nScanlineCycle < nBGClip)  a = 0;
if(nScanlineCycle < nSprClip)  b = 0;

if(b & 0x80)  // render BG pixel if 'a' is nonzero... else render sprite pixel
else             // render Sprite pixel if 'b' is nonzero... else render BG pixel

if(a && (b & 0x40))  // raise Sprite 0 hit flag


This makes BG and Sprite clipping/disabling a breeze -- nBGClip/nSprClip are always either 0 (no clipping), 8 (clipping), or 256 (BG or Sprite disabled). Also handles the pipeline where there's a delay between when tiles are loaded and when they're drawn... plus it makes sprite 0 detection very simple.

Quote:
Can't you handle offset = x_scroll + (ppupixel >> 2)


Why bother? I'd rather update and use the PPU address (LoopyV) in realtime... since it theoretically could be altered by the game midscanline through $2006 or something.

by on (#3102)
By the way, if anyone cares anymore, Castlevania 3 doesn't glich around while being emulated with Nintendulator :P .

by on (#3106)
I can guarantee that Castlevania 3 - Dracula's Curse (E) does glich while scrooling vertically in Nintendulator as well than on the real hardware (many emus doesn't show the glitch exacly how it is on the real hardwar), however I don't know if the US version has gliches or not.

by on (#3109)
Well, It didn't for me, It might have a little, but not like it did playing it on Nesticle. it was barable. :)

by on (#3110)
Never compromise accuracy in an attempt to be appreciative.

by on (#3111)
Nesticle isn't a reference in accuracy department, you know. However, when I run MegaMan 6 on my PAL NES, it doen't look like when you switch to PAL mode trough Nintendulator, but I got an illegal copy from my brother-in-law, so maybe the code is different to be compatible with PAL (because the NTSC one would glitch).

by on (#3113)
I hate running things on PAL, it sucks. But yeah I wish Nesticle was an accurate emulator, because I LOVE the setup in Nesticle, and I really like the "make your own window size" thing they have. I only use Nesticle to play Final Fantasy 3, because it works just fine in Nesticle. Well, I don't know why i'm talking about that, so I'm going to stop.

by on (#3114)
I think the worst thing about Nesticle is that, due to its extreme popularity, people would hack ROMs to run correctly in it, and thus ruin them when more accurate emulators eventually started coming out. I can't remember any game specifically, but I know there were changes made to ROMs for the express purpose of making them run in Nesticle, which wasn't accurate enough to handle them as-is.

Thus, there are now hacked ROMs floating around that don't run right in the newer crop of emulators, making them seem broken, when it's really the ROM that's broken.

and Final Fantasy 3 works in many emulators that are miles-and-above better than Nesticle. :)

by on (#3116)
I know, but for some reason, I have way more fun playing it in Nesticle than in emus like Nintendulator. The thing I hate about Nintendulator is that you can't have a full window with black borders and a square screen. Ya know what I'm saying? And I HATE that you can't change the D-Pad controls on Jnes, otherwise I think I'd use that more often. I use it all the time for testing my ROMs, but I only use it for testing. Have you noticed that it's really not a good idea to write code where you incbin a .nam file? the top half usually appears on the bottom of the screen, wilst the bottom appears on the top. The only emu I know that keeps it centered is Jnes.

by on (#3118)
Celius wrote:
The only emu I know that keeps it centered is Jnes.


That probably means that Jnes is buggy, and that you should use a different emulator for testing.

by on (#3122)
Bregalad wrote:
I can guarantee that Castlevania 3 - Dracula's Curse (E) does glich while scrooling vertically in Nintendulator as well than on the real hardware (many emus doesn't show the glitch exacly how it is on the real hardwar), however I don't know if the US version has gliches or not.


You mean that background scanline flickering near the statusbar ? Any idea what causes this ?

by on (#3132)
I like using VirtuaNES myself, it has good graphical inferface, good sound interface, and is pretty much accurate, but not as accurate than Nintendulator or FCEUltra.

About CV3, I think this is there because of the NTSC->PAL transition, and because the programmers didn't know that it was possible to write to $2005 between two $2006 writes, there is 8 black scanlines below the status bar, and where the scroll is setup to a new value varies in this 8 pixels range.

by on (#3144)
[quote]I can guarantee that Castlevania 3 - Dracula's Curse (E) does glich while scrooling vertically in Nintendulator as well than on the real hardware (many emus doesn't show the glitch exacly how it is on the real hardwar), however I don't know if the US version has gliches or not.[/quote]

Interesting, because with the (U) version Nintendulator glitches incorrectly. The line seperating the status screen from the play screen should only flicker on the sides of the screen, not for the whole screen as Nintendulator does.

by on (#3164)
That flickering is most likely due to incorrect timing on VRAM address reloading; we need to get kevtris to test the exact timing on his 3-in-1 tester so we can solve this problem once and for all.

I know for a fact that my MMC5 IRQ timing is correct.

by on (#3281)
As I write this message, Kevin Horton is running the first of several PPU test programs on his 3-in-1 unit. This test will determine the exact point where the VRAM address latch is copied into the 'working' address register at the beginning of each frame (and will take quite a while to run, since it's testing every single cycle on the 'dummy' scanline). The test functions as such: set the PPU to start rendering at the 3rd nametable ($2800) with scroll X=0 and Y=0 and wait until just before the dummy scanline starts, then set Y-scroll to 128 at every possible point during the dummy scanline (starting at the very end, where it will have no effect) until the PPU starts rendering from 2A00 instead of 2800.

After I have some results, I'll write the next test to see when the horizontal scroll portion of the VRAM address is reloaded at the beginning of each scanline - set horizontal scroll to 0 at the beginning of the scanline, then set it to 128 near the beginning of HBLANK (starting after HBLANK, where it will have no effect, and moving to before HBLANK to see when it starts working).

by on (#3283)
Quietust wrote:
As I write this message, Kevin Horton is running the first of several PPU test programs on his 3-in-1 unit. This test will determine the exact point where the VRAM address latch is copied into the 'working' address register at the beginning of each frame (and will take quite a while to run, since it's testing every single cycle on the 'dummy' scanline).

There are 341 cycles on scanline -1. How does 341 cycles of a loop take "quite a while", especially given that sprite 0 overlap lets you automate the test cycle and print a number within 6 seconds?

by on (#3288)
The test was not running on a complete NES - it was running on a PIC microcontroller attached to an NES PPU, manually clocking it and watching the address bus and reading/writing its I/O port ($2000-$2007). The reason it took so long is because for every test (of which there were 1536 - 1364 for the scanline itself and a few others before and after), I had to wait for an NMI (cycle-exact) and the PIC is only capable of clocking the PPU at around 2.75MHz (as opposed to 21.47MHz) - add in the delays from dumping the address data over a slow serial connection, and it took nearly an hour to complete.

Now that I have results for the first test, I've discovered something rather peculiar: the PPU copies the VRAM address latch onto the 'working' VRAM address register during cycle 304 - that is, the 'nametable data' fetch cycle for the 7th sprite! It doesn't make much sense to me, but this is exactly what the test results indicate.

[edit]

Results are in for the second test. The PPU appears to reload the 'horizontal' portion of the VRAM address at cycle #257, the data fetch portion of the 'nametable' fetch for the first sprite. This is actually consistent with the addresses the PPU reads from for sprite 'nametable' and 'attribute' data.

Results for the 3rd (and final) test will be available when kevtris wakes up in the morning; after he ran the test and went to bed, I realized there was a significant bug in it.

[edit: fix description for cycle #257]

by on (#3298)
Thanks. Silly question: in your explanation, is the 1st cycle cycle 1 (1..341) or cycle 0 (0..340) ?

by on (#3302)
0..340, of course.

[edit]

The final test is complete: the VRAM address vertical scroll increment takes place at cycle #251 - that is, during the data fetch portion of the last tile's attribute data (cycle #250 is when it outputs the attribute address). This happens to be exactly the timing my emulator currently uses. Horizontal increments have also been verified to occur during the 4th cycle of each tile (again, during the data fetch portion of the attribute data); in addition, the very last tile on each scanline increments both the vertical AND horizontal offsets - evidently, this why the PPU needs to reset the horizontal offset later.