Jump to content
IGNORED

scanlines, light sixers, stella, and white flashes


quohog

Recommended Posts

I have a game that looks solid in Stella, and on my heavy sixer, vader, and jr. But on my friends light sixer, it vibrates up and down, gaining and losing a scanline about every frame. I'm sure I just have some scanline that's cutting the timing too close, but I have questions on how to quickly zero in on the problem area.

 

1. First of all, I'm just curious if there are known timing differences with light sixers? 

 

2. What are the right developer settings in Stella to simulate these differences, if any? So far I haven't found a setting that recreates the scanline hop. 

 

3. In addition to this bug, I have another one that's very rare, but at least once per game there is a single white flash and roll. So I was hoping to find this by setting a breakpoint if my scanlines ever went over 262, but I can't find the right variable in the stella manual. I think I heard there was one called "_scans" or "_scanlines" but I can't find it. Am I close?

 

Any help is greatly appreciated! Or if you just have some pro-tips on catching rare timing issues. Thanks! :D

  • Like 1
Link to comment
Share on other sites

The first thing that comes to my mind is this might just be an issue with your friend's light sixer.  The cartridge slot might need to be cleaned.  Or there might be a power issue.

 

Unless you're really not certain that your code is good.  Have you wrapped everything in timers (vblank region, display kernel, overscan region)?

 

Also, are you willing to post the source code or a ROM to try out/take a look at?

Link to comment
Share on other sites

38 minutes ago, quohog said:

I have a game that looks solid in Stella, and on my heavy sixer, vader, and jr. But on my friends light sixer, it vibrates up and down, gaining and losing a scanline about every frame. I'm sure I just have some scanline that's cutting the timing too close, but I have questions on how to quickly zero in on the problem area.

 

1. First of all, I'm just curious if there are known timing differences with light sixers? 

 

2. What are the right developer settings in Stella to simulate these differences, if any? So far I haven't found a setting that recreates the scanline hop. 

 

3. In addition to this bug, I have another one that's very rare, but at least once per game there is a single white flash and roll. So I was hoping to find this by setting a breakpoint if my scanlines ever went over 262, but I can't find the right variable in the stella manual. I think I heard there was one called "_scans" or "_scanlines" but I can't find it. Am I close?

 

Any help is greatly appreciated! Or if you just have some pro-tips on catching rare timing issues. Thanks! :D

I found it while scanning the forums. 
breakif _scan>#262

 

responds with 

“breakpoint added” or added breakpoint.

 

if you hit tilde ‘ to enter the debugger again and enter the exact same breakif statement, it will remove the breakpoint.

Edited by CapitanClassic
  • Thanks 1
Link to comment
Share on other sites

There could be many different issues so it is hard to say what it is without the rom. Here though is a useful link for detecting when scanlines go over.

 

I also had a post in there for detecting too few scanlines.

 

 

With the light sixer, there are some known hardware issues with an inductor on the board. However, the heavy sixer should also have this issue. During the release of SF2 we had to deal with this.

 

  • Thanks 2
Link to comment
Share on other sites

most likely you left out a # on an immediate mode instruction, coding something as LDA 7 instead of LDA #7, as CMP 10 instead of CMP #10, and so on. It's a very common mistake that causes problems on some, but not all, 2600s.

 

Turning on Stella's Developer Settings will cause the issue to show up in Stella. For best results check all the options, but especially "Drive unused TIA pins randomly..." as that's the one that exposes missing #.


image.png.de1e2e2b5cf954b442afcb072c3eece7.png

 

  • Thanks 1
Link to comment
Share on other sites

Thanks for all the help, everybody!

 

I found the one frame flash/roll bug using the "breakif _scan>#262" command. Thanks @CapitanClassic! (The hashtag was was I was missing.) But you know, I still can't find that term "_scan" anywhere in the Stella manual I'm using (https://stella-emu.github.io/docs/index.html) Is there another one that lists all the terms like that? Because I'm looking for another one...

 

The next term I'm looking to find is something that tells the cycles used on a given scanline, so I can discover if one of my lines is getting close to that 76 cycle limit. Is there something like "breakif _scncycle>#70" ? I'm still trying to find that one-scanline-hop-up-and-down bug. I' have all my developer settings like in @SpiceWare's screenshot, but still can't repro it. 

 

I'll also hunt my code for missing #s...

Link to comment
Share on other sites

19 minutes ago, quohog said:

Thanks for all the help, everybody!

 

I found the one frame flash/roll bug using the "breakif _scan>#262" command. Thanks @CapitanClassic! (The hashtag was was I was missing.) But you know, I still can't find that term "_scan" anywhere in the Stella manual I'm using (https://stella-emu.github.io/docs/index.html) Is there another one that lists all the terms like that? Because I'm looking for another one...

 

The next term I'm looking to find is something that tells the cycles used on a given scanline, so I can discover if one of my lines is getting close to that 76 cycle limit. Is there something like "breakif _scncycle>#70" ? I'm still trying to find that one-scanline-hop-up-and-down bug. I' have all my developer settings like in @SpiceWare's screenshot, but still can't repro it. 

 

I'll also hunt my code for missing #s...

It lists them under Pseudo-Registers

https://stella-emu.github.io/docs/debugger.html#PseudoRegisters
 

Not sure if you can check if you have exceeded 76 cycles. I think the emulator is mimicking the behavior of a TV, and if you exceed 76 cycles, the beam has already started moving back to the left side of the screen. There are some games that never send a WSYNC, because the kernel is designed to be exactly 76 cycles long. If it does work, I suspect the command would be , “breakif _scycles>#76

 

Function Description
_bank Currently selected bank
_cclocks Color clocks on a scanline
_cycleshi Higher 32 bits of number of cycles since emulation started
_cycleslo Lower 32 bits of number of cycles since emulation started
_fcount Number of frames since emulation started
_fcycles Number of cycles since frame started
_icycles Number of cycles of last instruction
_scan Current scanline count
_scanend Scanline count at end of last frame
_scycles Number of cycles in current scanline
_vblank Whether vertical blank is enabled (1 or 0)
_vsync Whether vertical sync is enabled (1 or 0)

 

 

 

 

  • Thanks 1
Link to comment
Share on other sites

It does mention that you can use labels in the breakpoints (I assume with conditional breaks too), so something like ...

breakif {pc==__endofScanline && _scycles<20}

 

breakif program counter is at your label, and the cycle count is greater than 76 (or if it automatically makes cycle count =0 when it overflows, then some low number that shouldn’t be possible 

  • Thanks 1
Link to comment
Share on other sites

On 7/29/2020 at 8:41 PM, quohog said:

I have a game that looks solid in Stella, and on my heavy sixer, vader, and jr. But on my friends light sixer, it vibrates up and down, gaining and losing a scanline about every frame. I'm sure I just have some scanline that's cutting the timing too close, but I have questions on how to quickly zero in on the problem area.

 

1. First of all, I'm just curious if there are known timing differences with light sixers? 

 

2. What are the right developer settings in Stella to simulate these differences, if any? So far I haven't found a setting that recreates the scanline hop. 

 

3. In addition to this bug, I have another one that's very rare, but at least once per game there is a single white flash and roll. So I was hoping to find this by setting a breakpoint if my scanlines ever went over 262, but I can't find the right variable in the stella manual. I think I heard there was one called "_scans" or "_scanlines" but I can't find it. Am I close?

 

Any help is greatly appreciated! Or if you just have some pro-tips on catching rare timing issues. Thanks! :D

 

I think there's probably nothing wrong with your friends light sixer, but that your friends Television is likely right on the spec requiring a stable scanline count.

 

Even some classic Televisions have additional circuitry to tolerate a degree of variance in the scanline count, yours may have this.

 

I initially used a Sony CRT with my setup that had these characteristics and did not roll easily, models like the JVC or Sears SR1 Composite Monitor are better for development on the real hardware, because they are right on the spec and will roll with a variance of just 1 scanline; that is the kind I use now.

 

  • Thanks 1
Link to comment
Share on other sites

Thanks for all the help everybody! So this was the game I was working on:

 

 

I eventually got the scanline jump "fixed" but what I think happened is I added more code so that the tight loop in my keyboard reading code moved off a page boundary. I loop to wait the 400 microseconds to required to read the keyboards and every once in a while I push that loop onto a page boundary and everything goes to heck. I had it aligned to a page boundary before but then I ran past 4k rom. So I think I just have to org things into place. I mean you don't have to always use align to fix page timing issues, right? You can use org to just make sure the timing loops don't cross the page? Well, that's the hope anyway.

 

I think I need to study Basic Programming or Codebreaker to see how the pros of yore used to read keyboards to see if I can write tighter keyboard code. Right now I have to alternate and only read one keyboard each frame, alternating left and right. It works, but on the left controller I swear every once in a while the hammer falls a couple of rows too high. Also reading one controller takes almost all of my vertical blank.

 

But that's a problem for another day. Tonight I'm just happy that ZPH streamed my game and liked it. This community is the best! :) ❤️

Link to comment
Share on other sites

11 hours ago, quohog said:

I loop to wait the 400 microseconds to required to read the keyboards and every once in a while I push that loop onto a page boundary and everything goes to heck.

 

 

My macro.h has macros written by @supercat that help with this, looks like they're not in the latest macro.h file:

;-------------------------------------------------------
; SAME PAGE BRANCH CHECK
; Original author: John Payson
;
; Usage: sbeq, sbne, etc just like a normal beq, bne, etc.
;        A message will be output if the target of the branch
;        is not on the same page.
;
            mac sbcc
                bcc     {1}
                if (* ^ {1}) & $FF00
                echo "PAGE CROSSING","WARNING ",{1}," at ",*
                err
                endif
            endm

            mac sbcs
                bcs     {1}
                if (* ^ {1}) & $FF00
                echo "PAGE CROSSING","WARNING ",{1}," at ",*
                err
                endif
            endm

            mac sbeq
                beq     {1}
                if (* ^ {1}) & $FF00
                echo "PAGE CROSSING","WARNING ",{1}," at ",*
                err
                endif
            endm

            mac sbmi
                bmi     {1}
                if (* ^ {1}) & $FF00
                echo "PAGE CROSSING","WARNING ",{1}," at ",*
                err
                endif
            endm

            mac sbne
                bne     {1}
                if (* ^ {1}) & $FF00
                echo "PAGE CROSSING","WARNING ",{1}," at ",*
                err
                endif
            endm

            mac sbpl
                bpl     {1}
                if (* ^ {1}) & $FF00
                echo "PAGE CROSSING","WARNING ",{1}," at ",*
                err
                endif
            endm

            mac sbvc
                bvc     {1}
                if (* ^ {1}) & $FF00
                echo "PAGE CROSSING","WARNING ",{1}," at ",*
                err
                endif
            endm

            mac sbvs
                bvs     {1}
                if (* ^ {1}) & $FF00
                echo "PAGE CROSSING","WARNING ",{1}," at ",*
                err
                endif
            endm

 

Here's the time critical routine for sending data to the AtariVox, a bit must be sent every 62 cycles:

        sec     ; start bit
.byteout_loop
        ; put carry flag into bit 0 of SWACNT, perserving other bits
        lda     SWACNT          ; 4
        and     #$fe            ; 2 6
        adc     #$00            ; 2 8
        sta     SWACNT          ; 4 12

        ; 10 bits sent? (1 start bit, 8 data bits, 1 stop bit)
        cpy     #$09            ; 2 14
        beq     .speech_done    ; 2 16
        iny                     ; 2 18

        ; waste some cycles
        ldx     #$07
.delay_loop
        dex
        bne     .delay_loop     ; 36 54

        ; shift next data bit into carry
        lsr     {1}             ; 5 59

        ; and loop (branch always taken)
        bpl     .byteout_loop   ; 3 62 cycles for loop

 

To make sure a branch stays on the same page just prefix it with an s:

        sec     ; start bit
.byteout_loop
        ; put carry flag into bit 0 of SWACNT, perserving other bits
        lda     SWACNT          ; 4
        and     #$fe            ; 2 6
        adc     #$00            ; 2 8
        sta     SWACNT          ; 4 12

        ; 10 bits sent? (1 start bit, 8 data bits, 1 stop bit)
        cpy     #$09            ; 2 14
        beq     .speech_done    ; 2 16
        iny                     ; 2 18

        ; waste some cycles
        ldx     #$07
.delay_loop
        dex
        sbne     .delay_loop    ; 36 54   <----- time critical loop, must be on same page

        ; shift next data bit into carry
        lsr     {1}             ; 5 59

        ; and loop (branch always taken)
        sbpl     .byteout_loop   ; 3 62 cycles for loop  <----- time critical loop, must be on same page

 

Link to comment
Share on other sites

30 minutes ago, quohog said:

Oh wow, that looks like exactly what I need! Thanks @SpiceWare

I wonder why it was removed? Seems useful!

 

You're welcome!

 

Now that I think about it, they were probably never in the official macro.h file. A quick search turned up this comment in a blog with @supercat's macro for SBPL - I most likely thought it was a great idea, dropped it into my macro.h, and cloned it for all the branch instructions.

 

  • Like 1
Link to comment
Share on other sites

23 hours ago, quohog said:

I think I need to study Basic Programming or Codebreaker to see how the pros of yore used to read keyboards to see if I can write tighter keyboard code. Right now I have to alternate and only read one keyboard each frame, alternating left and right. It works, but on the left controller I swear every once in a while the hammer falls a couple of rows too high. Also reading one controller takes almost all of my vertical blank.

Consider reading a keypad during the kernel as you can wait longer than 400mS between reading each row, but not sooner. I remember alex_79 saying he had to wait at least 500mS between reads on one of his consoles while the other consoles he had were fine at 400mS intervals.

 

Reading during the kernel is efficient because you are doing stuff between reads (drawing the screen), and the time between reads is easily set to a fixed to a certain time interval.

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...