bobp@amiga.UUCP (Robert S. Pariseau) (11/09/85)
TITLE: Fun With 6 Bit Planes (SOURCE) There are lots of fun things you can do in 6 bit planes on the Amiga, including Hold and Modify color displays and dual-playfield mode with two separately scroll-able, completely independent, 8 color playfields with overlay and transparency. But tonight I'm going to discuss something you don't already know about your Amiga -- even if you've read all the tech manuals cover to cover. The specs for the Amiga say that in a completely static, low-resolution display, with nothing fancy going on (like Hold and Modify), you can display up to 32 colors simultaneously out of a pallette of 4096. Well not quite. You can actually display up to 64 distinct colors out of that pallette of 4096! Yes, an unlimited choice of any of 64 colors at each pixel in the screen! Have I got your attention? Welcome to Extra-Half-Brite mode. The Amiga display hardware automatically enters Extra-Half-Brite mode whenever you select a 6 plane display (which must be low res due to the hardware) and have NOT selected either Hold and Modify or Dual Playfield mode. The graphics kernel software further enforces the rule that you must set the EXTRA_HALFBRITE flag in the ViewModes for the ViewPort (Screen in Intution lingo) or it will automatically trim your screen down to 5 planes. This is done both for backward compatability and to insure support in future Amiga architectures. Consider the playfield data bits for a given pixel. The bits from the first five planes form a color register selector for that pixel, allowing you to choose among the 32 color registers in the Amiga. The bit from the sixth plane is interpreted as follows: 0 -- Use the color in the selected color register just as specified. 1 -- Take the color in the selected color register, shift each of its R, G, and B components right one bit, and use the new color value thus formed. The net result is as if you had 64 color registers where the colors in the top 32 were "half-intensity" counterparts of the colors in the bottom 32! Of course, that means there is a dependency between the choice of colors in the 32 real registers and the resulting colors in the 32 psuedo-registers. Nevertheless, I assert we have as much right to claim 64 colors on screen as IBM has to claim 16 colors from a monitor that is physically capable of producing only 8 colors at 2 intensities! At least we can select our 32 colors out of a pallatte of 4096! Note also that, since fractional color components have no meaning in the hardware, there are several distinct real colors that produce the same extra color. For instance (in hex): 888 --> 444, 988 --> 444, 898 --> 444, 999 --> 444, etc. Despite all this quibbling, with a little thought it's easy to see how you can choose a set of 32 real colors to make sure all 64 real plus extra colors are distinct. And they are every-pixel-addressable! Why have we kept this little jewel a secret? No, it's not that we were planning to lull the competition into complacency and then spring an instant double of the Amiga's color capacity on them. Actually, the rev of the custom chips in which this worked was the last rev before we went into production. Thus the info was too late to make it into the current version of the Amiga Hardware Manual. Some caveats. Although ALL the consumer machines have the necessary chip rev, there are some older developer's machines out there which can't do this trick. BEWARE! Some of the store demo units come out of that older developer's stock and won't contain the Extra-Half-Brite hardware. Note that you can't hurt anything by running such a program on an older machine -- the values in the 6th bit plane will simply be ignored. Also the V1.0 printer device will not correctly handle this trick for color printing -- it works fine in V1.1. The sample program below shows Extra-Half-Brite mode in operation. -------------------------Program Notes The Extra program will compile and link cleanly using the native Amiga Lattice C tools on the standard V1.0 C disk. The Make script in the examples directory will do all the work for you. I suggest you copy your source file into ram disk, cd over to your C development disk, and type 1> execute Make ram:Extra [assumes you are where Make is] Afterwards, copy the resulting Extra program back out of ram: to someplace safe from power failures. The program itself is pretty straightforward. It opens a 6 plane low res custom screen and then opens a window in that screen. 64 color patches are then drawn into that window with color register usage increasing left to right then top to bottom from 0 to 63. For simplicity, this program uses the default color pallette supplied with the new screen. Due to the EXTRA_HALFBRITE special ViewMode in the screen definition, the bottom 4 rows of color should be the half intensity counterparts of the corresponding patches in the top 4 rows. The program waits for a CLOSEWINDOW message from Intution, then cleans up and goes away. -------------------------Program Source Follows: /*********************************************************************** * Extra -- Program to demonstrate Extra-Half-Brite graphics display * mode on the Amiga. * * Dale Luck -- October, 1985 * Bob Pariseau -- November 8, 1985 (Editorial changes) * **********************************************************************/ #include <exec/types.h> #include <exec/tasks.h> #include <exec/libraries.h> #include <exec/devices.h> #include <devices/keymap.h> #include <graphics/copper.h> #include <graphics/display.h> #include <graphics/gfxbase.h> #include <graphics/text.h> #include <graphics/view.h> #include <graphics/gels.h> #include <graphics/regions.h> #include <hardware/blit.h> #include <intuition/intuition.h> #include <intuition/intuitionbase.h> struct GfxBase *GfxBase; /* Export library base pointers */ struct IntuitionBase *IntuitionBase; struct Screen *colscreen; /* Pointers to new screen and */ struct Window *wndo; /* window. */ struct NewScreen newscreen; /* OpenX() arguments for new */ struct NewWindow newwindow; /* screen and window. */ struct TextAttr Font = { "topaz.font", /* Use standard system font */ 8, FS_NORMAL, FPF_ROMFONT, }; struct IntuiMessage *message; main() { if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0)) == 0) { printf("WOT ! No Intuition ???\n"); exit(); } if ((GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0)) == 0) { printf("Oh ! No Graphics??\n"); CloseLibrary(IntuitionBase); exit(); } /* values for new screen */ newscreen.LeftEdge = 0; newscreen.TopEdge = 0; newscreen.Width = 320; newscreen.Height = 200; newscreen.Depth = 6; newscreen.DetailPen = 0; newscreen.BlockPen = 1; newscreen.ViewModes = EXTRA_HALFBRITE; newscreen.Type = CUSTOMSCREEN; newscreen.Font = &Font; newscreen.DefaultTitle = "Six Planes Low Res"; newscreen.Gadgets = NULL; colscreen = (struct Screen *)OpenScreen(&newscreen); if (colscreen == 0) { printf("Screen Failed !!!!!\n"); CloseLibrary(GfxBase); CloseLibrary(IntuitionBase); exit(); } /* values for new window */ newwindow.LeftEdge = 0; newwindow.TopEdge = 15; newwindow.Width = 320; newwindow.Height = 185; newwindow.DetailPen = 0; newwindow.BlockPen = 1; newwindow.Flags = ACTIVATE | SIMPLE_REFRESH | WINDOWCLOSE; newwindow.IDCMPFlags = CLOSEWINDOW; newwindow.FirstGadget = NULL; newwindow.CheckMark = NULL; newwindow.Title = "Extra-Half-Brite Colors!"; newwindow.Screen = colscreen; newwindow.BitMap = NULL; newwindow.MinWidth = 20; newwindow.MinHeight = 20; newwindow.MaxWidth = 320; newwindow.MaxHeight = 200; newwindow.Type = CUSTOMSCREEN; wndo = (struct Window *)OpenWindow(&newwindow); if (wndo == 0) { printf("Window failed!!!\n"); CloseScreen(colscreen); CloseLibrary(GfxBase); CloseLibrary(IntuitionBase); exit(); } setup(wndo->RPort); FOREVER { WaitPort(wndo->UserPort); message = (struct IntuiMessage *)GetMsg(wndo->UserPort); if(message->Class == CLOSEWINDOW) { ReplyMsg(message); /* Can't reply till done using */ CloseWindow(wndo); CloseScreen(colscreen); CloseLibrary(GfxBase); CloseLibrary(IntuitionBase); exit(); } ReplyMsg(message); } } setup(rastp) struct RastPort *rastp; { USHORT countx; USHORT county; USHORT color; for (countx = 0; countx < 8; countx++) for (county = 0; county < 8; county++) { color = (county<<3) + countx; SetAPen(rastp,color); RectFill(rastp,countx*35+10,county*20+15,countx*35+45,county*20+35); } } ------------------------That's all for now!