BBC b, reading the CRT vertical sync position.

Discuss all aspects of programming here. From 8-bit through to modern architectures.
Post Reply
User avatar
BadProgram
Posts: 14
Joined: Thu Mar 22, 2018 12:56 pm
Contact:

BBC b, reading the CRT vertical sync position.

Post by BadProgram » Tue Oct 22, 2019 6:43 pm

Hi, i am wondering how the CRT vertical sync position can be read ?. In my poor games moving characters will disappear in certain horizontal bands even when using *FX19. The few other documented bbc games seam to be reading the CRT draw position but i was not able to easily grasp how with all the other operations taking place.

Thank you.

RobC
Posts: 2709
Joined: Sat Sep 01, 2007 9:41 pm
Contact:

Re: BBC b, reading the CRT vertical sync position.

Post by RobC » Tue Oct 22, 2019 8:39 pm

Are you using BASIC or assembler?

If you're using assembler, there's a useful discussion around sprite plotting (with code) here.

It sets up a timer on each vsync interrupt that triggers as soon as the visible part of the screen has been rendered - this buys you back some time as vsync usually happens after the whole screen has been rendered.

As the timer decrements at 1MHz and each scanline takes 64uS to render, you could use a similar approach and then read the timer to work out how much of the screen has been rendered at any given time.

I suspect you're already aware of this but the key is not to be erasing or plotting on a scanline as it's being rendered. Something as simple as sorting your sprites by vertical position and erasing/replotting in that order can help a lot.

User avatar
scarybeasts
Posts: 165
Joined: Tue Feb 06, 2018 7:44 am
Contact:

Re: BBC b, reading the CRT vertical sync position.

Post by scarybeasts » Wed Oct 23, 2019 2:39 am

At the recent ABUG Cambridge, Jonathan Griffiths' talk was described his use of this technique in Rocket Raid :-)


Cheers
Chris

User avatar
BadProgram
Posts: 14
Joined: Thu Mar 22, 2018 12:56 pm
Contact:

Re: BBC b, reading the CRT vertical sync position.

Post by BadProgram » Wed Oct 23, 2019 6:17 pm

Thanks for the reply's, yes i use the built in acorn bbc 32k assembler.

I can read over the MovingSpritesMode2 txt file and hopefully find some tricks.

The twisted brain mega demo has some information on the subject, the most detailed ive seen so far.
viewtopic.php?t=15300

I also saw the fantastic presentation with by Jonathan Griffiths it was a treat.

The twistedBrain demo thread has a very handy map of the video registers, but it would seam that they only report
the amount of scan lines to be drawn and when it has.

My assembler programs are small, only comparing input from keyboard,mapping character data into screen positions via loops and blanking.
The poor results i get certainly point to there being a far more comprehensive way of dealing with vertical sync positions and interrupts,
perhaps demonstrated someone inside the large MovingSpritesMode2 demo.

thanks again.
Ps ive also viewed MrBroadhursts multi,multicolored spirte dmon, that just waits for the *fx19 and dose fine for that way of plotting.

User avatar
kieranhj
Posts: 822
Joined: Sat Sep 19, 2015 10:11 pm
Location: Farnham, Surrey, UK
Contact:

Re: BBC b, reading the CRT vertical sync position.

Post by kieranhj » Wed Oct 23, 2019 7:45 pm

(Sorry, only a quick reply as I’m on a train.)

Glad you found my write up useful. It’s not possible to read the vertical position of the raster from a CRTC register. *FX19 waits for the vertical sync interrupt which typically occurs a few rows after the end of the visible part of the screen has been displayed.

If your code to erase & redraw a sprite executes during the raster period then you will get those horizontal bands where the sprites seem to ‘disappear’. Basically the code to draw the sprite has executed after the raster has passed that point on the screen.

Sadly the Beeb isn’t very fast at drawing sprites, it takes a lot of work to copy the data to the screen when accounting for the character row addressing and pixels per byte etc. Plot routines take so long it’s quite likely you’ll end up catching the raster, even if you start the work in the vertical blank period after vsync (with *fx19).

There are a few solutions to this, varying in complexity and amount of work:

1. Double buffer the screen - most feasible on a Master with SHADOW RAM but can be done on a B in MODEs 4&5.
2. Erase and redraw your sprites one horizontal line at a time from top-to-bottom - works best if they are plotted EOR’d to the screen.
3. Sort your sprites by Y position to try and beat the raster (or split into top / bottom half of the screen plotting).
4. Use an IRQ timer to trigger your plot routines as soon as possible after the raster has passed the visible display on screen.
5. Split sprite updates across frames, e.g. erase & redraw odd numbered sprites one frame and even numbered sprites on the next frame.

One good trick is to use raster timing to check where the raster is on the screen whilst your code is executing. Simply set the background palette colour at the start and back to black at the end. E.g. in MODE 2:

LDA #&00+(1EOR7):STA &FE21
... run your sprite code...
LDA #&00+(0EOR7):STA &FE21

You should see a red band on the screen for the duration of the sprite plot taking place. You’ll notice that when your sprite is at the same position on the screen as the red bar then it will flicker / disappear. That’s because the code is running at the same time as the raster.

In general attempting to achieve sprite plotting at 50Hz on the Beeb is tough (ask Tricky!) but you can draw quite a lot at 25Hz and reduce the flicker with some careful coding.

Hope this helps. Good luck!
Bitshifters Collective | Retro Code & Demos for BBC Micro & Acorn computers | https://bitshifters.github.io/

User avatar
tricky
Posts: 3774
Joined: Tue Jun 21, 2011 8:25 am
Contact:

Re: BBC b, reading the CRT vertical sync position.

Post by tricky » Thu Oct 24, 2019 12:42 pm

You could reset one of the timers on the User VIA and read the high byte to know how much time is left (hence how far down the screen the beam is) , as used by Snapper to stop pacman flickering.
For my games, I usually have quite a few interrupts, mostly for palette changes or tricking the CRTC into clipping lines for me, but as a side effect I have a counter counting up every 16 scan lines.
For a game I might split the screen into 4 sections and then:
When the beam is at the end of the top section, I clear anything that needs clearing in the top section.
When the beam is at the end of the second section, I clear anything that needs clearing in the second section and draw anything in the top section.
When the beam is at the end of the third section, I clear anything that needs clearing in the third section and draw anything in the second section.
When the beam is at the end of the screen, I clear anything that needs clearing in the forth section and draw anything in the last two sections.
How much to split the screen up will depend on how tight the timing is, but this is usually enough.
For Frogger, I wait until the beam is half way down the screen and then start drawing from the top, handling the frog when I find it and just go flat out. The simplest frame is about 14ms and the heaviest 19.5ms so it never misses or catches the beam while on screen; actually, while the frog is jumping, it adds about .6ms so does just tip over 20ms, but catches back up on the first couple of frames when it lands.
For my simple sprite demo/sample, I think it uses the 1/4 screen chunks approach, but I can't be sure without checking.

User avatar
BadProgram
Posts: 14
Joined: Thu Mar 22, 2018 12:56 pm
Contact:

Re: BBC b, reading the CRT vertical sync position.

Post by BadProgram » Thu Oct 24, 2019 6:47 pm

Thank you Tricky and kieranhj for those well detailed explanations of various approaches to drawing, i will attempt to implement something from these great suggestions over the next weeks. Thanks for sharing your wisdom on the matter, Trickys work is hugely impressive and inspiring as is kieranhjs tour de force demo.

User avatar
BadProgram
Posts: 14
Joined: Thu Mar 22, 2018 12:56 pm
Contact:

Re: BBC b, reading the CRT vertical sync position.

Post by BadProgram » Wed Oct 30, 2019 9:48 pm

Thanks again, with those handy instructions posted before i was able to very easily see
where and why the disruption takes place and now its a matter of setting up a timer
to draw at the right time like was previously suggested.

This is a whole new area of game design for me so i will take a few weeks or longer
mulling over ideas, every time i see code on here new questions arise, like seeing
a 12 character label !, shorthand and acorn assembler quirks that look like a futuristic
version of C, its a marvel, although graspable via familiarity with acorn basic.

I was drawing just single pixels before when the banding was at its worst, but here
i used a 16X16 "stamp" for testing the idea of seeing raster disruption
via clever (as suggested before) mode changes.

Once ive got a tight loop going ill post back but it may be some time as i am only
in my 2nd year of 6502 programming. thanks.

Image

Andrew_Waite
Posts: 175
Joined: Tue Aug 30, 2016 2:58 pm
Contact:

Re: BBC b, reading the CRT vertical sync position.

Post by Andrew_Waite » Sat Nov 09, 2019 2:49 am

BadProgram wrote:
Tue Oct 22, 2019 6:43 pm
Hi, i am wondering how the CRT vertical sync position can be read ?. In my poor games moving characters will disappear in certain horizontal bands even when using *FX19. The few other documented bbc games seam to be reading the CRT draw position but i was not able to easily grasp how with all the other operations taking place.

Thank you.
Could you use video double buffering as an alternative to chasing the CRT beam? My game, Planet Nubium, uses the BBC Master's main and shadow memory as two separate video frame buffers, such that the Nth frame can be displayed by the video subsystem whilst the (N+1)th frame is being rendered by the CPU. Effectively, the Master is flipping from Mode 1 to Mode 129 or from Mode 129 to Mode 1 every cycle of the game loop.

One advantage of this technique is that the CPU does not need to be idled waiting for the raster to move off the screen.

This technique could also be used on the Model B or Electron, although memory limitations would limit a game to using the 10kbyte Modes 4 or 5, as 2x10kbyte frame buffers would be needed.

Post Reply