This Week With My Coleco ADAM 9612.01

by Richard F. Drushel (drushel@apk.net)

I. More on RGB Values of the TMS9xx8 VDP Palette.

Two weeks ago (TWWMCA 9611.18) I presented an extensive derivation of the RGB triplet values corresponding to the color palette of the TMS9118 VDP (which is closely related to the TMS9928 VDP in the ColecoVision and ADAM). I've had some interesting responses from Marcel de Kogel (author of the ColEm and ADAMEm emulators under MS-DOS) and Marat Fayzullin (author of the original MSX emulator, upon which the ColEm and ADAMEm emulators were originally based). Marcel was happy with my RGB palette; but Marat claims that his palette (which I felt was not a good match to what I saw on my monitor screen with a real ADAM) was derived directly from the default RGB palette loaded into the TMS9938 VDP when starting in backward- compatible 9918/28 mode. I asked Marat if his palette came directly from a Texas Instruments Data Manual or from some other source; I haven't heard a reply yet.

In the meantime, I decided that I would follow up on one of my own suggestions about how to determine the RGB palette: create a color test pattern, use a video frame grabber to create an RGB TIFF image of the display, and then analyze the RGB triplets. I used a RasterOps 24STV 24-bit frame grabber on a PowerMac 7100 host computer, with an R80 ADAM's NTSC composite video output plugged into it. I wrote a simple SmartBASIC 1.x program to draw 15 256 x 12 horizontal bars in HGR2 mode, after setting the border color to white. (You can use regular SmartBASIC 1.0, but you have to use POKEs to set the colors; the COLOR(x)=y syntax of SB1.x is much cleaner, so I used the latter.) Here's the program (indenting used to promote clarity; it will disappear if you load this into SB1.x):

 1 REM colorbar / Created Saturday 30 November 1996 by Richard F. Drushel
 2 REM makes a test pattern of horizontal color bars
 3 REM Note:  SmartBASIC 1.x only!
 9 IF VER(0)<20 THEN TEXT: BEEP: PRINT "Requires SmartBASIC 1.x!": NEW
10 COLOR(2)=15:                   REM set border to WHITE
20 HGR2:                          REM 256 x 192 graphics mode
30 FOR n=0 to 15:                 REM step through each color
40     COLOR(1)=n:                REM set HCOLOR color
50     FOR j=0 to 11              REM each bar is 12 lines high
60          y=(n*12)+j:           REM find our current scan line
70          HPLOT 0,y TO 255,y:   REM draw the colored line
80     NEXT j
90 NEXT n

The software which comes with the RasterOps board (MediaGrabber 3.0) allows the current video to be grabbed and saved in a variety of image formats, including 24-bit color (RGB) TIFF. I grabbed the colorbar screen, moved the image to an MS-DOS machine, looked at it with a hex editor (Norton Utilities), and wrote a QuickBASIC 4.5 program to create an RGB frequency distribution of the pixels in each color bar. (There is always some noise in a video signal, meaning that each "color" would have some slight variations pixel-to- pixel.) Fortunately, for most of the colors, there was a vastly-predominating RGB triplet combination, so I could just select the triplets of greatest frequency as representative of each "color". The file ADAM.TIF is available for download.

[GIF of framegrab of R80 ADAM (TMS9928A VDP) color bars
adam.tif, framegrab of R80 ADAM (TMS9928A VDP) color bars

The following 2 tables give the RGB triplets from the colorbar framegrab, both as 8-bit values and percentages. For comparison, the values I calculated previously for the TMS9918 VDP are also presented. The file TMS9928A.TIF is a representation of the framegrab-derived palette.

[GIF of TMS9118 palette, calculated from Data Manual parameters
tms9118.tif, TMS9118 palette, calculated from Data Manual parameters
GIF of framegrab palette using only most frequent RGB triplets (as calculated above)]
tms9928a.tif, framegrab palette using only most-frequent RGB triplets (as tabulated above)
     ================================================
     |   |              |        8-bit value        |
     |   |              =============================
     |   |              |   TMS9928A  |   TMS9118   |
     |   |              | (frame grab)| (calculated)|
     |   |              =============================
     |hex|    color     |  R   G   B  |  R   G   B  |
     ================================================
     | 1 | Black        |   0  16   0 |   0   0   0 |
     | 2 | Medium Green |  16 191   0 |  71 183  59 |
     | 3 | Light Green  |  64 192  32 | 124 207 111 |
     | 4 | Dark Blue    |  64  63 255 |  93  78 255 |
     | 5 | Light Blue   |  96  95 255 | 128 114 255 |
     | 6 | Dark Red     | 160  80  16 | 182  98  71 |
     | 7 | Cyan         |  47 192 208 |  93 200 237 |
     | 8 | Medium Red   | 207  79  15 | 215 107  72 |
     | 9 | Light Red    | 224 111  32 | 251 143 108 |
     | A | Dark Yellow  | 160 175   0 | 195 205  65 |
     | B | Light Yellow | 175 175  31 | 211 218 118 |
     | C | Dark Green   |  16 144   0 |  62 159  47 |
     | D | Magenta      | 159  79 160 | 182 100 199 |
     | E | Grey         | 159 160 143 | 204 204 204 |
     | F | White        | 191 207 175 | 255 255 255 |
     ================================================


     ==================================================================
     |   |              |            percent maximum value            |
     |   |              ===============================================
     |   |              |        TMS9928A      |        TMS9118       |
     |   |              |      (frame grab)    |      (calculated)    |
     |   |              ===============================================
     |hex|    color     |    R      G      B   |    R      G      B   |
     ==================================================================
     | 1 | Black        |   0.00   6.27   0.00 |   0.00   0.00   0.00 |
     | 2 | Medium Green |   6.27  74.90   0.00 |  27.56  71.65  22.86 |
     | 3 | Light Green  |  25.10  75.29  12.55 |  48.39  80.97  43.24 |
     | 4 | Dark Blue    |  25.10  24.71 100.00 |  36.52  30.37 100.00 |
     | 5 | Light Blue   |  37.65  37.25 100.00 |  49.90  44.42 100.00 |
     | 6 | Dark Red     |  62.75  31.37   6.27 |  71.12  38.22  27.76 |
     | 7 | Cyan         |  18.43  75.29  81.57 |  36.19  77.99  92.75 |
     | 8 | Medium Red   |  81.18  30.98   5.88 |  84.06  41.70  28.23 |
     | 9 | Light Red    |  87.84  43.53  12.55 |  98.06  55.70  42.23 |
     | A | Dark Yellow  |  62.75  68.63   0.00 |  76.16  80.23  25.50 |
     | B | Light Yellow |  68.63  68.63  12.16 |  82.27  85.18  45.95 |
     | C | Dark Green   |   6.27  56.47   0.00 |  24.31  62.27  18.31 |
     | D | Magenta      |  62.35  30.98  62.75 |  71.15  39.06  77.92 |
     | E | Grey         |  62.35  62.75  56.08 |  80.00  80.00  80.00 |
     | F | White        |  74.90  81.18  68.63 | 100.00 100.00 100.00 |
     ==================================================================

There are clearly differences between the RGB values from the framegrab and the calculated values for the TMS9118 VDP; but what these mean isn't clear just from the numbers. Comparison of the framegrab image ADAM.TIF with the image of the calculated palette (TMS9118.TIF, also available for download) shows that the framegrab is "warmer": the colors are more saturated. Also, the "white" of the framegrab isn't really very white, but is instead rather grey. The framegrab "black" also has a distinct greenish cast to it.

To determine the exact nature of the color differences between the framegrab palette and the calculated TMS9118 palette, the RGB triplets were converted into luminance (Y), I, and Q signals. The I and Q signals were then used to calculate the magnitude of the chrominance vector (C) and the phase angle relative to the B-Y axis (P). The reader is referred to TWWMCA 9611.18 for discussion of color television signals and the necessary mathematics. The results are presented in the following table:

          ========================================================
          |   |              |       TMS9928A (frame grab)       |
          |   |              =====================================
          |hex|    color     |   Y  |    I  |    Q  |   C  |  P  |
          ========================================================
          | 1 | Black        | 0.04 | -0.02 | -0.03 | 0.04 | 241 |
          | 2 | Medium Green | 0.46 | -0.17 | -0.38 | 0.41 | 238 |
          | 3 | Light Green  | 0.53 | -0.10 | -0.30 | 0.32 | 232 |
          | 4 | Dark Blue    | 0.33 | -0.24 |  0.23 | 0.33 | 347 |
          | 5 | Light Blue   | 0.44 | -0.20 |  0.20 | 0.28 | 348 |
          | 6 | Dark Red     | 0.38 |  0.27 | -0.01 | 0.27 | 126 |
          | 7 | Cyan         | 0.59 | -0.36 | -0.10 | 0.37 | 288 |
          | 8 | Medium Red   | 0.43 |  0.38 |  0.03 | 0.38 | 119 |
          | 9 | Light Red    | 0.53 |  0.37 | -0.00 | 0.37 | 123 |
          | A | Dark Yellow  | 0.59 |  0.18 | -0.23 | 0.29 | 174 |
          | B | Light Yellow | 0.62 |  0.18 | -0.18 | 0.25 | 167 |
          | C | Dark Green   | 0.35 | -0.12 | -0.28 | 0.31 | 236 |
          | D | Magenta      | 0.44 |  0.09 |  0.16 | 0.19 |  61 |
          | E | Grey         | 0.62 |  0.02 | -0.02 | 0.03 | 172 |
          | F | White        | 0.78 |  0.00 | -0.05 | 0.05 | 210 |
          ========================================================

For comparison, here is the equivalent data for the TMS9118 VDP, derived from values tabluated in the Data Manual:

          ========================================================
          |   |              |     TMS9118 (from Data Manual)    |
          |   |              =====================================
          |hex|    color     |   Y  |    I  |    Q  |   C  |  P  |
          ========================================================
          | 1 | Black        | 0.00 |  0.00 |  0.00 | 0.00 | --- |
          | 2 | Medium Green | 0.53 | -0.11 | -0.24 | 0.27 | 237 |
          | 3 | Light Green  | 0.67 | -0.08 | -0.19 | 0.20 | 235 |
          | 4 | Dark Blue    | 0.40 | -0.19 |  0.23 | 0.30 | 354 |
          | 5 | Light Blue   | 0.53 | -0.17 |  0.21 | 0.27 | 354 |
          | 6 | Dark Red     | 0.47 |  0.23 |  0.04 | 0.23 | 114 |
          | 7 | Cyan         | 0.67 | -0.30 | -0.04 | 0.30 | 295 |
          | 8 | Medium Red   | 0.53 |  0.30 |  0.05 | 0.30 | 114 |
          | 9 | Light Red    | 0.67 |  0.30 |  0.05 | 0.30 | 114 |
          | A | Dark Yellow  | 0.73 |  0.15 | -0.18 | 0.23 | 173 |
          | B | Light Yellow | 0.80 |  0.11 | -0.13 | 0.17 | 173 |
          | C | Dark Green   | 0.46 | -0.09 | -0.22 | 0.23 | 235 |
          | D | Magenta      | 0.53 |  0.07 |  0.19 | 0.20 |  53 |
          | E | Grey         | 0.80 |  0.00 |  0.00 | 0.00 | --- |
          | F | White        | 1.00 |  0.00 |  0.00 | 0.00 | --- |
          ========================================================

The remarkable result of this comparison is that the phase angles of all the colors are virtually the same between the framegrab and the calculated 9118 values. The main differences are in

  1. the luminance values, which are low in the framegrab, and

  2. the chrominance values, which are greater in the framegrab.

The low luminance is the cause of the greyed-out "white" color in the framegrab, while the larger chrominances are responsible for the framegrab colors looking "warmer" and less pastel.

For fun, I rescaled the RGB values (by dividing by 0.78) so that the maximum luminance was 1.00 volts. Here's the result:

          ========================================================
          |   |              |        TMS9928A (frame grab)      |
          |   |              =====================================
          |hex|    color     |Y/0.78|   I'  |   Q'  |  C'  |  P' |
          ========================================================
          | 1 | Black        | 0.05 | -0.02 | -0.04 | 0.05 | 241 |
          | 2 | Medium Green | 0.59 | -0.22 | -0.48 | 0.53 | 238 |
          | 3 | Light Green  | 0.68 | -0.13 | -0.38 | 0.41 | 232 |
          | 4 | Dark Blue    | 0.42 | -0.31 |  0.30 | 0.43 | 347 |
          | 5 | Light Blue   | 0.57 | -0.25 |  0.25 | 0.36 | 348 |
          | 6 | Dark Red     | 0.49 |  0.34 | -0.02 | 0.34 | 126 |
          | 7 | Cyan         | 0.76 | -0.46 | -0.13 | 0.48 | 288 |
          | 8 | Medium Red   | 0.55 |  0.49 |  0.04 | 0.49 | 119 |
          | 9 | Light Red    | 0.68 |  0.47 | -0.00 | 0.47 | 123 |
          | A | Dark Yellow  | 0.76 |  0.24 | -0.29 | 0.37 | 174 |
          | B | Light Yellow | 0.80 |  0.23 | -0.22 | 0.32 | 167 |
          | C | Dark Green   | 0.45 | -0.15 | -0.36 | 0.39 | 236 |
          | D | Magenta      | 0.56 |  0.11 |  0.21 | 0.24 |  61 |
          | E | Grey         | 0.79 |  0.02 | -0.03 | 0.04 | 172 |
          | F | White        | 1.00 |  0.00 | -0.07 | 0.07 | 210 |
          ========================================================

Two more remarkable results to note:

  1. the luminances for all colors now matches that given in the Data Manual; and

  2. the phase angles are unchanged.

If I understood this topic better, maybe I wouldn't be (or shouldn't be) surprised by this; but I find it quite unexpected nonetheless.

One possible explanation for the Y and C differences is that the brightness and hue controls for the RasterOps framegrabber board were not set at the correct defaults, and that the brightness was too low and/or the hue was too high. The tint setting, however, must be okay, because all the phase angles are correct. (Remember, "brightness" knob changes luminance, "hue" knob changes magnitude of chrominance vector, and "tint" knob changes phase angle of chrominance vector.) Another possibility is that the video circuitry of the ADAM I used is out of adjustment.

Speaking of settings, one setting I did play with in the MediaGrabber 3.0 software was the "gamma" setting. Gamma is a non-linear parameter introduced into the transmitted R,G,B color signals to compensate for non-linear behavior of the receiver. The transmitted signal is raised to the gamma power; the receiver takes the gammath root of the signal to restore the original. A gamma of 1.0 is for a perfectly linear response. A typical gamma for a television set is 2.2. When I changed the gamma of the RasterOps framegrabber board to 2.2, and looked at the live ADAM colorbar video display, I saw a color palette which looked (IMHO) very similar to Marat Fayzullin's palette for the TMS9938. Hmm...is it possible that the RGB values Marat used were gamma-corrected, and needed to be uncorrected? See the similarity yourself in the two files GAMMA22.TIF (the gamma-corrected view of my ADAM colorbar display) and MARAT.TIF (which is Marat's palette as extracted from COLEMDOS screen shots in Windows BMP format).

[ADAM.TIF gamma-corrected (gamma=2.2)]
gamma22.tif, same screen as ADAM.TIF but gamma-corrected (gamma=2.2)
[Marat Fayzullin's TMS9938 palette]
marat.tif, Marat Fayzullin's TMS9938 palette, used by Marcel de Kogel in the COLEMDOS ColecoVision emulator

Note that the order of color bars in the two TIFs is not the same; you should be able to figure out the colors, though. In principle, I should be able to gamma-uncorrect MARAT.TIF and get back something which looks like my TMS9118 palette. Something to try this week...

II. Exploring ADAMnet: How the Z80 CPU Shares RAM With ADAMnet.

Chris Braymen recently cleared up a long-standing mystery (to me, anyhow) about why the EOS _READ_BLOCK function needed to make 2 ADAMnet read requests to read from a block device, while _WRITE_BLOCK needs only 1 ADAMnet write request. While checking out his answer by looking over the source code for the ADAMnet master 6801 microcontroller, I ended up lingering over the routines which actually read and write to the Z80 address space. (The ADAMnet Device Control Blocks, or DCBs, are memory-mapped I/O areas for communicating with each ADAMnet device.) I've spent a few hours with my ADAM schematics, my 6801 Reference Manual from Motorola, and the master 6801 source, to try to understand this part of the ADAM hardware. It's complicated by the fact that there's a large logic gate array chip, the Memory I/O Controller (MIOC), sitting between the Z80 CPU and the master 6801, and made worse by the fact that the MIOC is a totally-undocumented black box.

I think I can make some headway, for my own amusement, but I don't have a "final" story worked out yet; so I'll be satisfied with just letting everybody know that I'm poking around with it. If I get it worked out (and if Chris Braymen doesn't have it worked out already), I'll write it up. Who knows, maybe enough can be gleaned to replace the MIOC with discrete logic chips someday; right now, the MIOC is the only non-replaceable chip on the ADAM motherboard.

III. A Holiday Wish.

I hope all the Americans got lots of turkey this Thanksgiving weekend. To you Canadians, visit your closest ADAMite across the border and get some leftovers :-)

See you next week!

*Rich*


Next Article
Previous Article
TWWMCA Archive Main Page