Jump to content
Andrew Davie

Chess

Recommended Posts

Tested version in post #1198: it still rolls.

 

I connected my cheap logic analyzer to the console:

 

CDFJchess.thumb.png.56377a2611dcaf1ad2e5921f7f1e5cce.png

 

The frames are 375 scanlines (24ms) long

The board is displayed between scanline 144 and 345 as there's activity on LUM0-3 pins of the TIA in this range.

The arm appears to idle the 6507 between scanline 5 and 33 as in this range A12 is high (cart space) and D4 is constantly low (which is compatible with the arm putting $EA, that is "nop", on the bus).

I only have 8 inputs available, so I can't monitor the entire bus.

 

CDFJchess_idle.thumb.png.a7c6e615e980257c077f870e9decbd90.png

  • Like 1

Share this post


Link to post
Share on other sites
1 minute ago, alex_79 said:

Tested version in post #1198: it still rolls.

 

I connected my cheap logic analyzer to the console:

 

CDFJchess.thumb.png.56377a2611dcaf1ad2e5921f7f1e5cce.png

 

TY... extremely useful and interesting.

I'll use this analysis to crosscheck with the code. 

I'm learning and using unfamiliar code so I'm probably doing silly things.

Midway between a complete reconversion of the draw loop right now, then I'll check your info.

 

Share this post


Link to post
Share on other sites
3 minutes ago, alex_79 said:

The arm appears to idle the 6507 between scanline 5 and 33 as in this range A12 is high (cart space) and D4 is constantly low (which is compatible with the arm putting $EA, that is "nop", on the bus).

 

 

My basic understanding of how this works says to me that my draw code (which should be executing while the 6507 is forced-idle) is therefore taking 28 scanlines.  But, I'll get back to this...

 

Share this post


Link to post
Share on other sites

Still rolls for me as well, though slower than the prior two builds.

 

2 hours ago, alex_79 said:

The frames are 375 scanlines (24ms) long

The board is displayed between scanline 144 and 345 as there's activity on LUM0-3 pins of the TIA in this range.

The arm appears to idle the 6507 between scanline 5 and 33 as in this range A12 is high (cart space) and D4 is constantly low (which is compatible with the arm putting $EA, that is "nop", on the bus).

 

Hmm:

  • Custom ARM code running 5-33
  • Board drawn 144-345

Begs the question of what's going on in those 111 scan lines after the ARM code finishes.

Share this post


Link to post
Share on other sites
3 minutes ago, SpiceWare said:

Still rolls for me as well, though slower than the prior two builds.

 

 

Hmm:

  • Custom ARM code running 5-33
  • Board drawn 144-345

Begs the question of what's going on in those 111 scan lines after the ARM code finishes.

Totally has me beat.

I'm currently looking at how the end of timer is being checked, and if that's somehow failing... super long wait... accounting for those 111 lines.

All my previous code checked INTIM being 0.  This code checks TIMINT being positive.

I seem to recall some comments about the behaviour of one of these when reaching 0 and then continuing to count by 1... vague.

Anyway, that's where I'm looking... tomorrow...

 

Share this post


Link to post
Share on other sites
3 minutes ago, Andrew Davie said:

Totally has me beat.

I'm currently looking at how the end of timer is being checked, and if that's somehow failing... super long wait... accounting for those 111 lines.

All my previous code checked INTIM being 0.  This code checks TIMINT being positive.

I seem to recall some comments about the behaviour of one of these when reaching 0 and then continuing to count by 1... vague.

Anyway, that's where I'm looking... tomorrow...

 

Just for reference, here's a version that waits in VB on INTIM the way I'm used to doing it... instead of TIMINT

Display is mid-work so there's a few glitchy pieces.

 

 

CDFJChess.bin

Share this post


Link to post
Share on other sites
28 minutes ago, Andrew Davie said:

Just for reference, here's a version that waits in VB on INTIM the way I'm used to doing it... instead of TIMINT

Display is mid-work so there's a few glitchy pieces.

 

That generates a stable image, though image is shifted upward.  Regular photo:

 

IMG_1566D.thumb.jpg.f7fd6329f146d70ae757d594b369eb03.jpg

 

 

Cortex Camera photo:

 

IMG_1567.thumb.jpg.0f78412f79ffcc73d012ed9fa5ff0e70.jpg

 

Cortex Camera merges multiple photos into one in realtime for improved image quality in low-light situations. Compare the detail on the Draconian label (on the right) in the two photos.

Share this post


Link to post
Share on other sites
21 minutes ago, SpiceWare said:

That generates a stable image, though image is shifted upward.

It rolls faster than the previous one on my PAL CRT TV.

 

By looking at the signals:

592 scanlines per frame (38ms)

ARM code running from scanline 5 to 33

Chess board from scanline 361 to 562

 

Senzanome.thumb.png.3e59d5d1e031893e2f0c5265cb9195e3.png

 

Share this post


Link to post
Share on other sites

I tried increasing the value stored in the timer from $2f to $31, which gives 278 scanlines in Stella, and the resulting rom works fine on my TV (I confirmed with the logic analyzer that the frame is 278 lines with the hacked rom)

So, the arm code is taking is taking too long and the timer expires before the 6507 code starts checking it.

 

Senzanome.thumb.png.989c49c6ac918b0548f2e46509c704fa.png

 

IMG_20210124_220850.thumb.jpg.9c5765f2f7f7c0628706108c87b2f4ad.jpg

 

 

  • Like 2

Share this post


Link to post
Share on other sites
36 minutes ago, alex_79 said:

I tried increasing the value stored in the timer from $2f to $31, which gives 278 scanlines in Stella, and the resulting rom works fine on my TV (I confirmed with the logic analyzer that the frame is 278 lines with the hacked rom)

So, the arm code is taking is taking too long and the timer expires before the 6507 code starts checking it

 

TY that's excellent news. I'm sure I can find that little bit extra speed.

Looks like I should increase the brightness of the darks a notch.

What do you think of the shimmer/flicker and the visuals overall?

 

 

Edited by Andrew Davie

Share this post


Link to post
Share on other sites

OK, so here's a version that

1) Increases the VB timer from 47 to 49 ($31)

2) Decreases the OS timer 

3) Hits 276 scanlines

4) Has some colour brightness adjustments

 

 

CDFJChess.bin

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Let me just jump in and say, this thread has been fascinating from the beginning and remains so!  Thanks for sharing.

Share this post


Link to post
Share on other sites
2 hours ago, Stephen said:

Let me just jump in and say, this thread has been fascinating from the beginning and remains so!  Thanks for sharing.

For me, at least, the journey is more than half the fun. By sharing the progress I also benefit from many great suggestions and help without which things would have been way more difficult. Look at the awesome diagnostic help @SpiceWare and @alex_79 gave to find the cause of this particular issue. The logic analyser step was critical to understanding the problem, and I've learned something important about how the timer behaves as a result.  Also, I rarely finish things so it's nice to have a sort of "plog" about what decisions I made along the way and why. Thanks for the feedback!

  • Like 3

Share this post


Link to post
Share on other sites
2 hours ago, SpiceWare said:

Looks good!

 

IMG_1571D.thumb.jpg.684e990d7895bfeeaa418bbef41f03d9.jpg

 

IMG_1570.thumb.jpg.7f6f6156c8b715510faf55b2384e04ef.jpg

 

I'm so very grateful for your assistance on this!

What's your opinion on how it actually looks to the naked eye?

 

Share this post


Link to post
Share on other sites
4 hours ago, alex_79 said:

I tried increasing the value stored in the timer from $2f to $31, which gives 278 scanlines in Stella, and the resulting rom works fine on my TV (I confirmed with the logic analyzer that the frame is 278 lines with the hacked rom)

So, the arm code is taking is taking too long and the timer expires before the 6507 code starts checking it.

An awesome bit of detective work. Thank you so much.

What is your view on how it looks to the eye?

Share this post


Link to post
Share on other sites

 

14 hours ago, alex_79 said:

The frames are 375 scanlines (24ms) long

The board is displayed between scanline 144 and 345 as there's activity on LUM0-3 pins of the TIA in this range.

The arm appears to idle the 6507 between scanline 5 and 33 as in this range A12 is high (cart space) and D4 is constantly low (which is compatible with the arm putting $EA, that is "nop", on the bus).

 

@alex_79 wrote...

 

Quote

In fact, when the interrupt flag (TIMINT bit 7) is set, the timer always counts at 1T, while when it's clear, it counts at the programmed interval (1T,8T,64T,1024T).
The flag is set whenever the timer wraps around, while it's cleared on every read (INTIM) or write (TIM1T,TIM64T,etc.) access, except when the read/write happens at the wraparound cycle.

 

So, the "bit TIMINT" would appear to be the more correct method than reading INTIM

 

So, scenario... VB timer is setup. We run ARM code, but before that finishes, INTIM has counted down to 0 (i.e., we're overtime).

At that point, the timer interrupt flag (TIMINT) is set, and timer starts to decrement by 1 every cycle.  The ARM code finishes. The branch should detect the interrupt flag set, and immediately exit.  So, where's the large number of bogus scanlines coming from?

 

We know it's in that wait loop, so that suggests to me that the timer flag isn't behaving as we expect.  In terms of when I read INTIM instead of the timer flag, that's explainable - we are effectively waiting for a whole bunch of time until we just happen to accidentally do a INTIM read when it's 0 (remember it's counting down 1 cycle speed, so we could "miss" the 0-value as our read takes 3 cycles).  We might end up waiting for several whole "loops" of INTIM counting down until we "hit" the zero value at the right time.  So that's explainable.

 

But with the bit TIMINT, not so explainable.  ARM code is overtime. TIMINT is set.  INTIM starts counting down 1-cycle-at-a-time.  And yet, somehow we "miss" the TIMINT flag until some later time.  Can't explain that yet.

 

Remember, the "fix" was to make the timer run for just 3 more 64-cycle ticks.  We were only overtime by a couple of hundred cycles here.  It's almost as if the flag clear has somehow been missed and we had to wait a whole lot more.

 

 

 

 

 

Share this post


Link to post
Share on other sites
9 hours ago, Andrew Davie said:

OK, so here's a version that

1) Increases the VB timer from 47 to 49 ($31)

2) Decreases the OS timer 

3) Hits 276 scanlines

4) Has some colour brightness adjustments

Works fine!

 

 

10 hours ago, Andrew Davie said:

What do you think of the shimmer/flicker and the visuals overall?

I find the flicker a bit too much visible on bright objects. The black pieces and the board look ok, but the effect on the white pieces is a bit annoying to my eyes. It gets a bit better if I reduce the contrast and/or back away from the screen.

 

3 hours ago, Andrew Davie said:

But with the bit TIMINT, not so explainable.  ARM code is overtime. TIMINT is set.  INTIM starts counting down 1-cycle-at-a-time.  And yet, somehow we "miss" the TIMINT flag until some later time.  Can't explain that yet.


That's because you're reading the timer value (lda INTIM at $f0ac) before testing TIMINT.

Senzanome.thumb.png.700533de77f23a60e48687cd600505bc.png

Even if the timer already expired (so, interrupt flag set and timer counting at 1 cycle interval), that read access clears the flag and, as a consequence, the timer resumes counting using the last programmed interval (64 cycles in this case) from whichever value it reached at that point.

The flag will be set again only the next time the timer wraps around, and since it is now counting at 64T, it can take a long time (it depends on what value it was on when the flag was cleared).

Edited by alex_79

Share this post


Link to post
Share on other sites
1 minute ago, alex_79 said:

That's because you're reading the timer value (lda INTIM at $f0ac) before testing TIMINT.

 

Even if the timer already expired (so, interrupt flag set and timer counting at 1 cycle interval), that read access clears the flag and, as a consequence, the timer resumes counting using the last programmed interval (64 cycles in this case) from whichever value it reached at that point.

The flag will be set again only the next time the timer wraps around, and since it is now counting at 64T, it can take a long time (it depends what value it was on when the flag was cleared).

 

Well spotted; thanks! Makes perfect sense.

I will update the code accordingly, and perhaps @SpiceWare will modify the collect demo/tutorial, too - as it's definitely a bug in the code.

Has been a good learning experience.

Share this post


Link to post
Share on other sites

Something like this appears to be the right way to do it, then....

 

        ldy #0
        sty TimeLeftOS
        bit TIMINT
        bmi .zeroTime

        lda INTIM
        sta TimeLeftOS
OSwait:        
        stx WSYNC
        bit TIMINT
        bpl OSwait
        
.zeroTime

Even so, there's potential to "miss" -- after the read of INTIM and before the subsequent bit/branch.  Seems like storing "TimeLeftOS" isn't the greatest of things to do if you want to have reliable timer detection.

Share this post


Link to post
Share on other sites

BTW, if you use these alternate addresses to access the timer

 

$28c (INTIM)
$29c (TIM1T)
$29d (TIM8T)
$29e (TIM64T)
$29f (T1024T)

 

you enable the hardware interrupt function, which will pull pin 25 of the RIOT chip low when the interrupt flag is set, so it can be detected with a logic analyzer.

Enabling the interrupt has no consequences as pin 25 of the RIOT is not connected to anything on a 2600 console (and 7800 too).

Share this post


Link to post
Share on other sites
7 minutes ago, alex_79 said:

BTW, if you use these alternate addresses to access the timer

 

$28c (INTIM)
$29c (TIM1T)
$29d (TIM8T)
$29e (TIM64T)
$29f (T1024T)

 

you enable the hardware interrupt function, which will pull pin 25 of the RIOT chip low when the interrupt flag is set, so it can be detected with a logic analyzer.

Enabling the interrupt has no consequences as pin 25 of the RIOT is not connected to anything on a 2600 console (and 7800 too).

Noted, thanks; I'll put that in.

 

Here's an updated version of the check I'm trying...

 

                    ldx #0
                    bit TIMINT
                    bmi .zeroTime
                    lda INTIM
                    beq .zeroTime
                    bmi .zeroTime
                    tax
OSwait              sta WSYNC
                    bit TIMINT
                    bpl OSwait

.zeroTime           stx TimeLeftOS

 

X holds the "time left" value.

The logic: first see if the flag is set, and if so we immediately exit (and write 0 to the TimeLeftOS variable).

Otherwise, time hasn't expired (but it could have just after the bit and before the INTIM load)...

So we load INTIM and if it's negative then it MUST have been counting down by 1 (and having just started doing that).

In that case, we skip past the loop and record 0 as the time left.

Otherwise, we put the (valid) time count into X for saving when we're done.

Then we start looping, waiting for the flag to be set.

Finally, after the loop, X holds the valid time count (or 0).

 

 

 

 

Share this post


Link to post
Share on other sites
1 hour ago, alex_79 said:

I find the flicker a bit too much visible on bright objects. The black pieces and the board look ok, but the effect on the white pieces is a bit annoying to my eyes. It gets a bit better if I reduce the contrast and/or back away from the screen.

 

Here's a version with the bright parts toned down a bit. Looks a bit dim to me on the emulator; maybe it's OK on your TV.

This is also using my new timer-wait loop...

 

 

 

CDFJChess.bin

Share this post


Link to post
Share on other sites

I also find full-screen flicker to be a bit much. However, I learned a trick in my C=128 days:

 

On 9/23/2006 at 5:16 PM, SpiceWare said:

I was working on an Asteroids clone as a followup to Alien Invaders. I had the asteroids and ship flying around, but lost interest in finishing it when I bought my Amiga.

 

Also, the VDC could generate 640x400 by turning on interlaced mode. Not all monitors supported interlaced, but mine did and I wrote a program to turn it on & patch the kernel to support 80x50. It was really nice for coding, especially once I discovered that wearing polarized sunglasses reduced the flicker.

 

So I would play it without any problem by putting on my shades. 😎 I did the same when I was working on the RPG demo:

 

rpg.png

 

 

 

Interesting about the timer, surprised I hadn't run into that before. I put an uncommented note into Collect 3 so it'll generate an error and remind me to revise the routine when I get back to work on the CDFJ tutorial.

 

852120136_ScreenShot2021-01-25at10_12_31AM.thumb.png.d07a6525cd7a8201c411829c96cd5742.png

  • Like 1

Share this post


Link to post
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...