dmb@TIS.COM (David M. Baggett) (09/29/88)
There was some discussion about Setscreen waiting for the vertical blank before returning. I tried a few things to see how Setscreen behaves in practice, and I still believe that Setscreen returns immediately. If Setscreen waited for the vertical blank when you set the physical screen base, the following code would take about 1 minute: for (i = 0; i < 3600; i++) { Setscreen((char *) -1L, Physbase(), -1); } It doesn't. It takes about 2 seconds. This means that Setscreen does _not_ wait for the vertical blank to return. It _is_ true that the physical screen base doesn't actually set until the vertical blank. This is because Setscreen simply writes a value into a location in page 4. The _vertical blank routine_ looks at this location and sets the physical base. We're talking about an interrupt here. So you do have to Vsync after setting the physcial screen to be sure you won't get flicker. To illustrate: C statement executed Status of VBI for (;;) { /* * Do stuff Yet to come */ Setscreen(...) Yet to come Vsync(); It happens /* * Do stuff Just finished (now */ previous Setscreen has taken effect) } If you don't explicitly Vsync, some of your Setscreen calls won't ever take effect (they will be "overwriten" by the next Setscreen call). Unless my compiler is different from everyone else's (I'm usnig Laser C), this is how Setscreen works. David Baggett dmb@TIS.COm (arpanet)
leo@philmds.UUCP (Leo de Wit) (10/01/88)
In article <8809282323.AA10646@TIS.COM> dmb@TIS.COM (David M. Baggett) writes: > > There was some discussion about Setscreen waiting for the vertical >blank before returning. I tried a few things to see how Setscreen >behaves in practice, and I still believe that > > Setscreen returns immediately. > > If Setscreen waited for the vertical blank when you set the >physical screen base, the following code would take about 1 minute: > > for (i = 0; i < 3600; i++) { > Setscreen((char *) -1L, Physbase(), -1); > } > >It doesn't. It takes about 2 seconds. This means that Setscreen does >_not_ wait for the vertical blank to return. This is correct. I did the same test. Well, I did put in onto the net also. > It _is_ true that the physical screen base doesn't actually set until >the vertical blank. This is because Setscreen simply writes a value into >a location in page 4. The _vertical blank routine_ looks at this location >and sets the physical base. We're talking about an interrupt here. No. This is not correct. The physical screen base *IS* altered immediately; the reason this has no effect until the next vertical blank is that the video counter that generates addresses pointing into the screen memory is still happily incrementing and will be reset to the new screen start location only when it is about to rebuild the next screen, i.e. at vbl time. This is hardware stuff, and has nothing to do with the code that the vbl routine consists of; you can try it for yourself by setting the vbl semaphore ($452): decrement the vbl semaphore making it negative; now the code inside the routine won't get executed, but still the screen start address is updated! Note: you must not disable the vbl itself by setting the status word, as this will effectively disable the interrupt and hence the refill of the video counter. I think you're mixing up some locations in page 4. $44e _v_bas_ad (logical screen base) $45e screenpt The first one is the logical base that is used by all routines that want to produce output to the screen. Having logical and physical screen different means you can prepare a picture in the first, while showing the old picture in the other. The second one, screenpt, is used in the vbl routine as follows: if screenpt is not zero, both the physical and logical screen base will be reset to this value. Note the physical screen base has no associated RAM location; it is set by filling in two I/O addresses, which correspond to the shifter's counting base register. Screenpt is *NOT* set by SETSCREEN! SETSCREEN sets either physical, logical base or resolution or any combination of the three. Only if the resolution is being set, SETSCREEN waits for a vbl. Screenpt could be used for animation, were it not that setting both logical and physical screen starts make it less usefull for that. > So you do have to Vsync after setting the physcial screen to be sure >you won't get flicker. To illustrate: > [example omitted]... Not quite true. In fact this can slow down fast animations considerably. If you generate new frames at a rate lower than the vbl frequency it's OK, but if you generate at a higher rate this means you'll have to wait each time for the vbl. You could argue you still can't display at a higher rate than the vbl, which of course is true, but not waiting for the vbl means in effect once and a while skipping a frame (as you indicated). The flicker does not result from not using Vsync but from writing in a screen memory that's being displayed. I posted this before, but some extra explanation won't harm: Most people use two screens when animating. This is ok if you synchronize by using Vsync(), but it leads to trouble when you don't. For clarity I introduce the notion of actual screen memory, which is the memory currently being addressed by the shifter. Having screen memories A and B: Actual A A A B Physical A B B B Logical B A A A ^ ^ ^ | | | time axis ---> SETSCREEN write log vbl etc. If the logical screen gets updated between a SETSCREEN and a vbl it also affects the actual screen (they're both A), so there's trouble. The solution is to use (at least one) extra screens, traversing them cyclic and having the physical screen walk 'one behind', viz.: Actual A A A B B Physical A B B B C Logical B C C C A ^ ^ ^ ^ | | | | time axis ---> SETSCREEN write log vbl SETSCREEN etc. It can be shown that having two SETSCREEN's within a vbl period still can lead to flicker; the solution is to use more screens, or to await the vbl if you already had two - the wait time now being much less than in the original case. Trial and error are good judges in these cases, along with your criteria for what looks nice on the screen and how much screen memory you have to waste. > Unless my compiler is different from everyone else's (I'm usnig >Laser C), this is how Setscreen works. Well, close. > David Baggett > dmb@TIS.COm (arpanet) Leo.