V9938 Video Data Processor

From Ninerpedia
Revision as of 18:18, 11 June 2019 by Mizapf (talk | contribs) (Benchmarks)
Jump to navigation Jump to search

Officially called the MSX-Video Data Processor V9938, this video chip is one of the main advantages of the Geneve 9640. The name already suggests that this VDP is typically used in MSX computer systems.

Video modes

Mouse and Lightpen support



I wrote a couple of benchmark programs that run in native mode and use the clock chip for measuring the command execution times. The commands are repeated many thousand times so that in the end, an execution time in the range of several seconds up to minutes is measured; dividing by the iteration count and considering setup times, we get a good estimation of the single execution time.

This information is particularly important when using the VDP commands in time-critical situations, for instance, in games.

The times for the line operation vary, depending on the angle. Horizontal and vertical lines are fastest, while 45° diagonal lines are slowest. (This is a bit surprising, since on a raster screen, a line always consists of max(dx,dy) pixels.)

Graphics 7 mode

Command Description Specifics Setup [µs] µs per pixel Pixels per sec
HMMC Write bytes into rectangle Fast 133 39 25640
LMMC Write bytes into rectangle Logical 133 39 25640
HMMV Fill rectangle with one color Fast 37 2.9 344828
LMMV Fill rectangle with one color Logical 37 6.1 163934
HMMM Copy rectangle content Fast 100 5.875 170213
YMMM Copy rectangle content, Y only Very fast 100 5.125 195122
LMMM Copy rectangle content Logical 100 8.375 119403
LINE Draw line Logical 56 6.2..8.2 121951..161290

The setup time is a fixed time, independent of the amount of modified pixels on the screen. Maybe it is caused by internal calculations of the VDP, or by some trailing delay. You have to add some more time for your program to set the video registers; this is typically 100 µs.


The following calculations all refer to graphics 7 mode, and we leave away all setup times. Thus, the required times are lower bounds; it will take longer to perform the action.

  • We'd like to paint the whole screen: There are 192 rows and 256 columns, which means 49152 pixels. Using the HMMV command, we see that this takes t = 2.9 µs * 49152 = 142541 µs = 0.14 secs. Doing that repeatedly, we will achieve less than 8 frames per second.
  • Instead of filling a rectangle, we can draw lines in subsequent rows. If we want to fill the screen, we have 192 lines with a length of 256 pixels. Each line takes about 1587 µs, hence, it takes 0.3 secs to fill the screen. (Exactly 0.343 secs, as a sample program proved.)
  • Suppose we want to shift the upper half of the screen down by one row. The upper half takes up 24576 pixels; moving the contents with the fastest YMMM command takes 125952 µs = 0.126 secs, again, just 8 frames per second.
  • We'd like to print a text on the graphics screen. Each character consists of 8x8 = 64 pixels. Using the HMMC command, printing a single character takes about 2500 µs, so we get 400 characters/second. Since 768 characters fit on the screen, it takes almost 2 seconds to fill the screen with characters.
  • Alternatively, we could store the glyphs of the characters in a non-visible screen area, again, as 8x8 pixels rectangles and then just copy the glyph to the desired screen position. This can be done with the HMMM command. One character takes 376 µs, this means 2660 characters per second.

If we think about serious game programming, 8 frames per second is pretty disappointing. The line command is certainly useful, and also painting into the rectangles, but mass transfer should be avoided.