BBC b, reading the CRT vertical sync position.

bbc micro/electron/atom/risc os coding queries and routines
Post Reply
User avatar
BadProgram
Posts: 35
Joined: Thu Mar 22, 2018 12:56 pm
Contact:

BBC b, reading the CRT vertical sync position.

Post by BadProgram » Tue Oct 22, 2019 7: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: 2875
Joined: Sat Sep 01, 2007 10:41 pm
Contact:

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

Post by RobC » Tue Oct 22, 2019 9: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: 349
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 3: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: 35
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 7: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: 881
Joined: Sat Sep 19, 2015 11:11 pm
Location: Farnham, Surrey, UK
Contact:

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

Post by kieranhj » Wed Oct 23, 2019 8: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: 4327
Joined: Tue Jun 21, 2011 9:25 am
Contact:

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

Post by tricky » Thu Oct 24, 2019 1: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: 35
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 7: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: 35
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

User avatar
Andrew_Waite
Posts: 227
Joined: Tue Aug 30, 2016 3: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 7: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.

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

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

Post by BadProgram » Thu Nov 14, 2019 3:57 pm

Thanks for the reply Andrew i shall read up on the shadow screen as it is another interesting way of dealing with synchronized graphics. I appreciate the suggestions greatly as they could fit a multitude of purposes and others might find them helpful to in the future.

With only a few objects moving i was favoring blanking and drawing alternative frames and that was fine to start with however, reading others modern and well wrote code has inspired me to think more modular, and in turn lead to a new problem (ill make a thread on it).

I hit a stumbling block with understanding the 6522 user VIA (also in a new post).

I will return to this once i have something more interesting, i have copied these replies and read them offline during a bbc session, thanks again.

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

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

Post by BadProgram » Sat Nov 23, 2019 3:37 pm

With the suggestions here i was able to get a 3x5 sprite moving around the screen with no parts being blanked out. And 5 x 3x5 on screen with flicker issues creeping in but this is to test limits before it would be require to turn to more professional methods demonstrated here by others.

The instructions provided before demonstrated very well where the congestion took place, giving a clear picture of what the
actual problem is (my basic games suffered it too, its great to know what it was). I was able to better use the fx19 sync and can draw enough stamps inside the loop to any screen position without fear of any mysterious blanking. I am very pleased thanks.

During the last month or so i was impressed by the code style seen here, i had a look at Jonathan Griffiths book (posted on a form here) and he said "the mark of a good assembler is that it will contain no absolute addresses in the assembler source code".

With that in mind i have been adapting to use constants outside of the assembler and the results are much better and quicker to write.

Too see what my limits are i made a large data block of 90 stamps (representing 6 frames of a 3x5 stamp) and this required rethinking the whole structure of an assembler program. Examples here gave me plenty of ideas resulting in a modular assembler program that deals with stamps away from the main program, one time so the data never needs to be recompiled and simply " *load"data" to dump it into memory from disk.

The final (god willing) program to be saved as one giant block on another disk if a master is ever required for sharing.

With the weight and artistry of vsync-ing animations on microcomputers better understood in my mind and the mysterious blanking banished,
i will spend the next winter months working more on program structure.

Thanks again for explanations and solutions.

User avatar
0xC0DE
Posts: 574
Joined: Tue Mar 19, 2019 7:52 pm
Location: The Netherlands
Contact:

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

Post by 0xC0DE » Sat Nov 23, 2019 8:58 pm

May I just add that I'm enjoying reading about your enthusiastic journey towards getting better at programming our beloved computers. It's giving me great joy as well
0xC0DE
:idea: Follow me on Twitter :idea: Visit my YouTube channel featuring my demos for Acorn Electron and BBC Micro

julie_m
Posts: 151
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

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

Post by julie_m » Sun Nov 24, 2019 4:46 am

Thanks, @BadProgram -- it means a lot to me, to think I have helped someone learn something.

One thing you can do when writing large assembly language programs is split the Source Code across several files, each of which not only assembles some code, but also contains a routine to create a dump of entry points and other variables which will be needed in the next program. This is what I did in my own project BCP which you can find on GitHub. There is a chunk of code towards the end of each source file that exports selected variables in a file you can *EXEC into another program. L

If your game runs in MODE 2, you might want to use PAGE=&3000 for your BASIC source, and assemble each chunk "in place" below &3000. You can then go back to PAGE=&1900 so you can use MODE 2 again, import the variable dump and test your graphics drawing subroutines from within a BASIC program to be sure they work correctly.

For example, your first file might just be a bunch of EQUB/EQUW/EQUD/EQUS statements for sprites, backgrounds, messages &c., with a few sparse labels for each one -- and you probably won't even need to export them all anyway, if they can be calculated knowing the address of just the first one, or you have a table giving their addresses and sizes. Your next file probably will have sprite and background drawing code, and the associated address-finding maths; and maybe score keeping. (Or if your background drawing code is particularly complex, you might want to take care of that before the sprites. It will depend on your program.) Again it shouldn't have to export much, because you will have pulled together all the loose ends from subroutines within your code -- calculate start position of sprite data, calculate start position of background data, calculate memory location in screen memory, draw sprite, erase sprite, draw background and so forth -- into just a few, more powerful entry points that combine these steps. You can then write a BASIC test suite, starting with the variable export file, to call these routines to make sure they work correctly.

In fact, if your final game runs through a BASIC wrapper, that wrapper will be built from the final variable dump.

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

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

Post by BadProgram » Mon Nov 25, 2019 5:59 pm

0xC0DE thanks, i viewed your "Racing the beam" demo, the scaling is brilliant, it looks like the kind of effects you might have seen on professional video processors in the 1980s for TV titles, but with arcade colours, its a very impressive effect.

Julie_m i had a good scan of your pcb project to see the style and picked up a few ideas i had not seen yet like adding variables to a save ( save "file"+data+~more ), it was nice to see a giant project that liberally uses acorn basic procedures.

It must be pleasing to design circuits on your micro computer, even if micros are now superseded, i tend to look at the great successes they did bring to the world and individuals, if it worked in their practice then it might still work now, and who knows it might even be more ascetically pleasing and quicker.

I am not confidant enough with the memory map to attempt a mode 2 program, right now i use mode 4 only committing to mono chrome (colour in future i understood the byte interleaving), with memory &5000 to &57FFF for stamp bytes and 2k for program code at &3000-&5000,machine instructions never having reached over 1k yet (and user zero page 70-8F for important variables).

From the structures ive seen in your PCB project, tricky's examples, Crazyrider source and others it seems the floppy disks capacity is the real limit when using many files.

I have copied the suggestions for mode 2 thanks for the comments.

Post Reply

Return to “programming”