Page 3 of 3

Re: VGA vs. NTSC timings are not giving the same desired output

Posted: Thu May 15, 2025 3:06 pm
by doslogo
Wavicle wrote: Thu May 15, 2025 7:37 am I still don't quite understand what is is that you are saying is wrong.
Scanline register in NTSC mode is not behaving like in the documentation. 240p is not interlaced. Adding +1 to the current scanline register for the next IRQ LINE interrupt shouldn't work since bit 0 is ignored, still every other frame it does work, and the other frame it does just the same as when adding +2 to the scanline register.
Wavicle wrote: Thu May 15, 2025 7:37 am The CPU and VERA run asynchronously to one another. If you are attempting to do scanline effects in both VGA and NTSC, you need to understand the timing differences between the two, and you need to understand that some things, like palette changes, happen while the current line is being scanned out, but changes to how the line is rendered will not be seen until the rendered line is being scanned out, which happens one line after the change is made.
I have known this for the last 6 months. I almost got VGA to work like I want. The issue will always be that when you get a chance to touch the VERA scroll registers, the current scanline is already well into the rendering of that scanline, but the next scanline will still have a chance to take effect, ONLY, there is very little time there as well. So many have said you need to make changes that will happen 2 scanlines later, only to realize that some scroll register Y for some layer will be updated the next scanline (+1) while scroll register X of that same layer will be updated the 'next next' scanline (+2).
Once I release my game, I will make sure that every hardware revision and MHz setting of the CPU (and 16-bit or 8-bit variant) will require backward compatibility with the timings I have magically dialed in (we are not talking about a few hours here, weeks of work, first in emulators just to fail on real hardware, then again on real hardware moving SD cards for hours on end). That's what the "compatibility with existing software" is all about, right? But I am giving the hardware team a chance to fix these issues talked about in this thread before committing to almost random undocumented or unproven behavior.

Back to the NTSC problem: I did some further testing by setting the start scanline to an odd value, and then EOR that with 1 every vblank to try to sync with the 60 Hz swapping of fields for 240p (I know, that shouldn't happen, that is interlaced behavior). I was unsuccessful, and it just looked the same as the screenshots above, flickering with one correct output, and one wrong, every frame.

Re: VGA vs. NTSC timings are not giving the same desired output

Posted: Thu May 15, 2025 3:18 pm
by DragWx
Are you moving the mouse cursor with a Kernal call, during your ISR? Kernal calls are too slow for that, and can change with updates, so you'd be better off moving the sprite yourself (sprite 0), directly. At least inside your ISR. That could be what was stretching your ISR to two scanlines instead of one.


Edit: To address something you said earlier, yes, if you want a raster effect on every scanline, it will consume 100% of the CPU. When you see fancy scanline effects on the SNES, it's the HDMA doing it. On the Amiga, it's the "Copper" doing it. Those are all automatic "DMA" style features that happen parallel to the CPU executing code.

There's no equivalent hardware on the X16, so we have to do it all manually with a good old-fashioned display kernel (code that is cycle-timed for synchronization). We also need to think about things like, if we're using the VIA to stream data to the FM chip, we have a whole new puzzle to figure out for making sure it doesn't interfere with any scanline IRQs we might also want.

So, you need to identify what you want the scanline IRQ for; if it's to create a 2-player split-screen, that's just one IRQ, and won't affect you very much. If it's to create advanced parallax backgrounds, like Sonic 1, 2, and 3 for Genesis, that's still only happening on a handful of split points, and not every single scanline. If you want something like Pole Position where the road is transformed by shifting every scanline, that's going to be expensive, but a game like Pole Position isn't computationally expensive, and you can limit how much of the screen is the road.

Re: VGA vs. NTSC timings are not giving the same desired output

Posted: Thu May 15, 2025 6:45 pm
by Wavicle
doslogo wrote: Thu May 15, 2025 3:06 pm Scanline register in NTSC mode is not behaving like in the documentation. 240p is not interlaced. Adding +1 to the current scanline register for the next IRQ LINE interrupt shouldn't work since bit 0 is ignored, still every other frame it does work, and the other frame it does just the same as when adding +2 to the scanline register.
It is still difficult to parse your meaning. Are you saying that if you set the line interrupt to line 150 you expect line interrupts to happen at 60Hz, but in 240P mode they are happening at 30Hz?
doslogo wrote: Thu May 15, 2025 3:06 pm I have known this for the last 6 months. I almost got VGA to work like I want. The issue will always be that when you get a chance to touch the VERA scroll registers, the current scanline is already well into the rendering of that scanline, but the next scanline will still have a chance to take effect, ONLY, there is very little time there as well. So many have said you need to make changes that will happen 2 scanlines later, only to realize that some scroll register Y for some layer will be updated the next scanline (+1) while scroll register X of that same layer will be updated the 'next next' scanline (+2).
You seem to be holding context in your head that you aren't expressing here. There are HSCROLL and VSCROLL registers, but you are using language "scroll register Y" and "scroll register X" which creates ambiguity as to whether you are using "scroll register Y" to mean "VSCROLL" or if it means "some arbitrary scroll register other than X". I need a bit more precision to investigate this.
doslogo wrote: Thu May 15, 2025 3:06 pm Once I release my game, I will make sure that every hardware revision and MHz setting of the CPU (and 16-bit or 8-bit variant) will require backward compatibility with the timings I have magically dialed in (we are not talking about a few hours here, weeks of work, first in emulators just to fail on real hardware, then again on real hardware moving SD cards for hours on end). That's what the "compatibility with existing software" is all about, right? But I am giving the hardware team a chance to fix these issues talked about in this thread before committing to almost random undocumented or unproven behavior.
If you need a fast path between your dev environment and the X16 hardware, you should consider getting a Calypso. I designed it to ease this exact pain point. If you need to swap CPUs to make sure your game works on both, I have a CPU Switcher for this as well.

I am the one who added 240P mode to VERA and also fixed many issues in composite mode related to timing and interrupts, but I did not write the documentation. If there is a bug in the design here, I'm probably the one who would fix it. I'm not going to be able to do so unless I understand the problem.

Re: VGA vs. NTSC timings are not giving the same desired output

Posted: Thu May 15, 2025 7:08 pm
by doslogo
Wavicle wrote: Thu May 15, 2025 6:45 pm I am the one who added 240P mode to VERA
Just a short reply here, I am sorry for being rude before. I'll respond to the rest later.

I am constantly coming up with new ideas to test VERA, and many of them prove that there might not be a bug.

Re: VGA vs. NTSC timings are not giving the same desired output

Posted: Fri May 16, 2025 12:57 am
by MooingLemur
Could the issue be simply that on VGA, you will get 480 visible lines (525 total lines) in 1 frame, and on NTSC and RGB, you get 525 total lines (or 526 in 240p) in two frames. Therefore, each scanline scans out at (approximately) half the speed?

Therefore 63 NOPs would only consume half a line, as expected.

Re: VGA vs. NTSC timings are not giving the same desired output

Posted: Fri May 16, 2025 2:16 pm
by doslogo
Wavicle wrote: Thu May 15, 2025 6:45 pm You seem to be holding context in your head that you aren't expressing here. There are HSCROLL and VSCROLL registers, but you are using language "scroll register Y" and "scroll register X" which creates ambiguity as to whether you are using "scroll register Y" to mean "VSCROLL" or if it means "some arbitrary scroll register other than X". I need a bit more precision to investigate this.
What I mean when I say any scroll Y register, I mean them all:

L0_VSCROLL_L also called V-Scroll (7:0), and L0_VSCROLL_H also called V-Scroll (11:8),
And L1_VSCROLL_L also called V-Scroll (7:0), and finally L1_VSCROLL_H also called V-Scroll (11:8).


Once you get control of execution from an IRQLINE_L (Write only) also called IRQ line (7:0) and IEN scan line (8), the raster beam of the CRT has already started drawing for that requested scanline. That is understandable since the IRQ vector is in ROM code, and for some design reason, the LINE interrupt is fired at the beginning of the active display instead of at the end.
But now there is the problem of all of those registers I said in the smaller size above, as you get control of your interrupt, and must first save all the states of VERA, and then check for what interrupt you are servicing, changing the registers will affect the next scanline, or the scanline next to the next scanline? DC_VSCALE also known as Active Display V-Scale is set to $40, so sometimes half of the scaled pixels are cut in half by the scroll change (which should be impossible), which is not the same for horizontal scrolling when DC_HSCALE also known as Active Display H-Scale is set to $40.

What all this means is that whenever CPU speed is increased in the future, or cycles changes because of an upgraded CPU type (the 16-bit variant running in its 8-bit mode), all the games that rely on tight timings of LINE interrupts will fail. And when HDMI is added, will that also affect timings like how NTSC is different from VGA?

The demo on the SD card coming with the computer called "SONIC.PRG" has been updated to work with the newer VERA timings, but it fails in NTSC, and you can see errors in the timings in VGA (see my first post screenshots in this thread). This demo was one of the first demos written for this computer, and it had to be maintained by someone every time the computer changed. If downloaded from the internet, an older broken version will most likely fall into your hands. I am trying to not get that some situation with my game.

Oh, and "DEMOS/SONIC.PRG" only changes L0_HSCROLL_L also known as H-Scroll (7:0) + (8).

Official documentation states:
Note that VERA renders lines ahead of scanout such that line 1 is being rendered while line 0 is being scanned
out


So in VGA, with DC_HSCALE and DC_VSCALE set to $40, setting L0_HSCROLL_L while SCANLINE_L (Read only) is $02 and IEN scan line (8) is $0 will guarantee that the change happens when SCANLINE_L (Read only) is $03.

Remember that scale is in effect, so one unit of scroll is 2 pixels! So we are now scrolling on half a pixel, which won't be noticeable until SCANLINE_L (Read only) is $04. Great, no harm. But what about L0_VSCROLL_L? Well, that one will cut the pixel in half. Timings and order of these registers are very tricky and precise to get the output desired. By that information alone, I would say L0_HSCROLL_L has priority over L0_VSCROLL_L because of discrimination: My game scrolls horizontal so it is more important than yours that scrolls vertically. But the truth is most likely that there are no official software yet that uses vertical scrolling, so I need to get my game out there ASAP. Once I do, I believe I will be the one who locks these issues in place rather than helping to fix them. That's why I am doing this thread now.

It might be hard to see how you can scroll something vertically by using a LINE interrupt. But this is something many games do to make 3D effects, by scrolling to hide every other scanline, or duplicate them.

MooingLemur wrote: Fri May 16, 2025 12:57 am Could the issue be simply that on VGA, you will get 480 visible lines (525 total lines) in 1 frame, and on NTSC and RGB, you get 525 total lines (or 526 in 240p) in two frames. Therefore, each scanline scans out at (approximately) half the speed?

Therefore 63 NOPs would only consume half a line, as expected.
Yea, it was the case combined with the fact that VGA scans out 2 scanlines and NTSC skips one scanline because of progressive mode. So even if something takes longer to do, the rules are so different that you can't use the same code for both modes. VGA gets the color change on an odd scanline (which looks bad if you notice it), and NTSC gets the color change in the middle of the screen with the jitter and 16-bit writes mismatch colors all visible. For scroll register though, many games would benefit from a well defined behavior when writing to the registers that gets latched at some point during the scanout.

Once NTSC 240p is done with a scanline, it doesn't just wait for a blank scanline but rather start a new one. In VGA, once you have reached the first scanline, you have one more scanline to do, and that gives time to get out of the interrupt and continue the game for a few cycles before being interrupted again.

All of my game logic is done outside of vblank, and I am surprised how powerful the 65C02 is at doing extreme stuff that 8-bit computers shouldn't be able to do, all of that while still being interrupted so often just to set a few scroll registers and update the backdrop (I would say over 50% of the frame time is interrupted code and not game code). But if you WAI for the next scanline inside the LINE interrupt code, then you have to run all the game logic inside vblank, and that is truly a waste and bad game design in general.

If I had designed this computer (which I am not qualified to do), I would have put aside an area in VRAM for line scroll tables (that could be turned on or off when needed), and have VERA fetch those on new scanlines automatically. It would have been like the SNES's HDMA. That wouldn't have helped with the color change though, but many developers wouldn't even think about extending colors beyond the 256 limit on a frame. I just want the color change because it is cooooool.

Re: VGA vs. NTSC timings are not giving the same desired output

Posted: Fri May 16, 2025 3:20 pm
by DragWx
NES developers also needed to deal with timing differences between NTSC and PAL units, and some developers would auto-detect and adjust the delays automatically, using variable-length delays and tables. The same could be used on the X16 depending on whether VGA or NTSC mode is active.

I understand why the IRQ happens at the start of the active portion of the scanline: the same timing signal that drives the IRQ is also used to tell the composer to start outputting pixels.

Re: VGA vs. NTSC timings are not giving the same desired output

Posted: Sat May 17, 2025 11:59 am
by doslogo
DragWx wrote: Fri May 16, 2025 3:20 pm NES developers also needed to deal with timing differences between NTSC and PAL units, and some developers would auto-detect and adjust the delays automatically, using variable-length delays and tables. The same could be used on the X16 depending on whether VGA or NTSC mode is active.

I understand why the IRQ happens at the start of the active portion of the scanline: the same timing signal that drives the IRQ is also used to tell the composer to start outputting pixels.
Same with Sega Genesis, where you can't even change the palette mid-frame without glitchy color dots appearing on the screen. PAL and NTSC verisons of games (region locked or physics changes to adapt to the frame rate difference). All systems have their good sides and bad sides.
I was trying to use the VIA timer for such a variable delay, but I can't find a way to make it work reliable, and adding branches at already critical timed code is really difficult as well. There is always the multi-version approach, but that would not help Commander X16 much and confuse users more.

What I am most worried about is the upcoming change of the Commander X16, where HDMI is added. I have contingency plans for all issues except for when something is always changing.

The IRQ should have been designed to be usable for its purpose (raster effects) rather than a bi-product of something else. I have to say though, seeing all those mouse cursor trails forming because the scanline duplication is extremely powerful for any computer to accomplish. I have never seen any game console use such an effect on sprites, only background layers. I even thought that was impossible. If the computer could allow for double the sprites on a scanline, I would have used sprites to do the palette effects instead of the backdrop since sprites would lock in place (latch) for the next scanline. But, once you fill up 5 or so 64 wide sprites on a scanline, all the other sprites needed for the game will start to disappear.

Re: VGA vs. NTSC timings are not giving the same desired output

Posted: Sat May 17, 2025 5:16 pm
by DragWx
You don't need to complicate things with the VIA:

Code: Select all

    ldx zp_MyDelaySetting ; 3
delayLoop:
    dex                   ; 2
    bne delayLoop         ; 3
    .assert delayLoop / $100 = * / $100, error, "delayLoop crosses a page boundary!"
    ; -1 for branch not taken on final loop
The above code will delay for (2 + [zp_MyDelaySetting * 5]) cycles. On program start, check the VERA for which mode it's in, then load an appropriate value into zp_MyDelaySetting. The .assert warns you when the branch crosses a page boundary (would add an unexpected +1 cycle to each loop), so there shouldn't be anything unpredictable about this.


As a point of interest, the VERA's method of rendering pixels to a line buffer (instead of straight to the screen like the NES) is a strategy used by several arcade games, like anything that runs on Galaxian hardware for example.