Page 1 of 2

Video Timing

Posted: Fri Apr 20, 2018 6:10 pm
by Coeus
Where is the best description of how the CRTC timing registers interact with a typical monitor/TV? I am trying to understand why B-Em and b2 have the image for the NuLA SOTB demo in a different place in the screen. It looks like this demo sets some of the registers to rather novel values where I don't quite understand what is supposed to happen.

Re: Video Timing

Posted: Fri Apr 20, 2018 9:42 pm
by jgharston

Re: Video Timing

Posted: Sat Apr 21, 2018 6:08 am
by ThomasHarte
If the issue is just positioning being different, could it just be different assumptions about flyback?

If that's a possibility, then the Dictionary of Video and Television Technology, p. 234 says that horizontal flyback will usually take about 7us, and vertical is typically in the range 500–750us. In principle horizontal should be edge triggered, but I strongly suspect sets lowpass filter by sync length, hence the half-a-column displacement trick. Vertical should definitely be only upon completion of the proper pulses.

Re: Video Timing

Posted: Sat Apr 21, 2018 6:50 am
by tricky
The nula is blanking a few extra pixels on the left side of the screen (probably one byte).

Re: Video Timing

Posted: Sat Apr 21, 2018 12:29 pm
by Coeus
Thanks, everyone. I have solved it now.

What I ad originally thought was a vertical timing issue, because the B-Em was missing the black border above the graphics, turned out to be a blanking issue instead.

What eventually gave me the clue was that rhe first few lines of the display were radically different between the Master shadow RAM version and the sideways RAM version with the sideways RAM version looking a bit random, so I started to think that RAM that should not be displayed was being displayed.

The problem was that B-Em was turning off DISPEN when the vertical count reached the value in the vertical total register but did not do so if code re-programmed the vertical total register so it changed from being greater that the vertical count to being less than it, thus avoiding the moment they were equal.

The 6845 datasheet was certainly useful and contains timing diagrams that didn't get copied into the AUG but even that doesn't go into detail about what happens when you dynamically re-program the 6845 as the frame proceeds.

Re: Video Timing

Posted: Sat Apr 21, 2018 2:32 pm
by 1024MAK
I don't think the chip manufacturer expected it to be reprogrammed dynamically!

Remember, at the time, it was designed to drive a text screen and be controlled with (the relatively) slow microprocessors of the day.

Mark

Re: Video Timing

Posted: Sat Apr 21, 2018 5:11 pm
by ThomasHarte
Does the 6845 ever test any value for anything other than exactly equal?

Re: Video Timing

Posted: Sun Apr 22, 2018 11:01 am
by Coeus
ThomasHarte wrote:Does the 6845 ever test any value for anything other than exactly equal?
That's a very good point. How I arrived at the fix was I added a extra:

Code: Select all

if (vc >= crtc[6])
    dispen = 0;
comparison which was executed each time through the video_poll code. That seemed to solve the problem. Then I tried moving the comparison to where the register is set and that was also a suucess. I have now tried changing it to an '=' rather than '>=' and that works too.

So it looks like the issue was that the code was previously only doing the comparison at the end of a scan line when vc had just increased, on the basis that vc would not have changed anywhere else, neglecting the fact that the result of the comparison could change if the register changed.

The data sheet is not completely clear on this but reading it again it seems to lean slighly in favour of suggesting the comparisons are for equality. It would be good to know for sure but I am not so desparate to find out as to write a test program in assembler to find out. If anyone else has a suitable framework already that could be adapted to test this then feel free.

Re: Video Timing

Posted: Sun Apr 22, 2018 12:55 pm
by tricky
What I have found with my games, RichTW, Hoglet, JBNBeeb and others is that there are different behaviours in different manufacturers 6845s that cause different behavior when setting different registers during display.
Some of the data sheets hint at when things might differ. On frogger on some masters, when I change the number of characters rows per "frame" on the penultimate scanline, instead of one more scan line, you get two more fetched from the "wrong" address.
From my experiments, everything seems to be checked == and as this would be "cheaper" to implement, it seems logical that this is what was done.

Re: Video Timing

Posted: Sun Apr 22, 2018 4:44 pm
by jgharston

Re: Video Timing

Posted: Sun Apr 22, 2018 8:54 pm
by kieranhj
This is a really interesting thread, thanks for all the links and info. It is quite timely (pun intended?!) as I’m currently writing a new BBC Master demo that is all based around reprogramming the CRTC liberally. If you want to test anything I have a framework that runs code exactly at the start of scanline 0 (give or take 8 cycles of jitter) then cycle counts every visible scanline of the frame.

The only difference I’ve noticed between b-em (and jsbeeb) vs real hardware is when setting the screen address registers on the final visible scanline - I’m seeing that new address at the bottom of the screen instead of scanline 0 as I’d expect (as it shouldn’t be latched until the new CRTC cycle.) Not sure what’s going on there.

Re: Video Timing

Posted: Sun Apr 22, 2018 9:53 pm
by Coeus
kieranhj wrote:The only difference I’ve noticed between b-em (and jsbeeb) vs real hardware is when setting the screen address registers on the final visible scanline - I’m seeing that new address at the bottom of the screen instead of scanline 0 as I’d expect (as it shouldn’t be latched until the new CRTC cycle.) Not sure what’s going on there.
Interesting. I have just checked the B-Em code and in video.c we have:

Code: Select all

            if (vadj) {
                sc++;
                sc &= 31;
                ma = maback;
                vadj--;
                if (!vadj) {
                    vdispen = 1;
                    ma = maback = (crtc[13] | (crtc[12] << 8)) & 0x3FFF;
                    sc = 0;
                }
            } else...
The overall context here is that we have reached the end of a scanline, i.e. hc == R0 so this is where it does various vertical control things. These are the only references to R12/13 so this looks like resetting the current memory address back to the start address in R12/13 at the end of vadj. That in turn was picked up from R5 on the last scanline of the last character row, i.e. when vc == R4.

If you're also changing R4 partway through a line or, I think, even between the scanlines that make up a single character row in a way that would mean it should move immediately into the VADJ period that won't happen until the last scanline of that row. If that is the issue then that could also be fixed by repeating the test when the value of R4 is changed, as I have done for DISPEN.

If you can set up an example so the result is visually different I could test that.

Re: Video Timing

Posted: Mon Apr 23, 2018 11:26 am
by kieranhj
Coeus wrote: The overall context here is that we have reached the end of a scanline, i.e. hc == R0 so this is where it does various vertical control things. These are the only references to R12/13 so this looks like resetting the current memory address back to the start address in R12/13 at the end of vadj. That in turn was picked up from R5 on the last scanline of the last character row, i.e. when vc == R4.

If you're also changing R4 partway through a line or, I think, even between the scanlines that make up a single character row in a way that would mean it should move immediately into the VADJ period that won't happen until the last scanline of that row. If that is the issue then that could also be fixed by repeating the test when the value of R4 is changed, as I have done for DISPEN.

If you can set up an example so the result is visually different I could test that.
I should have stated that b-em was exhibiting the behaviour I expected but that my real hardware was "wrong" based on my understanding of how the CRTC works! I posted an issue on the jsbeeb GitHub but I should really put together a better (much simpler) repro example.

I haven't been able to test my latest work on real hardware yet but when I do that I'll take another look at this behaviour (my expectation is that I was not creating a proper full 312 line PAL signal, perhaps off by one, and b-em is being nice to me and ignoring it but the real hardware is less kind.)

Re: Video Timing

Posted: Mon Apr 23, 2018 11:57 am
by BigEd
jgharston wrote:This chap seems to have worked out the internals.
Thanks JGH! I see André has also listed the per-manufacturer 6845 differences here.

Re: Video Timing

Posted: Mon Apr 23, 2018 12:03 pm
by tricky
I've had LCD displays fail to display not quite 50hz screens, that have been fine on CRTs and similar "pickiness" with h-sync width, which was more surprising as the LCDs seem to time of the edge of h-sync.

Re: Video Timing

Posted: Mon Apr 23, 2018 12:11 pm
by tricky
There are other differences to do with writing register values at certain times causing unexpected behaviour, but I can't remember the ones other than the corruption and extra displayed scanline on some master 6845s.

Re: Video Timing

Posted: Mon May 14, 2018 1:08 pm
by Rich Talbot-Watkins
kieranhj wrote:This is a really interesting thread, thanks for all the links and info. It is quite timely (pun intended?!) as I’m currently writing a new BBC Master demo that is all based around reprogramming the CRTC liberally. If you want to test anything I have a framework that runs code exactly at the start of scanline 0 (give or take 8 cycles of jitter) then cycle counts every visible scanline of the frame.

The only difference I’ve noticed between b-em (and jsbeeb) vs real hardware is when setting the screen address registers on the final visible scanline - I’m seeing that new address at the bottom of the screen instead of scanline 0 as I’d expect (as it shouldn’t be latched until the new CRTC cycle.) Not sure what’s going on there.
So here's a strange thing I read recently (as I mentioned here):
Rich Talbot-Watkins wrote:Incidentally, this documentation has the following snippet about different CRTC types:
The MA is reloaded with the value from R12 and R13 when VCC=0 and VLC=0 (that's when a new CRTC screen begin). However, CRTC Type 1 keep updating the MA on every new scanline while VCC=0 (and VLC=<R9).
This would imply that, for some 6845s, you could set R12/R13 at different scanlines within the first character row of a new frame and get a change of address midway through a row. Doesn't it? Not that this is related to your problem, but it's probably worth considering all the same, if it's true.
Is it possible this is what you're seeing? If you have R4=0, so every row is the 'first' row, that would be the case where VCC=0. A type 1 CRTC allegedly then reloads R12/R13 at the start of every scanline for VCC=0, which would match your observed behaviour.

Curious, huh? I have no idea if this is documented somewhere, or if it's the author's own research.

Re: Video Timing

Posted: Mon May 14, 2018 1:21 pm
by Rich Talbot-Watkins
Coeus wrote:
ThomasHarte wrote:Does the 6845 ever test any value for anything other than exactly equal?
That's a very good point. How I arrived at the fix was I added a extra:

Code: Select all

if (vc >= crtc[6])
    dispen = 0;
comparison which was executed each time through the video_poll code. That seemed to solve the problem. Then I tried moving the comparison to where the register is set and that was also a suucess. I have now tried changing it to an '=' rather than '>=' and that works too.

So it looks like the issue was that the code was previously only doing the comparison at the end of a scan line when vc had just increased, on the basis that vc would not have changed anywhere else, neglecting the fact that the result of the comparison could change if the register changed.

The data sheet is not completely clear on this but reading it again it seems to lean slighly in favour of suggesting the comparisons are for equality. It would be good to know for sure but I am not so desparate to find out as to write a test program in assembler to find out. If anyone else has a suitable framework already that could be adapted to test this then feel free.
The 6845 schematic in the datasheet tells us all we need to know.

Image

The CO blocks in the diagram are COincidence circuits, which fire when the two inputs are equal. All comparisons with registers are done by equality, which makes sense, as a 'less than' comparison would be far more costly in transistors.

You can abuse this in various ways in the 6845. For example, if you want an R5 period greater than 31 lines, just wait until n lines have been rasterised, and then set R5 to some value less than n, and the internal counter will wrap around before eventually hitting the target value.

Re: Video Timing

Posted: Mon May 14, 2018 5:37 pm
by kieranhj
Rich Talbot-Watkins wrote:
Rich Talbot-Watkins wrote:This would imply that, for some 6845s, you could set R12/R13 at different scanlines within the first character row of a new frame and get a change of address midway through a row. Doesn't it? Not that this is related to your problem, but it's probably worth considering all the same, if it's true.
Is it possible this is what you're seeing? If you have R4=0, so every row is the 'first' row, that would be the case where VCC=0. A type 1 CRTC allegedly then reloads R12/R13 at the start of every scanline for VCC=0, which would match your observed behaviour.

Curious, huh? I have no idea if this is documented somewhere, or if it's the author's own research.
Thanks for the link - that's a great document and very interesting!

My interpretation of the doc is that it says MA gets reloaded at the "start" of every scanline when the character row = 0. So if you set a new R12/R13 during the first character row (e.g. scanline 4 / 8 ) then it would change address midway through the row, as you say (so presumably at the "start" of scanline 5 in this example, not during the scanline itself.) This should be possible for me to test with my framework as I can trigger code on HCC=0 VCC=0 (give or take a bit of cycle jitter.)

I still don't think this explains what I was seeing at the bottom of the screen because although every row is the first row, it's also the start of a new CRTC cycle so I'd expect it to reload MA. According to what I *think* my timing is (from the b-em debugger) I'm setting R12/R13 during the first few characters after the start of each scanline. My timing could be off though and it would only take a couple of cycles. When I get chance to try on my real Master again I will try twiddling some of the values to see what happens.

Do we know which "type" of 6845 is in a Master (following the Amstrad "type" definition.) The high-res photo from here: http://www.8bs.com/see/Master128_motherboard.jpg suggests a Hitachi part? Or are they different.

Re: Video Timing

Posted: Mon May 14, 2018 7:31 pm
by tricky
We know from Frogger that there are at least two different 6845s in Masters, unless several have been replaced.
The issue where the last line of the display has rubbish in it and then an additional scan line with more rubbish.
This only occurred on some masters, but not on any Model Bs AFAIK.

Re: Video Timing

Posted: Mon May 14, 2018 7:40 pm
by SarahWalker
HD6845SP is 'type 0'.

A quick scan through Google Images suggests almost all Beebs use the HD6845SP, though I have a feeling that some Bs (possibly early ones?) use the Motorola 6845-1. While I was trying to find confirmation of the latter, I noticed that BeebMaster has a late Master 128 with a Samsung KS68C45S - see http://www.beebmaster.co.uk/8bit/Cherry9.html. No idea where that falls under the type system!

Re: Video Timing

Posted: Mon May 14, 2018 8:33 pm
by Rich Talbot-Watkins
kieranhj wrote:I still don't think this explains what I was seeing at the bottom of the screen because although every row is the first row, it's also the start of a new CRTC cycle so I'd expect it to reload MA. According to what I *think* my timing is (from the b-em debugger) I'm setting R12/R13 during the first few characters after the start of each scanline. My timing could be off though and it would only take a couple of cycles. When I get chance to try on my real Master again I will try twiddling some of the values to see what happens.
I feel like this can also be explained by the same issue as tricky's problem, here.

Have I understood right that you have a bunch of single line, single row CRTC frames (R4=0, R9=0), and then a block of rows to make the PAL frame up to 312? In the other thread, we have the observation that R4 needs to be changed before the final scanline; but if each CRTC frame *is* only one scanline, that doesn't give you any place to do it. So you'll get an extra row of R4=0 with the new R12/R13 (at the bottom), and then you'll get the big block of R4 as intended.

Or maybe your issue was just about setting R6 to 0 too late in order to start the bottom border (remembering that it needs to be set to 0 before the new frame starts in order to show nothing). If it were set too late, that'd show exactly one extra single line row, and then correctly disable display for the remaining rows of the PAL frame.

Does that kinda make some sense?

Re: Video Timing

Posted: Mon May 14, 2018 9:47 pm
by tricky
PS, if R12/13 aren't latched as I expect, scramble will look very wrong.

Re: Video Timing

Posted: Mon May 14, 2018 9:50 pm
by kieranhj
Rich Talbot-Watkins wrote:I feel like this can also be explained by the same issue as tricky's problem, here.

Have I understood right that you have a bunch of single line, single row CRTC frames (R4=0, R9=0), and then a block of rows to make the PAL frame up to 312? In the other thread, we have the observation that R4 needs to be changed before the final scanline; but if each CRTC frame *is* only one scanline, that doesn't give you any place to do it. So you'll get an extra row of R4=0 with the new R12/R13 (at the bottom), and then you'll get the big block of R4 as intended.

Or maybe your issue was just about setting R6 to 0 too late in order to start the bottom border (remembering that it needs to be set to 0 before the new frame starts in order to show nothing). If it were set too late, that'd show exactly one extra single line row, and then correctly disable display for the remaining rows of the PAL frame.

Does that kinda make some sense?
Yes, I think you're right, that would make sense. I have in effect 255 single line, single row CRTC frames then a block of 57 single line rows with just one visible (intended to be the 256th line) totalling 312 scanlines.

If R4=57-1 isn't being latched until the following scanline am I actually generating 313 lines here? It doesn't seem like it because I have timer 1 running at 312*64-2us without interrupts to always land on scanline 0. If this was out then the effects would surely fail to generate a proper PAL signal and break within a couple of seconds (on real HW.)

I never had any joy with R6=0 hence intending to catch the last visible scanline and add the extra 56 invisible scanline rows to it for the frame.

Hmmm, more real HW testing to do soon I think. (Weekend at this rate.)

On a separate topic, I've also been interested in what happens when you switch between low & high frequency ULA modes during the frame (or scanline.) It's quite a challenge to reprogram all of the CRTC registers in the right order before the counters are tested as the horizontal values are obviously doubled/halved as you switch between the two frequency modes so easy to overrun.

Re: Video Timing

Posted: Tue May 15, 2018 2:05 pm
by Rich Talbot-Watkins
kieranhj wrote: Yes, I think you're right, that would make sense. I have in effect 255 single line, single row CRTC frames then a block of 57 single line rows with just one visible (intended to be the 256th line) totalling 312 scanlines.

If R4=57-1 isn't being latched until the following scanline am I actually generating 313 lines here? It doesn't seem like it because I have timer 1 running at 312*64-2us without interrupts to always land on scanline 0. If this was out then the effects would surely fail to generate a proper PAL signal and break within a couple of seconds (on real HW.)
That's a good point. If you were generating 313 lines, I think most monitors would still lock to the signal OK, but I guess your effects would gradually roll upwards as the interrupt fired one line higher each frame. So let's assume you're generating 312 lines OK.

Just looking at .twister_draw in twister.asm - it looks like you actually have 254 lines, plus a 255th which also contains the flyback. LDX #2 here means that you loop 254 times (2 <= X <= 255); then after the loop, you set up for the 'special' last line, and then set R12/R13 ready for the top of the next frame. But with this weird CRTC effect, I think you're getting an extra 1 scanline CRTC frame, before the CRTC takes R4=56 and does the remainder of the PAL frame (57 lines). Which adds up to 312! And that's why you're seeing the top address echoed at the bottom for a single scanline.

This seems fairly compulsive evidence for this being a real 'thing', though the next question is - does every 6845 variant behave the same? For this we'd need to invite everyone with real hardware to try your demo and see what the results are...

---
Edit: I am mistaken, I think. I didn't count the first scanline which happens above the loop body. Shame. Though maybe there's something else we can extrapolate from my rambling.

Edit 2: Also, we don't see a similar effect when changing R4 back to 0 at the top of the screen. By this model, it wouldn't bother to check there (because VCC != R4 (56) at the beginning of the scanline) so we might expect it to keep going, but clearly it does indeed generate a one line frame at the top of the frame. Needs a rethink.

Re: Video Timing

Posted: Wed May 16, 2018 9:43 pm
by jms2
I don't know if this is in any way related to the video timing issues being discussed, but I tried out Frogger on my real Master today using the Gotek interface to load it. The results were odd: the screen display is perfect, and the game seems to play ok, but I am seeing no screen updates at all! in other words, I can press keys and hear the frog hopping about, getting killed etc but the "game over" screen is all I see. On an emulator the same image plays normally.

Re: Video Timing

Posted: Wed May 16, 2018 10:20 pm
by tricky
I think it must be a shadow ram issue.
Try turning shadow Ram off.

Ps I did put code in for WE Shadow ram, but as I had never had a master, assumed that Shadow ram was of by default.

Re: Video Timing

Posted: Thu May 17, 2018 5:49 am
by jms2
Good point, that makes sense! My Master does boot up into a shadow ram mode. Explains why it worked OK in Master mode on BeebEm.

EDIT: I have reconfigured it to boot to a non-shadow mode, but the problem persists. Definitely works OK in BeebEm (in Master mode).

I checked the value of HIMEM to be certain the machine isn't stuck in shadow mode, but it was fine. Very odd. :?:

Re: Video Timing

Posted: Sat May 19, 2018 5:21 pm
by jms2
Good news - I've managed to solve this problem! :D And I think it does shine some light on the video timing issue actually.

All I did was switch to a different TV (a Samsung Syncmaster 510MP). On this other TV everything works fine. So this means that the first TV (a Sony) wasn't entirely happy with the video signal it was getting from Frogger.

What I was seeing on the screen was everything looking good initially (cars moving) but then everything effectively froze. There was no screen rolling or jittering.

I hope this helps a bit.

Re: Video Timing

Posted: Sat May 19, 2018 6:21 pm
by tricky
Good news, Frogger should be correct for 50hz non-interlaced, but maybe the TV doesn't like non-interlaced at 50hz.
It may also be h-sync/v-sync timing that it isn't keen on, I'll try and find some docs.

In other news, I found another type of 6845 behavior today.
In frogger, only the first scanline of the timer is visible, it is then followed by either 7 or 8 lines of not screen.