MEGA65 / mega65-core

MEGA65 FPGA core
Other
237 stars 84 forks source link

Sprite Y positions are off, depending on video standard and freezer usage #289

Open steph72 opened 3 years ago

steph72 commented 3 years ago

While experimenting with some old games in C64 mode I discovered that sometimes sprite positions are shifted up and down.

I wrote a little test program in BASIC 2 in order to reproduce the issue: spostest.zip

Here are the reproducible findings so far:

  1. Original PAL C64: sprtest01

  2. MEGA65, NTSC mode on powerup, directly booted into C64 mode with test disc image mounted as standard image: sprtest02

  3. MEGA65, PAL mode on powerup, directly booted into C64 mode with test disc image mounted as standard image: sprtest03

  4. MEGA65, PAL mode on powerup, directly booted into C64 mode with test disc image mounted as standard image, change to NTSC via freezer menu: sprtest04

  5. MEGA65, PAL mode on powerup, directly booted into C64 mode with test disc image mounted as standard image, change to NTSC via freezer menu, run test, change back to PAL via freezer, run test again: sprtest05

In my original experiments, I encountered worse deviations, but so far I haven't been able to reproduce them.

gardners commented 3 years ago

It looks like the NTSC sprite vertical positioning is out versus the character generator position. In mega65-tools/src/tests there is also vicii.prg that can be built that tests various things. Interestingly it doesn't pick up the problem you indicated, but does find another problem when I ran it in NTSC.

It would be a very good idea to expand on this, implementing the test you wrote, and attempt to document the problems, so that we can find and fix the root cause(s).

steph72 commented 3 years ago

It would be a very good idea to expand on this, implementing the test you wrote, and attempt to document the problems, so that we can find and fix the root cause(s).

I'd love to do that (as soon as my jtag adapter arrives)

gardners commented 3 years ago

Issue gladly assigned :)

Ben-401 commented 3 years ago

Hi, yes I confirm that my build also demonstrates collisions=255 when i mount and run the test program. Can we add that program to the repo somewhere? is in repo:test-procedures a good spot? And instead of checking in the binary, can we check in the source code for a basic program?

My build is BRANCH:138-hdmi-27, 20200826, 8A90709 (yes quite old i know). Using VGA on N4ddr, all DIPs off.

steph72 commented 3 years ago

@gardners I just checked my machine (preseries r2 board, 138-hdmi-audio-27-mhz, 20200917.07) with the vicii test program from mega65-tools/src/tests

To my great surprise, the existing test actually detects the error with my board:

vicii

This behavior is reproducible by

@Ben-401 Can you confirm the error using mega65-tools/src/tests/vicii.prg on your board, too?

I have the feeling that the error in Y positioning gets more pronounced the more the freezer is being used.

This is a photo of my own test program after applying the same procedure:

sprpos2

Notice how all sprites are being placed way too low on the screen – in fact almost completely covering the lower 'test frames', except one single line? This almost certainly corresponds to the $32-$1c=$16 pixels difference your test program is reporting.

(Since the existing test program picks up the error alright, I'll refrain from adding my own – redundant – tests, unless you see any use in it...)

gardners commented 3 years ago

The problem when switching PAL/NTSC in the freezer, is that it has to do some magic to do the switch, because the hotregs don't get triggered, because the flags are being changed in a frozen programme, not in a running one. Thus freezer.c modifies some VIC-IV registers, but clearly doesn't modify the sprite one.

See from about line 862 in freezer.c

I am putting a fix in there,

gardners commented 3 years ago

Build new FREEZE.M65 from the referenced commit, and it will hopefully fix the problem.

steph72 commented 3 years ago

@gardners with the new FREEZE.M65, the $16px problem after using the freezer is gone

But there's still an 2px offset in Y position when starting up in NTSC mode (not using the freezer) and running the test program:

2px

gardners commented 3 years ago

Try putting different values in $FFD3072 to find the value that is correct. Let me know the correct value, and I'll bake it in.

steph72 commented 3 years ago

For my r2 board, it's $18 in NTSC60 mode.

But once I've set $ffd3072 to $18 and then return to PAL mode via the freezer, there is a 1px error in the sprite's Y position which I can't correct because $ffd3072 already is on $00 with the 1px gap. It would need -$01 to correct for the gap.

gardners commented 3 years ago

ok, making a bitstream and updated freezer with $18 as the value.