Current Scanline?

bbc micro/electron/atom/risc os coding queries and routines
Post Reply
User avatar
Diminished
Posts: 1242
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Current Scanline?

Post by Diminished »

I would like (on a Model B) to be able to read the current video scanline out of a register. Am I right in thinking that no such register exists?

Lacking one, how about starting a VIA timer at the top of every frame, and using that to count scanlines? Would you have to take complete control of the machine, in order to avoid the synchronisation between scanline and timer being ruined by the sporadic arrival of irrelevant interrupts?

Is there an established way of doing this?
gfoot
Posts: 987
Joined: Tue Apr 14, 2020 9:05 pm
Contact:

Re: Current Scanline?

Post by gfoot »

You may be able to use the light pen interface for that I think - you cause the relevant VIA pin to dip at the right time and the CRTC latches in the address it's currently outputting. Though I'm not sure if it latches the scanline.

But if you set up a VIA timer in sync with the frame then it will stay in sync forever, so yes that is another way. This is how my single-scanline scrolling and split screen demos worked - they babysat the timer quite a bit to get interrupts midframe, but you could equally just leave it set to expire once per frame.

You don't even need to synchronise the timer with vsync, you can just measure the skew once and then offset your calculations by that amount.

Interlacing offsets things as well so you need to either disable it or take account of it.

Edit, I remembered some of the numbers - one scanline takes 64us, there are 312.5 per field, so you can set T1 to 64*312.5 and it will fire at the same point every frame. In alternate frame it will be offset by half a physical scanline as the monitor starts halfway through a line on those frames. Noninterlaced is either 312 or 313 scanlines per frame, it will be obvious when you find it which!
VectorEyes
Posts: 573
Joined: Fri Apr 13, 2018 2:48 pm
Contact:

Re: Current Scanline?

Post by VectorEyes »

What gfoot said, basically. There's no register that will tell you the current CRTC scanline, but there are plenty of ways to set up a VIA timer that fires at a known point with respect to the vsync ... indeed with a bit of work you can get to the point where your 'timer interrupt' code starts once per frame, at a point which is perfectly in sync with CRTC, at whichever offset (out of the 40000 cycles per frame) you'd like.

Can you tell us what you're trying to achieve by being able to read the current scanline?
User avatar
Diminished
Posts: 1242
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Current Scanline?

Post by Diminished »

Many thanks. Is there any sample code for any of this stuff I can look at? I'm not really confident with interrupt handling.
gfoot wrote: Fri Dec 22, 2023 8:05 pm Interlacing offsets things as well so you need to either disable it or take account of it.
Hmm .. is there a disadvantage to disabling interlacing? Does that knock you down to 25 fps from 50? Are there compatibility problems with old SD TVs or anything like that?
VectorEyes wrote: Fri Dec 22, 2023 8:28 pm Can you tell us what you're trying to achieve by being able to read the current scanline?
To avoid flicker/tearing. Suppose you have a sprite routine that pokes a sprite into video RAM at some point (X,Y). It would be nice to know if (X,Y) is currently in the process of being sent to the screen. If it is, then you could busy-wait for the electron beam to pass. Better, you could mark the sprite as "deferred" somehow, maybe push it onto the stack and increment a counter, while you get on with something else. Then have a cleanup routine that will draw any missed sprites later.
User avatar
TobyLobster
Posts: 622
Joined: Sat Aug 31, 2019 7:58 am
Contact:

Re: Current Scanline?

Post by TobyLobster »

Diminished wrote: Fri Dec 22, 2023 9:00 pm Many thanks. Is there any sample code for any of this stuff I can look at? I'm not really confident with interrupt handling.
Introduction to interrupts (two parts):
https://www.youtube.com/watch?v=GouduAdUa4s
https://www.youtube.com/watch?v=Eu9mSQPS2g8
Diminished wrote: Fri Dec 22, 2023 9:00 pm Better, you could mark the sprite as "deferred" somehow, maybe push it onto the stack and increment a counter, while you get on with something else. Then have a cleanup routine that will draw any missed sprites later.
I used this idea on one of my projects. Given a list of sprites to draw, I draw any sprites that can safely be drawn and mark them as 'drawn this game tick'. By the time that's done, the current scanline will have moved on, so I go back and try again to draw any as yet undrawn sprites. Repeat this process until there are no more undrawn sprites.
User avatar
tricky
Posts: 7709
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Current Scanline?

Post by tricky »

There are several ways to achieve what you want, but which are more suitable friends on how many stories you have, what they are doing and what sort of background they are on.
I think snapper used a timer to track the current scan line to stop the player sprite from flickering.
I generally either draw when the beam is off screen or split the screen in to four horizontal strips and only draw in one once the beam has passed.
Those videos should have everything you need, but fell free to ask more questions, hopefully someone else might get inspired.
gfoot
Posts: 987
Joined: Tue Apr 14, 2020 9:05 pm
Contact:

Re: Current Scanline?

Post by gfoot »

Diminished wrote: Fri Dec 22, 2023 9:00 pm Many thanks. Is there any sample code for any of this stuff I can look at? I'm not really confident with interrupt handling.
This post has some code to read the light pen registers and decode it to an X,Y position in CRTC characters, which is sufficient I think for what you're doing, you only need the vertical result and don't care too much about the granularity. This doesn't require interrupts at all, though the test program it appears in probably uses them.

Earlier in that thread is a much more complex program using interrupts and VIA timers to time specific points in the frame, in an interlaced mode. You won't need most of it but it might help a bit seeing how those things are set up - it gets things fully in sync with the vsync.
Hmm .. is there a disadvantage to disabling interlacing? Does that knock you down to 25 fps from 50? Are there compatibility problems with old SD TVs or anything like that?
I don't know about old TVs (actually does that work on real CRT TVs at all?) but disabling interlacing was common on games console in the 80s I believe so anything after that point should be fine, certainly on monitors it is fine. The image is slightly less solid, more "scanliney", but doesn't shimmer up and down any more.
SteveF
Posts: 1683
Joined: Fri Aug 28, 2015 9:34 pm
Contact:

Re: Current Scanline?

Post by SteveF »

Diminished wrote: Fri Dec 22, 2023 9:00 pm Many thanks. Is there any sample code for any of this stuff I can look at? I'm not really confident with interrupt handling.
My Blinkenlights toy might be helpful to take a look at.

It uses a VIA timer to track the current (text, not individual pixel) raster row. See the code mentioning inverse_raster_row in animate.asm. It initialises an internal counter on VSYNC and decrements it every character row's worth of time using a VIA timer.

Disclaimer: I wrote this having watched Kieran's tutorial, I am not an expert on this stuff and I may have done something wrong. The nature of the visual display produced is that it's not necessarily trivial to spot tearing if it happens (i.e. not trivial to spot if my code is buggy and not doing what I thought). But I think it does probably work. I only ever tested it under emulation but I don't remember anyone reporting tearing on real hardware, though maybe no one noticed or they were too polite to complain about my code. :-)

I suspect you could also reset the VIA timer on vsync and read the current timer value to determine the current pixel scanline (so there would be no VIA timer interrupt, just the VSYNC interrupt used to set the timer to a known value), but maybe I'm missing something. I didn't do it that way anyway!
User avatar
jgharston
Posts: 5332
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: Current Scanline?

Post by jgharston »

gfoot wrote: Fri Dec 22, 2023 8:05 pm Edit, I remembered some of the numbers - one scanline takes 64us, there are 312.5 per field, so you can set T1 to 64*312.5 and it will fire at the same point every frame.
Who do we have to go back in time and thank for ensuring scanlines were an exact power of 2 microseconds? It makes so much video stuff so much easier. :) Exactly 1MHz per display cycle, exactly 8MHz per pixel, etc., display and sync signals easily generated from NAND logic from a binary counter, etc.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.45
(C) Copyright J.G.Harston 1989,2005-2024
>_
User avatar
tricky
Posts: 7709
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Current Scanline?

Post by tricky »

Except mode 7 ;)
I can't think of a reason for non-interlaced not too work, if anything interlaced is more tricky on modern hardware.
The trick of interlace is that the beam moves down at a constant rate, so waiting half a scan line just means it starts lower and half way across the screen which means that it has to sort itself out by the time you can see anything!
You could set the user via T1 in continuous mode and just read the high byte which will be in chunks of 4 scan lines, but counting down.
There are a few ways to sync to vsync, but if you allow for some error margin, the assembler version of *FX 19 will probably be good enough.
User avatar
BigEd
Posts: 6277
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: Current Scanline?

Post by BigEd »

jgharston wrote: Sat Dec 23, 2023 2:56 am
gfoot wrote: Fri Dec 22, 2023 8:05 pm Edit, I remembered some of the numbers - one scanline takes 64us...
Who do we have to go back in time and thank for ensuring scanlines were an exact power of 2 microseconds? It makes so much video stuff so much easier...
I think it was easier back in the day to divide (or multiply?) high frequencies by successive small odd numbers, and that has something to do with it, although of course some tradeoffs and arbitrary choices must have been made... so the question still stands... oh dear I've gone down a rabbit hole...

To get 64us, we calculate ((fields per frame)/(fields per second))/(lines per frame) which is (2/50)/625.

This doesn't work out so nicely with the earlier 405 lines, or with NTSC's 525 lines, or with the USSR's 441 lines or with other early choices... but it seems the first choice of 625 lines was made in Moscow perhaps with much (semi-coerced) (East) German technical input:
The proposed standard provided for 625 scan lines, good enough to compete with 16 mm film. Dividing this number by 5 two times provided frame frequency neatly aligned with 50 Hz mains AC power. Horizontal frequency, calculated by multiplying this number by 5 two times fell within 1% of the horizontal frequency of the newly adopted 525-line NTSC television standard. This opened a possibility of buying off-the shelf equipment from the United States and using it with minimal modifications.
and
This explains why a 567-line format announced by Philips in 1948 was abandoned and forgotten by 1950. Philips fully supported the 625-line format because it offered costs savings when designing equipment both for the European and for the American market.
It seems the decision was implemented (by the Soviets) in East Germany, then West Germany felt compelled to follow, and the Swiss were brought in to promulgate it as a European standard. The BBC followed, although note that the British were involved in running the new West Germany, so the BBC were surely there near the beginning.
The aim of the British [in setting up NWDR in Hamburg] was to foster a massive monopoly, conscious of its standing and responsibility as an impartial independent public service.


Perhaps at the transmission side you start with a very high frequency master clock which is divided down for the Hsync and Vsync. You need to hit 50Hz or (originally) 60Hz with an odd number of lines, in order to get the half-lines which deliver interlace.

But at the receiver side, perhaps, you start with 50Hz and use some technique of frequency multiplication by small odd numbers to make a local line frequency which can then lock to the received signal. Maybe this is a crucial constraint? See perhaps here and here.

Edit: old telly website pretty much says receivers don't do any frequency multiplication or division.
User avatar
Diminished
Posts: 1242
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Current Scanline?

Post by Diminished »

Thanks enormously, everyone. I would like to go through these replies properly, but I'm pretty busy right now. (I am typing this post with one hand while I eat a sandwich with my other ...)
tricky wrote: Sat Dec 23, 2023 7:37 am You could set the user via T1 in continuous mode and just read the high byte which will be in chunks of 4 scan lines, but counting down.
There are a few ways to sync to vsync, but if you allow for some error margin, the assembler version of *FX 19 will probably be good enough.
This is more or less now what I'm trying to do.

Here's some sample beebasm code (photosensitive epilepsy warning):
scanline.s.txt
(1.53 KiB) Downloaded 4 times

Code: Select all

org &1900

zp_old_irq1v_L      = &71
zp_old_irq1v_H      = &72
zp_timer_started    = &73
IRQ1V               = &204

.top
.start

  ; MODE 4
  LDA   #22
  JSR   &FFEE
  LDA   #4
  JSR   &FFEE

  LDA   #0
  STA   zp_timer_started
  
  ; disable interlacing
  LDA #8
  STA &FE00
  LDA #0
  STA &FE01
  
  ; install ISR
  SEI
  LDA   IRQ1V
  STA   zp_old_irq1v_L
  LDA   IRQ1V+1
  STA   zp_old_irq1v_H
  LDA   #LO(S_ISR)
  STA   IRQ1V
  LDA   #HI(S_ISR)
  STA   IRQ1V+1
  CLI
  
  CLC
.P_main
  LDA   &FE65               ; get timer high byte
  AND   #&7
  JSR   S_set_bgcolour      ; VDU 19
  BCC   P_main
  
.S_set_bgcolour
  EOR   #7
  STA   &fe21 ; 000
  ORA   #&10
  STA   &fe21 ; 001
  ORA   #&20
  STA   &fe21 ; 011
  ORA   #&40
  STA   &fe21 ; 111
  EOR   #&10
  STA   &fe21 ; 110
  EOR   #&20
  STA   &fe21 ; 100
  ORA   #&10
  STA   &fe21 ; 101
  EOR   #&70
  STA   &fe21 ; 010
  RTS

.S_ISR
  LDA   &FC
  PHA

  ; VSYNC?
  LDA   &FE4D
  AND   #&2
  BEQ   L_isr_ret           ; no
  
  ; yes
  LDA   zp_timer_started    ; timer already running?
  BNE   L_isr_ret           ; yes
  
  ; no
  LDA   #&40                ; parkour mode ...
  STA   &FE6B               ; ACR
  
  LDA   #0                  ; no timer interrupts, thanks
  STA   &FE6E               ; IER

timer_latch = &20000
  LDA   #LO(timer_latch - 2)
  STA   &FE64
  LDA   #HI(timer_latch - 2)
  STA   &FE65
  
  ; mark timer as running
  DEC   zp_timer_started
  
  BNE   L_isr_ret           ; done
  
.L_isr_ret
  PLA
  STA   &FC
  
  JMP   (zp_old_irq1v_L)

.end

SAVE "SCAN", top, end, start

This uses an ISR to start the timer at vsync (once) with the value 20000 (minus 2), then runs the timer in continuous mode (the ISR is irrelevant from here onwards). The main loop at P_main takes the timer's high byte, ANDs it with 7, and then tries to change the MODE 4 palette, to stripe the screen.

Sure enough, that works, and the positions of the horizontal stripes seem to be stable (modulo some noise). However, the stripes' colours are not stable, and I don't understand why. I would have expected the timer to take the same values with respect to to the Y-coordinate on every frame, but it seems that isn't the case.

I expect a stupid mistake has been made.

Screenshot 2023-12-23 at 12.56.16.png
User avatar
jgharston
Posts: 5332
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: Current Scanline?

Post by jgharston »

tricky wrote: Sat Dec 23, 2023 7:37 am Except mode 7 ;)
Still works if you start at exactly 6MHz per pixel, divide by 6, exactly 1MHz per display cycle, count until bit 6 triggered, exactly 64us per scan line. :)
Something I typed up years ago when trying out some designs to replace a 6845 with non-programmed hardware (I was trying to design a SAA5050 stand-alone display system):

Code: Select all

        00  04  08  12  16  20  24  28  32  36  40  44  48  52  56  60
           03  07  11  15  19  23  27  31  35  39  43  47  51  55  59  63
      __________________________________________________    _________________________
        :                 48us                          | 4 |    12us   :
  HS    :                                               |___|           :
      _________________________________________________            __________________
        :                 47us                         |   12us    | 5us:
  DIS   :                                              |___________|    :
        ________________________________________                        _____________
        |                 40us                  |   8us :     16us      |
  DEN  _|                                       |_______:_______________|

This allows us to generate the DEN and HS signals directly from the counter:

count/4 00  01  02  03  04  05  06  07  08  09  10  11  12  13  14  15
  HS    ------------------------------------------------XXXX------------
  DEN   XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX------------------------

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.45
(C) Copyright J.G.Harston 1989,2005-2024
>_
User avatar
jgharston
Posts: 5332
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: Current Scanline?

Post by jgharston »

BigEd wrote: Sat Dec 23, 2023 8:16 am Perhaps at the transmission side you start with a very high frequency master clock which is divided down for the Hsync and Vsync. You need to hit 50Hz or (originally) 60Hz with an odd number of lines, in order to get the half-lines which deliver interlace.

But at the receiver side, perhaps, you start with 50Hz and use some technique of frequency multiplication by small odd numbers to make a local line frequency which can then lock to the received signal. Maybe this is a crucial constraint?
Yes, with valve technology, a divide chain of prime numbers is easier, so 625 comes from 5*5*5*5, the USA's 525 comes from 3*5*5*7. An advantage of 625 is the divider chain is four identical units, with 525 you have three different dividers.

And with 525, the line period is 63.9something, which is close enough to 64 that you can pretend it's 64 and use a 6-bit counter for timing, and just feed a slightly over-frequency clock to the circuitry.

Gawd, this is dragging old memories out. :)

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.45
(C) Copyright J.G.Harston 1989,2005-2024
>_
gfoot
Posts: 987
Joined: Tue Apr 14, 2020 9:05 pm
Contact:

Re: Current Scanline?

Post by gfoot »

Diminished wrote: Sat Dec 23, 2023 1:02 pm Thanks enormously, everyone. I would like to go through these replies properly, but I'm pretty busy right now. (I am typing this post with one hand while I eat a sandwich with my other ...)
Impressive!

A couple of things that jumped out:

Code: Select all

  ; disable interlacing
  LDA #8
  STA &FE00
  LDA #0
  STA &FE01
Disable interrupts while you do this sequence, as the OS might jump in and set a different register active.

Code: Select all

.S_ISR
  LDA   &FC
  PHA

  ; VSYNC?
  LDA   &FE4D
  AND   #&2
  BEQ   L_isr_ret           ; no
  
  ; yes
  LDA   zp_timer_started    ; timer already running?
  BNE   L_isr_ret           ; yes
At this point you didn't really need an ISR, I think - as it looks like right now you're catching the first vsync interrupt, but then ignoring all interrupts after that point. You could instead just sit with interrupts disabled on startup waiting for a vsync (tested via &FE4D as above), then start your timer.

Code: Select all

  LDA   #0                  ; no timer interrupts, thanks
  STA   &FE6E               ; IER
This doesn't disable any interrupts. The way the IFR and IER work is that you set the bottom 7 bits to a mask of which bits in the register you want to change, and the top bit to the value you want them to have. So what you're doing here is disabling no interrupts. To disable the T1 interrupt you want &40 (top bit clear, T1's bit set). I've attached a 6522 cheat sheet below in case it's helpful for reference, I made it when I got fed up of paging back and forth through datasheets!

Code: Select all

timer_latch = &20000
I'm not sure why you used this value. You need to wait for 312 scanlines of 64 cycles each, if you want the timer to stay in sync with the display. So set this to 312*64. This is probably why the colour cycle.

Edit - I put your code into bbcmic.ro and fixed the timer_latch value to demonstrate, see here: https://bbcmic.ro/#%7B%22v%22%3A1%2C%22 ... %5Cn%22%7D
Attachments
6522_quickreference.png
User avatar
BigEd
Posts: 6277
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: Current Scanline?

Post by BigEd »

From vague memory is there an offset of 2 counts needed when using VIA timers? So 10ms is a count of 9998 IIRC
User avatar
tricky
Posts: 7709
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Current Scanline?

Post by tricky »

Yes, of you are running in continuous mode as it takes 2 cycles to reload the latches values. I think we have richtw to thank fire funding this out.
User avatar
Diminished
Posts: 1242
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Current Scanline?

Post by Diminished »

gfoot wrote: Sat Dec 23, 2023 2:17 pm A couple of things that jumped out:

Code: Select all

  ; disable interlacing
  LDA #8
  STA &FE00
  LDA #0
  STA &FE01
Disable interrupts while you do this sequence, as the OS might jump in and set a different register active.
This hadn't crossed my mind.
At this point you didn't really need an ISR, I think - as it looks like right now you're catching the first vsync interrupt, but then ignoring all interrupts after that point. You could instead just sit with interrupts disabled on startup waiting for a vsync (tested via &FE4D as above), then start your timer.
You're right -- and I was aware of this, but this sample of code was extracted from something more complicated, so I had the scaffolding in place for setting up a vsync ISR anyway.
This doesn't disable any interrupts. The way the IFR and IER work is that you set the bottom 7 bits to a mask of which bits in the register you want to change, and the top bit to the value you want them to have. So what you're doing here is disabling no interrupts. To disable the T1 interrupt you want &40 (top bit clear, T1's bit set). I've attached a 6522 cheat sheet below in case it's helpful for reference, I made it when I got fed up of paging back and forth through datasheets!
Thanks. I suspect this was a victim of "shotgun debugging", where in desperation I started changing code that was probably correct to start with ...

Code: Select all

timer_latch = &20000
I'm not sure why you used this value. You need to wait for 312 scanlines of 64 cycles each, if you want the timer to stay in sync with the display. So set this to 312*64. This is probably why the colour cycle.
Thank you. I have no idea where I got this value from, either. I think it was actually meant to be 20000 decimal and not hexadecimal, which is closer, but still wrong ...
Edit - I put your code into bbcmic.ro and fixed the timer_latch value to demonstrate, see here:
Much appreciated, thank you. Unfortunately my code for which this technique was intended (the VCCC2023 "Wild" category) ended up being submitted to Logiker without any flicker mitigation, as I simply ran out of time to implement the technique (as well as about six other things) :(
Last edited by Diminished on Mon Dec 25, 2023 12:36 am, edited 1 time in total.
User avatar
Diminished
Posts: 1242
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Current Scanline?

Post by Diminished »

TobyLobster wrote: Fri Dec 22, 2023 9:30 pm Introduction to interrupts (two parts):
https://www.youtube.com/watch?v=GouduAdUa4s
https://www.youtube.com/watch?v=Eu9mSQPS2g8=
This was really good, thanks (and thanks to Kieran). I was fine with using interrupts on microcontrollers, but I have just never quite grasped how they interacted with MOS on the Beeb, because of the way they vector through ROM. Basic concepts like IRQ1V meaning "go before the MOS" and IRQ2V meaning "go after the MOS" were completely opaque to me before watching this. "Primary interrupt vector" and "Secondary interrupt vector" aren't particularly helpful terms ...
gfoot
Posts: 987
Joined: Tue Apr 14, 2020 9:05 pm
Contact:

Re: Current Scanline?

Post by gfoot »

Diminished wrote: Mon Dec 25, 2023 12:28 amThank you. I have no idea where I got this value from, either. I think it was actually meant to be 20000 decimal and not hexadecimal, which is closer, but still wrong ...
Ah yes, 20000 decimal is indeed 64*312.5, which would be correct in interlaced mode.
User avatar
Diminished
Posts: 1242
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Current Scanline?

Post by Diminished »

Diminished wrote: Fri Dec 22, 2023 9:00 pmSuppose you have a sprite routine that pokes a sprite into video RAM at some point (X,Y). It would be nice to know if (X,Y) is currently in the process of being sent to the screen. If it is, then you could busy-wait for the electron beam to pass. Better, you could mark the sprite as "deferred" somehow, maybe push it onto the stack and increment a counter, while you get on with something else. Then have a cleanup routine that will draw any missed sprites later.
Well, thanks to Logiker granting me an extra day to finish my wildcard submission, I had enough time to implement this in my demo entry for VCCC2023. It's switchable, so you can build the demo's code with or without this mitigation. The demo's disc image contains both builds.

You will have to wait a few days to see the effect, but the results are very interesting I think. The idea I mention above does seem to work, but IMO it produces less pleasing results for this particular application than simply letting the sprites go ahead and flicker. (I am not entirely convinced there isn't still a bug in the implementation).

I need to see both versions on a CRT, so another guerilla mission to CfCH with a cassette lead and a phone might be in order.
User avatar
Diminished
Posts: 1242
Joined: Fri Dec 08, 2017 9:47 pm
Contact:

Re: Current Scanline?

Post by Diminished »

I suppose I should update this thread

Compare

(a) no defence (drawing occurs regardless of current beam position, trace violations be damned):

https://www.youtube.com/watch?v=komh0jJgaP4


to (b) deferral (asterisks that would violate the trace are pushed to the stack and drawn later):

https://www.youtube.com/watch?v=0TSk2dBFFak


Of course (b) still flickers a bit, because deferred asterisks may violate the trace when they are drawn post-hoc -- I didn't bother trying to mitigate these "second-order" effects. Nevertheless, the amount of flicker is severely reduced (I did have figures for this, obtained by stepping through both videos frame-by-frame, but I've lost them and I no longer care enough to find them).

However, video (a) clearly moves more smoothly than video (b), despite the flicker. There is a pronounced jerkiness to the animation where the deferral strategy is used, particularly for asterisks on the circumference of the shapes (which move by ~3 pixels or so each frame). I can think of ways I might have been able to improve this, too, but whatever.

I thought the results were interesting, anyway.

I've attached the submission ZIP with the beebasm source; you can build it either way using the BEAM_AVOIDANCE switch.

Overall I was impressed that the Beeb could spin the thing at about 18 fps, even with my lacklustre 6502 asm.

Thanks to everyone who contributed to this thread.
Attachments
YuleGetDizzy_Diminished_WILD_BBCmicro__VERSION_2.zip
(269.46 KiB) Downloaded 3 times
User avatar
tricky
Posts: 7709
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Current Scanline?

Post by tricky »

That's a nice demo and a good test need for you flickering avoidance code.

I would say it needs double buffering to remove the flicker, but that should be ok in mode 4.

I do have a fast sort, but that won't help if it isn't running at 50fps and 32 is a practical limit anyway.
Post Reply

Return to “programming”