N64® Functions Menu

al - Audio Library Functions
gDP - DP GBI Macros
gdSP - General GBI Macros
gSP - SP GBI Macros
gt - Turbo Microcode RDP
gu - Graphics Utilities
Math - Math Functions
nuSys - NuSystem
os - N64 Operating System
sp - Sprite Library Functions
uh - Host to Target IO
64DD - N64 Disk Drive

Nintendo® Confidential

## Video Interface (VI) Management

VI Management Functions
There are 16 management functions for the video interface (VI):

- osViGetStatus
- osViGetCurrentMode
- osViGetCurrentLine
- osViGetCurrentField
- osViGetCurrentFramebuffer
- osViGetNextFramebuffer
- osViSetMode
- osViSetEvent
- osViSetSpecialFeatures
- osViSetXScale
- osViSetYScale
- osViSwapBuffer
- osViBlack
- osViFade
- osViRepeatLine
- osCreateViManager

Links to each of these VI management functions are listed in the "See Also" section at the foot of this article.
42 Video Display Modes
The VI is responsible for displaying the RDP-rendered images in different video modes. Currently, VI supports 42 video display modes -- 14 for NTSC, 14 for PAL, and 14 for MPAL. Each mode contains different settings to handle attributes such as interlaced and non- interlaced, 16-bit and 32-bit color pixel, and low and high resolution. Furthermore, a mode can be configured to rescale the image to sacrifice resolution for rendering speed.
These supported modes can be represented by 5 switches:

- high/low resolution
- 16-/32-bit color pixel
- anti-aliased/point-sampled
- filtered/not filtered
- NTSC/PAL/MPAL format

There are symbolic names defined for these modes in <os.h>. For example, uhOpenGame represents an NTSC mode that supports low resolution, point sampled, non- interlaced, and 16-bit color pixel. Similarly, OS_VI_PAL_LPN1 refers to the same mode but in PAL format. The last four-character block (LPN1) in the symbol name is constructed by using the following codes for each character position:

- 1st position is H for high resolution or L for low resolution
- 2nd position is A for anti-aliasing or P for point-sampled
- 3rd position for:
  - Low resolution is N for non-interlace or F for interlace
  - High resolution is N for normal-interlace F deflickered interlace
- 4th position is 1 for 16-bit pixel size or 2 for 32-bit pixel size

When you apply these codes, the following 14 modes are supported for NTSC as well as for PAL and MPAL for a total of 42 modes:

    LPN1   HPN1
    LPF1   HPF1
    LAN1   HAN1
    LAF1   HAF1
    LPN2   HPN2
    LPF2   HPF2
    LAN2   LAF2

In low resolution (320 pixels by 240 lines), you have a choice between non-interlaced and interlaced mode. Non-interlaced mode repeats the same frame each field. Interlaced mode interpolates between adjacent lines, weighting 75% of the line above plus 25% of the line below in the first field, and then weighting 25% of the line above plus 75% of the line below in the second field. Note that there is no flicker because there are no high spatial frequencies.
In high resolution (640 pixels by 480 lines), you have a choice between normal interlace and deflickered interlace. Normal interlace uses just the data rendered in one field to display that field. This mode can use one high resolution frame buffer without additional double buffering because one field can be displayed while the next is being rendered without stepping on each other. However, any single pixel with high detail will flicker because it is only displayed in one field. Deflickered interlace averages adjacent lines to filter out the high frequency vertical detail, but at the cost of requiring double buffering of the entire high resolution frame because both rendered fields are used to display each field.
VI Management Functions
You can use the 16 functions described in this section to manage the VI.
Currently, there is a global VI mode table (osViModeTable) that contains register settings for these 42 modes. You can use the osViSetMode function to register one of these modes with the VI to be used at the next vertical retrace. This function simply overwrites all the VI registers with data from the location pointed to by the mode argument, which is a pointer into osViModeTable. All previous settings (such as XY scaling and gamma correction) are reset. For example, to register the NTSC, low resolution, anti-aliased, non-interlaced, 16-bit mode with the VI, use this code:
osViSetMode(osViModeTable[OS_VI_NTSC_LAN1]);
For storage efficiency, the global VI mode table is divided into 42 separate mode structures with each structure globally defined in a separate source file. These structures are externally declared in <os.h>. To gain access to the equivalent mode mentioned above, use this code:
osViSetMode(osViModeNtscLan1);
You can call osViGetCurrentMode to return the VI mode currently being used.
After setting the display mode, the application should call osViSetEvent to register a message queue (mq) and a message (m) with the VI manager. This allows the program to receive the notification message (m) at the message queue (mq) from the VI manager when a vertical retrace occurs. Setting retraceCount to a value higher than 1 (such as 2) decreases the frequency with which the application receives the vertical retrace notification. This allows it to run at a slower speed such as 30 Hz instead of 60 Hz.
The VI manager is a system thread that must be invoked at the beginning of the application. To do this, call osCreateViManager with the priority (pri) at which it is to run. Usually, this priority should be set to OS_PRIORITY_VIMGR, which is defined in <os.h>. The VI manager is designed to service both the VI interrupt (OS_EVENT_VI) and CPU counter interrupt (OS_EVENT_COUNTER) in the most efficient manner. The counter interrupt is used by the timer manager.
Once the display mode and message queue have been registered with the VI manager, the application needs to call osViSwapBuffer to register the frame buffer (frameBufPtr) to be displayed at the next vertical retrace interrupt.
When Nintendo 64 powers on, the boot code sets the timing to NTSC, PAL, or MPAL and blanks out the video. The call to osCreateViManager initializes the video to LAN1 (in either NTSC, PAL, or MPAL mode) and also blanks out the video. The first time video is enabled is when osViSetMode is called. To keep the screen blank until after the first use of osViSwapBuffer, call osViBlack(TRUE) immediately after the osViSetMode call. Then call osViBlack(FALSE) right before the first call to osViSwapBuffer.
Call osViSetXScale to scale the image up horizontally (in the X direction) to the required display format from a reduced number of rendered pixels per line. The value argument specifies the scaling factor and can range from 0.25 to 1.0.
Call osViSetYScale to scale the image up vertically (in the Y direction) to the required display format from a reduced number of rendered lines per frame. Use Y-scaling only in low resolution and non-interlaced modes such as LAN1, LAN2, LPN1, and LPN2. The value argument specifies the scaling factor and can range from 0.05 to 1.0.
Call osViSetSpecialFeatures to enable or disable various VI special features such as GAMMA, GAMMA_DITHER, DIVOT, and DITHER_FILTER. There are symbolic names defined in <os.h> including:

- OS_VI_GAMMA_ON and OS_VI_GAMMA_OFF
- OS_VI_GAMMA_DITHER_ON and OS_VI_GAMMA_DITHER_OFF
- OS_VI_DIVOT_ON and OS_VI_DIVOT_OFF
- OS_VI_DITHER_FILTER_ON and OS_VI_DITHER_FILTER_OFF

You can OR these names together to enable or disable specific features. Note that some of these settings only make sense in certain video modes. For example Gamma Dithering only happens if Gamma Correction is enabled, and Divot Removal only occurs in an anti-aliased video mode. Divot is a special operation that can be (optionally) performed on the anti-aliased pixels to filter out the "divot" (one pixel notch) artifacts when multiple silhouettes overlap on a pixel. Note that this filter is not used in regions of full coverage, so high spatial frequency textures within a surface will not be disturbed.
Call osViGetStatus to get the value of the video interface status/control register. The unsigned 32-bit returned value contains various bit patterns that are defined in <rcp.h>. Some of these patterns include:

- VI_CTRL_TYPE_16 - 16-bit pixel size
- VI_CTRL_TYPE_32 - 32-bit pixel size
- VI_CTRL_GAMMA_DITHER_ON - gamma_dither mode is enabled
- VI_CTRL_GAMMA_ON - gamma correction is enabled
- VI_CTRL_DIVOT_ON - divot mode is enabled
- VI_CTRL_SERRATE_ON - serrate mode is enabled
- VI_CTRL_DITHER_FILTER_ON - dither filter mode is enabled

You can mask (AND) these bit patterns against the returned value to interpret the video interface status. Serrate mode mentioned above is a special feature of true NTSC that provides a twice line frequency narrow sync pulse during vertical sync. This feature helps ancient analog amplifiers to stabilize vertical retrace phase lock loop. Apparently, there are some very high-end TVs that can differentiate between true interlaced and low resolution non-interlaced mode by the presence or absence of these serration pulses. The global VI mode table is initialized to have serrate mode enabled in all interlaced modes and disabled in all low resolution non-interlaced modes.
The osViGetCurrentLine function returns the current half line, sampled once per line. The least significant bit (lsb) of this value is constant within a field in non-interlaced modes but toggles to give the field number (0 or 1) in interlaced modes.
The osViGetCurrentField function returns the field number (either 0 or 1) currently being accessed by the VI.
The osViGetCurrentFramebuffer function returns an opaque pointer to the currently displayed frame buffer.
The osViGetNextFramebuffer function returns an opaque pointer to the next frame buffer to be displayed.
Based on the active flag setting, which can be TRUE (enabled, screen black) or FALSE (disabled), the osViBlack function can black out the screen and still generate vertical retrace signals. You can only use osViBlack when the YScale factor for the video mode is 1.0. Using it for YScale factors that are not 1.0 creates the potential for the video interface to malfunction and enter a state that cannot be exited without resetting the system.
In low-resolution, point-sampled, and non-interlaced modes (such as LPN1 and LPN2), you can use the 10-bit fractional interpolation factor in the osViFade function to fade between the first two scan lines of the frame buffer.
You can call the osViRepeatLine function to repeat the first scan line of the frame buffer for the entire frame.
Notes
The VI manager must be started at the beginning of the program so that vertical retrace interrupts can be serviced as quickly as possible. Note that osViSetMode resets all current settings such as X-Y scaling and special features such as gamma to the default values defined in the global mode table.
The video back-end filter can only execute an anti-aliasing filter or a dither filter, but not both simultaneously. This is especially visible on "billboard" cutouts in texture edge mode during magnification in the region of the cutout where alpha goes from 1 to 0. In this region, the dither pattern is visible because the back-end filter executes an anti-alias filter (due to partial coverage) and turns off the dither filter.
This problem also occurs on anti-aliased silhouette edges of polygons, but it is not obvious due to the small width of the partially covered region.
See Also
osViGetStatus
osViGetCurrentMode
osViGetCurrentLine
osViGetCurrentField
osViGetCurrentFramebuffer
osViGetNextFramebuffer
osViSetMode
osViSetEvent
osViSetSpecialFeatures
osViSetXScale
osViSetYScale
osViSwapBuffer
osViBlack
osViFade
osViRepeatLine
osCreateViManager
osSetEventMesg
osGetTime

Nintendo® Confidential Warning: all information in this document is confidential and covered by a non-disclosure agreement. You are responsible for keeping this information confidential and protected. Nintendo will vigorously enforce this responsibility.
Copyright © 1998
Nintendo of America Inc. All rights reserved
Nintendo and N64 are registered trademarks of Nintendo
Last updated March 1998