quohog Posted July 30, 2020 Share Posted July 30, 2020 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! 1 Quote Link to comment Share on other sites More sharing options...
+splendidnut Posted July 30, 2020 Share Posted July 30, 2020 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? Quote Link to comment Share on other sites More sharing options...
CapitanClassic Posted July 30, 2020 Share Posted July 30, 2020 (edited) 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! 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 July 30, 2020 by CapitanClassic 1 Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted July 30, 2020 Share Posted July 30, 2020 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. 2 Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted July 30, 2020 Share Posted July 30, 2020 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 #. 1 Quote Link to comment Share on other sites More sharing options...
quohog Posted August 1, 2020 Author Share Posted August 1, 2020 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... Quote Link to comment Share on other sites More sharing options...
CapitanClassic Posted August 1, 2020 Share Posted August 1, 2020 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) 1 Quote Link to comment Share on other sites More sharing options...
CapitanClassic Posted August 1, 2020 Share Posted August 1, 2020 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 1 Quote Link to comment Share on other sites More sharing options...
quohog Posted August 1, 2020 Author Share Posted August 1, 2020 Great ideas, thanks! I see now that my problem was I was searching in the regular Stella manual, not the debugger manual. Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted August 4, 2020 Share Posted August 4, 2020 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! 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. 1 Quote Link to comment Share on other sites More sharing options...
quohog Posted August 12, 2020 Author Share Posted August 12, 2020 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! ❤️ Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted August 12, 2020 Share Posted August 12, 2020 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 Quote Link to comment Share on other sites More sharing options...
quohog Posted August 12, 2020 Author Share Posted August 12, 2020 Oh wow, that looks like exactly what I need! Thanks @SpiceWare! I wonder why it was removed? Seems useful! Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted August 12, 2020 Share Posted August 12, 2020 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. 1 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted August 12, 2020 Share Posted August 12, 2020 Edit: Nevermind - I figured it out. ? Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted August 13, 2020 Share Posted August 13, 2020 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. 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.