BASIC65 proposal: how abouy a raster sync command?

Es gibt 61 Antworten in diesem Thema, welches 9.454 mal aufgerufen wurde. Der letzte Beitrag (12. Juni 2022 um 15:07) ist von Snoopy.

  • Well, it would be a good and more stable alternative to SLEEPing, e.g. in a game's main loop. Also, it would be possible to create flicker-free games (without screen tearing) when e.g. syncing for line 0 or something inside the upper or lower border.

    I think the reason why your program fails to catch the line is because you try to catch EXACTLY the line. This can even fail on the C64 in assembly, if too many things are going on and you might just miss the line at exactly the desired time. But if it was a real BASIC command, it would make sure to use real interrupts or something like that, and it would be much more reliable.

    If you would change the program to check a range, e.g. not one specific line but something like +/- a few lines, it would probably work in every case. But it would still be just a workaround for an otherwise nice BASIC command.

    - neue Spiele für den C64 -
    Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.

  • Try the following in your program:

    Code
    200 L=FNRL(0): IF L<R-3 OR L>R+3 THEN 200

    That way, it will have a tolerance of 6 lines, and it will then work for every frame.

    This proves that BASIC is indeed to slow to catch a specific line (with your method at least), but it's not as slow as we thought in the beginning (i.e. it skips an entire frame until it's ready to wait for the line again). And if it was a real BASIC command, it would work even better.

    - neue Spiele für den C64 -
    Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.

  • As a BASIC coder, I would not even mind if my routine got called a little bit late, let's say you do SYNC 220 and my routine is called when rasterline 223 is reached, or program flow continues after line 223. That wouldn't be a problem. As long as I could rely on the fact that in EVERY frame, this would happen. No matter if it's exactly at 220, or at 221, 222 oder 223 or something like that. But it shouldn't be skipped. And that would be possible with such a command.

    - neue Spiele für den C64 -
    Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.

  • I could rely on the fact that in EVERY frame, ...

    We need more facts! :D

    How fast does a certain rasterline come back? So what period of time are we talking about from rasterline x to the next time rasterline x?

  • Well, there are 50 frames per second in PAL, so one frame is displayed for 20 milliseconds. So that would be the time in between two times displaying the same rasterline.

    In fact (you wanted more facts), most games use this for timing. They set up an interrupt at a certain rasterline, often outside of the visible area (i.e. in the upper or lower borders), and call their game update routine from there. That way, the game will always run at the same speed, no matter how much code is executed (except if it takes longer than 20 milliseconds, of course). Without that syncing, you would have to measure the time that your game update code used, and then wait 20 ms minus that execution time, and it still wouldn't be perfectly exact due to some jittering. With an interrupt, it's a pretty stable thing, because that is done at hardware level.

    So for coding games (or also demos or something), it would be really helpful to have such a mechanism. It's not something crazy, it's actually something very "basic", in a way. So why not include it in BASIC ;)

    - neue Spiele für den C64 -
    Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.

  • And BASIC already has some interrupt functionality, as for example instructions like MOVSPR, or PLAY, or COLLISION etc, already use interrupts in the background. So adding a command to sync to THIS interrupt wouldn't be too complicated. To be able to sync to a user-defined rasterline, MIGHT be a little bit more complex, but that is something the team has to decide.

    - neue Spiele für den C64 -
    Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.

  • Thanks for your program, but why is the rasterline flashing? It almost seems as if the line is only reached every 2nd frame or so... shouldn't the program run fast enough so that the line is catched every frame?

    I think even with 40 MHz the BASIC program is too slow to get every single rasterline "r". :/

    There is also the problem with the inherent race condition: If Bit 8 of the raster line changes between the two PEEKs, the resulting value would be totally off.

    Yes, I'm the guy responsible for the Bitte melde dich an, um diesen Link zu sehen. cross assembler. And some Bitte melde dich an, um diesen Link zu sehen..

  • Well, there are 50 frames per second in PAL, so one frame is displayed for 20 milliseconds. So that would be the time in between two times displaying the same rasterline.

    Thanks, and now the question what can you do in BASIC in 20 ms? :)

  • Well, there are 50 frames per second in PAL, so one frame is displayed for 20 milliseconds. So that would be the time in between two times displaying the same rasterline.

    Thanks, and now the question what can you do in BASIC in 20 ms? :)

    With 40 MHz? A lot. For example, you can change the border color over 120 times:

    Bitte melde dich an, um diesen Anhang zu sehen.

    - neue Spiele für den C64 -
    Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.

  • ... you can change the border color over 120 times:

    I have count only 119 lines. :D

    I'm just trying out of self-interest, whether I can tinker something in ROM. Whether that will be something, remains to be seen. :)

    And what happens with the official ROM is out of our hands anyway. ;)

  • SYNC 220

    to be used in place, e.g. instead of SLEEPing inside your main loop for a certain amount of time, you could tell the BASIC interpreter to wait until raster line 220 has been reached.

    Okay, this command works already. :)

    SYNC x (line 180 and 210) waits until the rasterline x is reached.

    x is in range 0 ... 288 (PAL) and 0...254 (NTSC) (approx. values I got from testing)

    Bitte melde dich an, um diesen Anhang zu sehen.

    Here's a short clip from the above demo again:

    Bitte melde dich an, um diesen Link zu sehen.


    The test ROM is simply called "SYNC1" and is based on the 920357. With this you should be able to test everything well. I sent you something about conversation for testing. ;)

    I would like to see a raster example with a cactus. :D

  • Wow, that looks really cool :)

    By the way, you can enable the option "Display" - "Show Full Borders" in xemu to get more accurate results regarding the rasterline ranges :)

    - neue Spiele für den C64 -
    Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.

  • I just did a quick test on the real machine and so far it works exactly like it should:

    Bitte melde dich an, um diesen Anhang zu sehen.

    I also tried your demo and it works super smooth!

    One thing I didn't test yet is to run at a slower CPU speed. Will your routine catch up or will it miss the rasterline? I will test that now...

    - neue Spiele für den C64 -
    Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.

  • Okay so there are some issues when running this on SPEED 1 - my guess is that your command simply waits until exactly the raster line, but to make sure it doesn't get skipped, there should be a mechanism that detects an "overstepping" of that line.

    Also, while I don't know exactly how you implemented the command, keep in mind that the following is faster and thus more reliable:

    Code
        LDA #rasterline
    .loop
        CMP $D012
        BNE .loop

    ...than this:

    Code
    .loop
        LDA $D012
        CMP #rasterline
        BNE .loop

    But since you have to handle the 8th bit and so on anyway, and since an "overstepping" detection would be nice, the code would be probably more complex anyway...

    - neue Spiele für den C64 -
    Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.

  • my guess is that your command simply waits until exactly the raster line

    Yes, this is the current way it works. :)

    Cool! I can't remember the last time I used the 1 MHz mode ... :D

    I'll just see what else I can do there. The 9th bit makes the whole thing a bit more complex.

  • Yes, unfortunately... and registering a real interrupt in that case wouldn't probably work either...

    - neue Spiele für den C64 -
    Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.

  • The 9th bit makes the whole thing a bit more complex.

    Polling two registers always creates the race condition described above, unless the hardware is specially designed not to do this. The TOD clock registers in the CIAs are an example of such a "safe" design.

    There are ways around this problem (LDA d012:LDX d011:CMP d012:BNE tryagain), but the simplest solution would be to just use the VIC's raster interrupt facility. But:

    registering a real interrupt in that case wouldn't probably work either

    There's no need to generate a real interrupt signal, just poll the VIC's interrupt register.

    Yes, I'm the guy responsible for the Bitte melde dich an, um diesen Link zu sehen. cross assembler. And some Bitte melde dich an, um diesen Link zu sehen..

  • Now it should be ABSOLUTELY clear that we absolutely need that ;)

    And you, Snoopy, should absolutely code a Centipede clone 8)

    - neue Spiele für den C64 -
    Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.Bitte melde dich an, um diesen Link zu sehen.

  • the basic command is really funny and yet also very useful. Demo effects in basic games, it really has something 😃 it's just important that the command comes into the official ROM, so of course you don't use it... But maybe the cool demonstration will ensure that the command is adopted 😃