Tips: Video Synch

by Denis Pelli

VideoToolbox
PsychToolbox
Tips
 
speed
displays
how to
mac software
bibliographies

visitors since September 17, 1996.
June 1, 2000

You might want to start by reading my recent article, which incorporates most of the information on this page:

Pelli, D.G. (1997) The VideoToolbox software for visual psychophysics: Transforming numbers into movies. Spatial Vision 10:437-442 (HTML)

VIDEO BUGS

CONTRIBUTORS to the VideoSynch,VideoBugs, & VideoSpeed pages.

The VideoToolbox allows you to produce accurately controlled visual stimuli. This document deals with time; how to make sure each video frame shows what you want. After reading this document, you'll probably want to look at the accompanying Video bugs document, and run the TimeVideo program on your Mac, to give all your video cards a thorough workout and learn their timing characteristics. If you have many computers, put TimeVideo on a floppy and run it from the floppy on each machine; all the results will accumulate in a single report file. I am always glad to receive copies of the TimeVideo report on new machines.

MOVIES. It's easy to show movies on a Mac. Create all your GWorlds in memory ahead of time, and then call CopyWindows() to copy one image after another to the screen (e.g. try the demos NoiseVBL or SandStorm). For any serious application you'll want a real-time movie, one image per video frame, so you'll want to wait for a new frame before copying each image, using one of the synchronization techniques described below (e.g. try the demo NoiseVBL). (Incidentally, some people have mistakenly assumed that page switching is the ONLY way to achieve a real-time movie. It's not. Video cards serially display the image pixels one by one during most of the frame period, e.g. 15 ms. If your computer starts writing at the beginning of the new frame and writes the pixels faster than they're displayed you'll display a whole new image on each frame.) How big a movie you can show in real time will depend on how fast your processor is. TimeVideo does this timing for you, telling you what fraction of the screen you can fill with a real-time movie. If you can't do a full-screen movie and you need to show multiple patches, consider showing several small movies, updating only the dynamic parts of the screen. (We assume that you are not limited by memory, and therefore do not discuss Apple's QuickTime, whose principal purpose, beyond making movies portable, is to minimize storage requirements by using image compression.) The Video Speed page lists data rates for showing movies on a few machines.

SPRITES. If you want to show objects moving around the screen, and your computer isn't fast enough to do a full screen movie, then you may want to animate just the objects. Objects animated in this way are called "sprites". You can download the free library called SpriteWorld2.

PAGE SWITCHING. Many video cards have multiple video pages; check your TimeVideo report, or call GDGetPageCnt(). Normally the Macintosh only uses page 0, but if you have multiple pages, they can be switched by calling GDSetPageShown() and GDSetPageDrawn(). This could be used to show very short full-screen movies, e.g. alternating two images. This might be an effective way to show large slow movies, taking several frames to load each new image to an unseen page that's instantly swapped in when it's full. (The number of pages available depends on the pixel size. In max depth there's always only one page. In lesser depths there's unused memory, which the video driver may make available as extra pages.) Sergei A.Kurkin, has "tested GDSetPageDrawn() and GDSetPageShown(), and they seem to work OK."

Sadly, most drivers only support 1 page, which is very disappointing. There is some new apple software for page flipping, which i haven't tried yet. The DrawSprockets library includes a SwapDisplayBuffers routine that is supposed to do page flipping on video drivers that support it. However, I don't know if there are any video drivers that do support it. (The Sprocket documentation doesn't say what call the video driver must support.) The Apple Games Sprockets software is available for downloading.

CLUT (Color Lookup Table) ANIMATION. Most video cards have a hardware color lookup table (clut) that dynamically transforms each pixel to a color (an RGB triplet) that is sent to the digital to analog converters. Temporal modulation (e.g. flicker or fading on and off) of visual stimuli can be achieved very conveniently by loading a new clut on each frame. Look at the demo FlickeringGrating. However, not all video card drivers are fast enough to achieve this. (Usually this is not a hardware limitation; it's crumby driver software.) Run TimeVideo to find out for sure; it determines how many frames it takes either GDSetEntries or SetEntriesQuickly to load the clut. The clut is also used for gamma correction. Apple's provision for gamma correction is somewhat crude; for the utmost luminance accuracy you may wish to use the Luminance.c routines. See section B, below.

COLOR CYCLING Bart Farell writes, "It's easy to do color cycling using either GDSetEntries or SetEntriesQuickly, e.g. GDSetEntries(device,start,count,table+offset); First create a double-sized ColorSpec array, e.g., an array of 512 instead of 256. It's called "table" in the above example. Set up the second half of the array to be identical to the first half, to implement wrap-around. GDSetEntries/SetEntriesQuickly(), as always, loads "count+1" entries starting at entry "start". (Yes, "count+1", that's Apple's confusing convention.) Just add an integer "offset" to the table pointer. GDSetEntries/SetEntriesQuickly() will start reading the table, offset by that number of ColorSpecs. Across a sequence of frames, using a different offset for each call to GDSetEntries or SetEntriesQuickly(), each ColorSpec of the array can be loaded to any entry. In practice you'd create several of these double-sized ColorSpec arrays and animate by using a different array and offset on each frame. The payoff is that the number of arrays, and clut computation time, is an order of magnitude lower than would be required to compute a custom clut for each case."

MAKING DYNAMIC WHITE NOISE. I know of at least three people (including myself) that hit upon clut animation as a fast way to synthesize dynamic white noise. You fill the image plane with random numbers in the range 0 to 255, and you load a new random clut on each frame. It might seem that this will produce noise that is spatially and temporally uncorrelated. Not quite. Any pair of pixels has a 1/256 chance of being driven by the same clut entry, in which case they will be perfectly correlated. So the spatial autocorrelation function has the (desired) delta function at zero separation and an (undesired) 1/256 correlation at all other separations. This corresponds to the desired flat spectrum, plus an undesired delta function at zero spatial frequency. In plain English, you'll end up with dynamic white noise plus a spatially-uniform temporally-white flicker. (This problem does not arise if you only use each clut entry once, but that restricts you to an image of only 16x16.) Note that I am only discussing first and second order statistics. Higher-order statistics will still differ from truly white noise, but I doubt that our visual systems are sensitive to the difference. However, the spatially uniform flicker component of the clut animation noise is visually very salient. Ted Adelson noticed it immediately when I proudly demonstrated this method at Optical Society in San Diego in 1989 (I think). The artifactual flicker becomes progressively more salient as you increase the viewing distance, since the spatially uncorrelated noise fades out while the spatially uniform noise is unaffected. What I now do, and recommend to others, is to use brute force. Precompute all the noise and show a movie in which all the pixels are truly independent random samples. The VideoToolbox routine RandFill() is a fast way to compute the noise, and is used by NoiseFill.c. Try the demos Sandstorm and NoiseVBL.

FANCIER TRICKS. The video card has only one clut, but it is possible to simultaneously present multiple independently modulated patterns, by reserving separate sections of the clut for each temporal modulation, though you'll suffer a comensurate loss of intensity resolution. Clut animation is not restricted to dynamic modulation of contrast. If the pixel values represent phase, and the clut is loaded with a sin function, then rotating the clut entries--i.e. setting the i-th entry to what was formerly the value of the i-1 entry (see Color Cycling, above)--will shift the phase of the pattern. A spatially vignetted drifting grating may be synthesized by using alternate pixels (or frames) to represent vignetted sin and cos components of the pattern, devoting half the clut to each (or loading alternate cluts on alternate frames). Appropriate adjustment of the relative contrasts of the sin and cos components will produce any desired phase of the sum. However, most of these tricks are superfluous; it's usually easier and better to just show a movie. Many current processors are fast enough to show 8-bit full-screen movies.

A. HOW TO SYNCHRONIZE A PROGRAM TO A VIDEO CARD.

The hardest part in doing vision experiments is synchronizing the computer program to the video card. Nearly all video cards are masters, and run freely, expecting the video monitor to be a slave. Any experiment that cares about timing will normally have to synchronize itself to the video card, by waiting for each frame to end, as will be discussed below.

You typically can't access the video card hardware directly, because it's undocumented. Instead you are allowed to send requests to the video driver associated with your video card. All video cards that plug into the Mac come with video drivers that conform sufficiently well to the Apple guidelines that they are at least minimally compatible with the VideoToolbox. However, some drivers have outright bugs, and the timing of many drivers, for which Apple does not publish guidelines, sometimes makes it surprisingly difficult to do simple things. A current list of these bugs and "features" appears in the VideoToolbox "Video driver bugs" document.

Every video card has a video driver in its ROM, but the manufacturer may supply a newer driver by floppy that supercedes the one in ROM, which may be buggy. (Built-in video devices, e.g. in the Mac IIci and Quadra computers, load the video driver from the computer's ROM.) Apple distributes video driver updates as resources in the System file, so updating your System may change the video driver of your Apple video card. IdentifyVideo(device) returns a string with the name and version number of the driver that is actually in use. Try TimeVideo.

There are 4 ways to synchronize a program to a video card:

  1. Apple recommends using the vertical blanking interrupts, which are supposed to occur once per frame, at the beginning of the vertical blanking. The VideoToolbox VBLInstall.c routines make this very easy to do. A disadvantage of this approach is that it fails if you raise the processor priority to block all interrupts.
  2. Most (not all) video drivers, when asked to load the clut, wait until the vertical blanking interval before beginning to load the clut. (They wait in order to avoid creating visible hash on the screen while the clut is changing.) This has the side effect of synchronizing your program to the display, since the driver doesn't return control until the VBL interval occurs. Either of these synchronization methods (1 or 2) may fail, depending on which video card you have, what you've set the pixel size to (1 to 32 bits), and whether you've raised the processor priority. The demo program TimeVideo tests both methods of synchronization on all your video cards at all pixel sizes and saves the results in a text file.
  3. I think that all video cards provide a read-only vertical-blanking bit, but unfortunately few manufacturers will tell you its address, so you have to find it yourself (typically by disassembling the video driver), which is tedious.
  4. Or use an analog or digital input to sample the video signal in a tight loop that watches for the leading edge of the vertical retrace pulse. Exit when you see the edge. [Suggested by Dave Post.]

Here's a fuller description of the first three methods:

1. VBL Interrupts. Most video cards emit one VBL interrupt during each video frame. However, during 1990-1 Apple generated some poor video drivers for their cards ("Macintosh Display Card": 8*24) and the built-in video in the Quadra 700 and 950. These drivers generate several interrupts per frame. (Kyle Cave discovered that there are no extra interrupts if the cache is disabled on the Quadra 700.) This behavior is contrary to Apple's documentation, but VBLInstall.c works around the bug, using a timer to discard the excess interrupts (as suggested by Raynald Comtois). Some video drivers take multiple frames to load the clut, and block interrupts while doing so, wreaking havoc with any attempt to count frames. Apple's video drivers produced before 1990 and since 1992 seem to be ok. (This may be in response to my many bug reports.) Try the demos TimeVideo and NoiseVBL.

The best current theory (due to Raynald Comtois) on the source of the extra interrupts is that the card is asserting the interrupt line for a fixed duration, perhaps 1 ms. As long as you are in the interrupt-handling routine (or one of higher priority), other interrupts of the same level are disabled. If you stay in the interrupt routine for long enough, the interrupt line has time to be released and you don't get a second interrupt, otherwise you do.

2. LOADING THE CLUT. It seems that all video drivers automatically synchronize clut-loading to the video frame. Apple's guidelines for video drivers (in the book Designing Cards and Drivers) state that the video driver may save the clut-load (i.e. cscSetEntries) request and defer the actual loading until the next VBL interrupt. Such video drivers return almost immediately after a cscSetEntries request. Thus, although the actual clut load will be synchronized to the display, your program will be asynchronous because the GDSetEntries call will return immediately. However, Apple's guidelines state that if the processor's interrupt priority has been raised, suspending the video card's VBL interrupts, then the video driver should always load the clut before returning, which would synchronize your program to the display. You can raise and lower the processor priority by calling the VideoToolbox routine SetPriority.c. The priority is normally zero. TimeVideo measures timing at both normal and high priority.

Be aware that a cscSetEntries request, i.e. calling GDSetEntries(), does not necessarily wait for the beginning of the next vertical blanking interval. It might merely wait until blanking is true. As a result, two successive GDSetEntries calls might occur during the same blanking interval. To get exactly one call per frame you may need to delay for a suitable interval (perhaps 1 ms) before calling it again.

Most video drivers that I've tested seem to be synchronous and reliably take exactly one frame to load the clut. However, some video drivers take longer, e.g. any loading of the clut on Apple's new video cards ("Macintosh Display Card": 8*24) takes 30 ms--two frames--which is unacceptably slow for lookup table animation. The TrueVision NuVista seems to be asynchronous. Presumably the on-board processor accepts the clut information at any time and actually updates the clut during the next vertical blanking interval. However, this means that asking the video driver to load the clut doesn't have the useful side effect of synchronizing the Mac program to the display. The NuVista takes about 0.3 frames (i.e. a few ms) to reload the whole clut when in 8, 16, or 32-bit mode, but takes several frames (i.e. tens of ms) when in 1, 2, or 4-bit mode (presumably because the fractional byte addressing is slow). I haven't checked, but presumably the NuVista driver would become synchronous, as specified by Apple, if the processor priority were raised.

SetEntriesQuickly.c--written primarily by Raynald Comtois, Peter Lennie, and Bill Haake--provides fast clut loading for several popular video devices. Try TimeVideo.

If 8-bit pixels are enough, and you have a NuBus, consider buying Apple's old "Toby" or "TFB" video cards, since they work fine, and cost only $90 each from Shreve Systems (800)-227-3971.

3. BLANKING BIT. Apparently all video cards have a blanking bit (telling whether the video signal is in the blank period between frames), but, alas, the manufacturers never tell you where it is. You could figure out which bit by disassembling the driver, as I did for the Apple Toby and TFB video cards (no longer sold by Apple; call Shreve at phone number given above). Perhaps one could write a program that would find the VBL bit automatically, by looking for any bit that changes at the right frequency.

WaitForBlanking() in SetEntriesQuickly.c tests the blanking bit, but presently supports only the (obsolete) Toby and TFB video cards. Hopefully other people will enhance this routine to support more devices.

CONCLUSION. Don't take synchronization or lookup table animation for granted. Run TimeVideo to check out your video cards.

B. SYNCHING MULTIPLE VIDEO CARDS TO EACH OTHER

SOFTWARE
: Short of butchering the hardware, synching two video cards is hard to do. It needn't be so, if the manufacturers were more forthcoming about how to program their cards. By disassembling the video driver for Apple's original "Toby" video cards I worked out that there are halt and restart commands that can be issued to the card. Several video cards can be synched by restarting them all at once (actually one after the other, in quick succession). Their quartz crystals run at slightly different frequencies so the cards slowly drift out of phase with each other, but that's still good enough for a relatively brief visual stimulus, resynching before each stimulus. Software to do this for the Toby video cards (which are still available from Shreve Systems (800)-227-3971, $90 each) is in the VideoTFB.c file in the VideoToolbox. It seems very likely that this approach is applicable to most video cards, but you would need to discover what the appropriate commands are to restart your cards. (Normally, video cards are restarted only at system restart.) You might be able to do this by disassembling the video drivers, but perhaps the manufacturer would tell you if you asked nicely. (Incidentally, the "Toby" video cards also have an undocumented ribbon cable connector that an Apple engineer explained to me could be used to achieve hardware-level synchronization. He said it might not work. I tried, but never got it to work.) I hope you'll share any useful results with me. I'd love to learn the restart commands for other video cards, especially Apple's, and would add support for them to the VideoToolbox software.

David Brainard adds (6/1/00), "One other way to sync two cards, which I have successfully used on a pair of RasterOps cards, is the following. Suppose you can detect in software the vertical sync pulse and suppose you can alter the frame rate of the display. Then you can run the two displays at different frame rates until they come into sync, then pop them both into the same frame rate. On the RasterOps card, I managed to get some low level code out of an engineer to do allow both operations (detection of sync, change of frame rate) by reading/writing the card directly. By making the frame rates close to each other, the two sync pulse drift slowly enough that you can lock them right up very easily. In principle this method will work with any cards, but you have to know the magic card-specific commands."

HARDWARE: David Brainard writes, "We have been working on the problem of synchronizing two video cards. For the Apple 8*24 card (rev B), we have a simple hardward solution. It turns out you can cut the clock trace and push the clock signal through a fast OR gate. Somewhat to my surprise, you can hold the clock for as long as you like without changing the state of the board. When you release the clock, the sync is shifted by the amount of time you held the clock. The 8*24 cards are OK. They will drive a 16" monitor and SetEntriesQuickly works fast. They cost $239 used. There may be a software solution like the one you developed for the Toby cards, but my guy struggled with it for a while and gave up. (He is better with hardware than software, which is why we went the way we did.)"

Karsten S. Weber adds, "I am working as a programmer for Professor Martin Banks at the University of California at Berkeley. We have recently done some stereo motion experiments that required synchronizing two video cards. I read in the 'Video Tool Box documentation' about how Dr. Brainard had developed a hardware solution for synchronizing two 8*24 cards. I have since used Brainard's work (and corresponded with him frequently) to do the same for our lab, but we did have some troubles with his approach primarily because we are using larger monitors. These problems have been solved in a nice way, as described below.

First I tried the approach that Brainard had successfully implemented earlier, i.e. a transistor to stop the clock of the video board. After soldering the transistor on the board, I tested it, and it worked fine. There is, however, a problem with this approach. It only works for 13" and 16" monitors. When I started using our 21" monitors, stopping the clock had no effect on the video output whatsoever! There is more than one clock on the video board, and it turns out that 21" monitors can be synchronized by stopping the fastest of the clocks. Using the 21" monitor and the 8*24 video board gives a maximum of 256 colors.

Secondly I implemented a nice software approach to synchronize the monitors. By looking at the VBLs for both boards I saw that they only stay in sync for a few seconds. This means that it is necessary to synchronize the video boards before every trial, of which there can be hundreds. It is therefore desirable to have a fast and easy way to synchronize the boards. I came up with a way for doing the synchronization that does not require photometers and a scope (as is required in Dr. Brainard's approach). The idea is the following: The hardware modification is installed on both video boards (rather than just one). A VBL interrupt routine is written for each board. When a VBL occurs on the left video board, the left interrupt routine is activated, and this routine stops the clock for the left video board (it does this by controlling the hardware that was added on the board). This means that the video board is stopped exactly at VBL time. The same procedure is done with the right video board: The interrupt from the right video board activated the right interrupt routine that stops the right video board. In this way both video boards get stopped at the time as their respective VBLs. The main program is still running and when it detects that both video cards have stopped, it activates them simultaneously, and the two video boards are now in synch. This means that synchronization can be done by calling one function, and the time it takes to synchronize the video boards is less than the time between the two VBLs. I'm using DTR of the modem and printer port to control the hardware."

BB. MORE ON INTERRUPTS

Michael Bach writes, "We are trying to do simultaneous visual stimulation and analog measurement of brain potentials on the same Macintosh. One of our ideas was to use the Time Manager to trigger analog measurement every 2 ms in its interrupt service routine. This works fine unless we use animate palette (or GDSetEntries or GDSetGamma): No timer tasks are serviced until vbl. Apparently the video driver goes into a tight loop, polling a vbl flag, with interrupts switched off! Can this be true? This would be a strong setback for using the Mac for this sort of work." Yes, alas, the normal behavior for interrupt service routines and the driver Control calls on the Mac is to suspend all interrupts until returning. Most video card drivers wait for vbl, as Michael says. However, TrueVision's NuVista returns immediately, letting the video card processor do the work later, at vbl time. And SetEntriesQuickly.c, for the few devices that it supports, allows you to achieve whatever behavior you want. Those solutions will make your code highly dependent on the particular video card. One solution that might work on all video cards would be to only call the video driver (e.g. GDSetEnries) during vertical blanking, i.e. immediately after the vbl interrupt occurs (use VBLInstall.c).

Michael Bach adds, "We have since done more experiments. We have an A/D card from National Instruments (NB-MIO-16), which we use with LabView. National Instruments also provide a library of lower-level routines ("NI-DAQ"), namely one "SCAN" that regularly scans analog input and writes into a buffer in memory. As the card lacks DMA, this is -- reading between the lines of their documentation -- implemented by an interrupt service routine called at the end of conversion. For this, the "NB-Handler Init" must be installed when the system is started up. While interrupts are blocked, measurements are kept in a FIFO on the card. If we use their SCAN routine, sampling is performed smoothly and not blocked by AnimatePalette et al. But care has to be taken that the FIFO is not overrun." This confirms that the video driver blocks all interrupts. Any interrupt that's still asserted will occur when the video driver exits. The timer interrupt is asserted only briefly and is lost if not serviced promptly; apparently the A/D card's slot interrupt request remains asserted until serviced.

C. CONTROLLING THE COLOR LOOKUP TABLE (CLUT)

QuickDraw is one of the great virtues of the Macintosh. However, several of its assumptions about what you want are inappropriate for vision experiments. In particular, it assumes that you want all your monitors to act as one consistent desktop (with consistent color tables). This is a problem if you want to load completely independent lookup tables and images onto two monitors that, for example, you may want to superimpose optically. QuickDraw enforces the consistency throught the Palette Manager, but calls that are nominally to the Color Manager (e.g. Apple's SetEntries) may be intercepted by the Palette Manager, resulting in undesired effects on other screens. My solution is to bypass QuickDraw and to load the lookup tables more or less directly, without telling QuickDraw.

GDSetEntries() and SetEntriesQuickly() work outside of QuickDraw. GDSetEntries makes a cscSetEntries control call to the video driver; SetEntriesQuickly directly addresses the hardware. They both load the clut of the video card without changing the color spec table of the graphics device; QuickDraw will continue to assume that the graphics device's color spec table is a true copy of the clut. This is the behavior that I usually want. However, it may cause problems if you use CopyBits since CopyBits will translate the color of each pixel it copies, using the inverse color table of the current device, which is based on the color spec table, NOT the clut. If you want to use CopyBits or SetCPixel, you should copy your color spec table into the graphics device's color spec table, and set ctSeed to alert QuickDraw that it's been changed. Or, instead of using QuickDraw's CopyBits and SetCPixel, you could use the VideoToolbox's CopyBitsQuickly and SetPixelsQuickly(), which copy pixel walues directly, ignoring all color tables and inverse color tables.

D. HIGH FRAME RATES

On March 17, 1995, fifty of us sent a letter to Apple requesting a new feature for video drivers to support arbitrary frame rates and resolutions. High frame rates are particularly relevant to stereo (using LCD glasses to alternate eyes) and retinal physiology (because retinal ganglion cells respond up to 100 Hz).

For some vision experiments it is desirable to run at very high frame rates, e.g. 100 or even 200 Hz, for retinal physiology experiments. Most multisynch monitors can go past 100 Hz, and there exist special monitors, e.g. the Joyce DM-4 Display, that can run at 200 Hz. Furthermore, all Mac video cards that I know of are programmable to a wide range of line and frame rates. Thus the Macintosh hardware is fully capable of running at high frame rates. However, very few video card manufacturers provide information on how to do this programming. Instead they supply a video driver (i.e. software) that only allows you to select a video timing from a list of timings that they built into the driver. The video driver that is read from your video card's ROM (or the Extensions folder) into memory when you boot the computer. Usually you make your selection by using the Monitors or Sound and Displays control panel, but you can also do it in software by calling the Display Manager. In either case, you can only select from the list offered by the video driver. I don't know of any standard video drivers for the Mac that offer a frame rate over 100 Hz. Truevision does supply information on how to program the NuVista to arbitrary line and frame rates. (I believe the TrueVision's max frame rate is over 100 Hz, but I don't recall what the limit is.)

Apple's response has two parts. Firstly, the VideoToolbox now includes a custom version of the video driver for the PowerMac 7300/7500/7600/8500/8600 (sorry it's only for those 5 models) supporting a 120 Hz frame rate at 640x480 pixels, in addition to the usual modes. (I repeat, 120 Hz x 640x480. You can have more pixels, but not at that frame rate: That's as fast as the video dot clock will go.) It works well on the Apple 17" and 20" multiscan, and the 1705 monitors, and probably on others too. (It doesn't work on the 1710, 1710AV, or multiscan 15, unless you use a multisynch adapter to make these monitors appear to the computer to be, e.g. a 17" multiscan.) You can select this mode from the standard Monitors or Sound & Displays control panel. This custom driver was created for us by Nano Urbina, the Apple engineer who wrote the original 7500/8500 built-in-video driver. Secondly, Nano Urbina is drafting a spec for a general-purpose video driver call that would allow us to specify any achievable configuration of pixels and frame rates. Once published by Apple, this will provide all video card manufacturers a standard way of allowing programs to achieve unforseen video modes, fully exploiting the capabilities of their hardware.

For now, if you need a frame rate over 100 Hz on a Mac, I suggest buying a 7500, 7600, or 8500 and using the custom driver that Nano Urbina wrote for us.

See 7300/7500/7600/8500/8600 Driver.

DD. FRAME RATES

According to Apple's Tech Information Library article number 18780 (October, 1995) "Apple uses a refresh rate of 62 Hz on all (color and grayscale) active matrix displays. The passive matrix screens use a refresh rate of 73 Hz for grayscale passive matrix (MFSTN) displays and 79 Hz for color passive matrix (CFSTN) displays."

"Active matrix displays, also called Thin-Film Transistor (TFT), have transistors that are individually addressed and charged. The amount of time that it takes for the charge to diminish is around 20 milliseconds (ms). Passive matrix displays, also called Film SuperTwisted Nematic (FSTN), have a faster refresh rate. Once their pixels receive a charge, the time it takes for the pixel to lose its charge can be measured in seconds. In fact, the fastest time that the computer can turn a pixel off is over 60 ms."

DDD. CONNECTING TO A NON-STANDARD VIDEO DISPLAY

Apple's Display Software 2.0 Read Me (1/96) says, "To set the screen resolution and configure your video card, you click the Options button in the Monitors control panel. To see more choices, hold down the Option key on your keyboard as you click the Options button. ... Note: Some of the items in this list will not work properly with your monitor. If you choose a resolution that doesn't work with your monitor, you may see a message, or your monitor may go blank or show static. After approximately 15 seconds, your monitor should revert to a usable resolution. If it does not, restart your computer." If, after attaching a new monitor to your computer, "the new monitor's screen is blank or shows "garbage" or "snow," the computer may not have recognized the monitor. Try the following: Turn off the computer and disconnect the new monitor. Start the computer with no monitor attached. Wait a minute or so for the computer to finish turning itself on. Turn off the computer again and reattach the new monitor."

Apple's InfoAlley (volume 2, issue 18, 1/15/96) describes a more elaborate way to restore normal resolution on a Power Macintosh 8500:

  1. Shut down the computer. (If you cannot see the menu bar, press the Power key on the keyboard. A dialog box will appear with the default option of Shut Down. To respond to it, press the Return key.)
  2. Restart the computer, and reset the parameter RAM (PRAM). To restart PRAM, hold down the Command-Option-P-R keys simultaneously.
  3. Disable extensions by holding down the Shift key until you see the message, "Welcome to Macintosh. Extensions off."
  4. Delete the Display Preferences file, which is located in the Preferences folder inside the System Folder. Deleting this file will set the resolution to its default setting of 512x384.
  5. Restart the computer
  6. You should now be able to access the menu bar and control strip to change the computer display's resolution.


Video compatibility between your video port and your video monitor has two parts: electrical and timing. The electrical part has to do with kinds of connector, and kinds of synching signals, and use of other pins to allow the computer to identify the kind of monitor ("auto sensing"). Electrical compatibility is usually easy to achieve.

Timing compatibility is harder because Apple's current conventions for video drivers assume that they will only support a fixed set of timings, and a new timing can be added to the list only by replacing the video driver with a new one that has the new timing added to its list.

Mac video hardware and drivers generally support half a dozen or so video timings. The available list of timings is set by the driver, and may be documented by the manufacturer. This list of timings comes up when you hit Options in the Monitors or Sound & Displays control panel. Usually the video card auto-detects the kind of monitor (by a digital pin code), but some can be forced into particular video timings, e.g. by selecting that timing from the list in the Monitors or Sound and Displays control panel.

I am trying to convince apple to adopt a more flexible scheme that would allow us to specify an arbitrary timing at run time, but this is still off in the future.

E. HOW TO LOAD THE CLUT ON A VIDEO CARD WITH MORE-THAN-8-BIT DACS

F. SHIELDCURSOR

In the summer of '93 Steve Lemke at Radius wrote, "Apple has stated several times (though I wouldn't necessarily expect you to have run across any of them) that if you write directly to the screen, you must use the "ShieldCursor" and "ShowCursor" traps to prevent the cursor from being overwritten. To do so, you pass the rectangle in which you are drawing to "ShieldCursor". It's nice that all QuickDraw routines use this trap, as it makes for a simple way to identify what areas of the screen are changing. It also makes for a simple way for people who draw directly to the screen to notify the Radius PowerView software that they are doing so. Everything in that rectangle gets updated on the Radius PowerView screen. Too bad more programs don't use it, though..."

Taking his advice, CopyWindows calls ShieldCursor before calling CopyBitsQuickly.

G. DISASSEMBLING A VIDEO DRIVER

Assuming you can read 680x0 assembly code, use the VideoToolbox utility GrabVideoDrivers to put the driver into a file, then use ResEdit with the ResEdit CODE editor to examine it, comparing it with the example in the appendix of Apple's Designing Cards and Drivers book. The ResEdit CODE editor is free. It was written by Ira L. Ruben of Apple Computer.

H. FIXING THE MAC IIci BUILT-IN VIDEO DRIVER

(The following remedies worked for the Mac IIci video driver, patching or replacing the buggy version 0 .Display_Video_Apple_RBV1 driver by copying the bug-free version 1 of the same driver from the Mac IIsi. It is very likely that an analogous approach could be used to patch or replace the buggy version 0, 1, and 2 .Display_Video_Apple_DAFB drivers in the Quadra 700, 750, and 900, by the bug-free version 3 or 5 of that driver in the Centris 650 or LC 475.)

The Mac IIci built-in video driver (.Display_Video_Apple_RBV1 driver, version 0) has a bug that causes it to crash if you try to do a cscGetEntries Status request. Here are two ways to fix the bug:

1. AUTOMATIC TEMPORARY PATCH. (This happens automatically if you use GDVideo. This note is an explanation, in case you're curious.) The bug only affects GDGetEntries, so the first time GDGetEntries is invoked it automatically calls PatchMacIIciVideoDriver() in GDVideo.c to find and patch the copy of the buggy driver residing in memory, preventing any trouble. (If the driver is in ROM, then the driver is copied to RAM, and patched there.) Only two instructions are modified, to save & restore more registers. (I figured out what needed patching by comparing this driver's disassembly with the bug-free version in the Mac IIsi.) And the driver's version number is changed from 0 to 100, so that programs can distinguish it from the buggy version 0. This fix persists only until the next reboot.

2. PERMANENT UPGRADE. The Mac IIsi has version 1 of the same driver, without the bug. In principle all you have to do is copy the new driver from the IIsi to your IIci, but this is nontrivial because these drivers are in ROM. It is fairly simple, as described below, to place a copy of the version 1 (i.e. fixed) driver into the System file of the Mac IIci, but, as explained in Inside Mac V-424, this will only displace the older version 0 (buggy) driver if it's not driving the boot monitor (i.e. if the "Welcome to Macintosh" message appears on some other monitor), because the boot monitor's driver is loaded at boot time before the System file is available. If you have multiple monitors, you can use the Monitors Control Panel to change the boot monitor: hold the option key down and drag the smiling Mac to any monitor except the one driven by the built-in video. So, in case you do have multiple monitors, here's how to copy the driver. First put the VideoToolbox utility "GetVideoDrivers" on a floppy and run it on a Mac IIsi. That will copy the all the video drivers onto your floppy as ResEdit files. Then put the floppy in your Mac IIci and copy "-Display_Video_Apple_RBV1" onto your hard disk. Make a copy of your System file. Open the "-Display_Video_Apple_RBV1" file in ResEdit. Hit Command-I to edit the Resource Info. Set the "System Heap" and "Purgeable" flags, change the ID from 1 to 122, and close the Resource Info window. Now copy the resource and paste it into the copy of your System file. Quit, saving changes. Now rename the active System file to something else, like "old System", and rename the edited System file to "System". Reboot. You can now throw the old System into the trash. The new driver will automatically be favored over the one in ROM because it has a higher version number (1 instead of 0). All my test programs indicate that the new driver works fine in the Mac IIci with System 7, and I would expect it to work fine with System 6 as well. (Thanks to Mike Alexander for figuring out why it didn't work for the boot monitor.)

I. VIDEO BANDWIDTH
Paul Sowden asks, "We have built a video attenuator for use with a PC based system and are now at the stage of calibrating our attenuator. Prior to this we need to check the input impedance of our monitor at various frequencies in the manner you describe in your paper (Vis. Res. 31, 1337-1350). In your paper you state that Z (the monitor's input impedance) should be independent of the oscillator frequency, from d.c. to 20 MHz. Our query is where does the upper limit of 20 MHz come from?" Sorry, the paper should have spelled it out. Your monitor draws pixels one after another along each scan line as it paints your image on the screen. The clock rate of the pixels depends on your video card. 20 MHz was common at the time the paper was written (e.g. a 640x480x67 Hz display) but higher speeds, e.g. 100 MHz, are common now. If you think about the spatial frequency spectrum of a scan line, it corresponds to the temporal frequency spectrum of the video signal for that line, where the width of the screen (e.g. in degrees of arc at the viewer's eye) corresponds to the time for the line to sweep across the screen. The time for a line is approximately the reciprocal of the line rate (except for a small blanking interval), which is typically around 34 kHz. (Alternatively, and equivalently, you can establish the correspondence based on a pixel's width and its duration, which is the reciprocal of the pixel clock rate.) If the pixel clock rate is f, then a scan line can represent image frequencies up to f/2 (by the Nyquist sampling theorem), and you would want the monitor's input impedance to be constant up to at least that frequency. In practice the only way of achieving this is to design a high-input-impedance amplifier with a 75 ohm resistor at its input. That gives the desired fixed impedance over a very wide bandwidth. So, in practice you'll probably find that your monitor's input impedance is either terribly frequency dependent (and unfit for serious psychophysical work) or fine over a very wide bandwidth. A separate issue is that it is desirable for the video bandwidth of the monitor to be as high as possible, to follow the frequencies in the incoming video signal, to avoiding nonlinear distortions from slew rate limitations, as discussed in the paper.

Please send any corrections or additions to denis@psych.nyu.edu