This document applies to version 1.0 of the driver.
TestMemory();Description
This function tests the video memory. I use 256Kb steps because I think less than it is impossible. In fact I think all the 9440 boards have 1Mb or 2Mb of memory. Some time ago I tried to install 1.5Mb in one board and the BIOS reported just 1Mb. I also tried removing 0.5Mb and the BIOS detected it OK. I think Trident's BIOS detects 256, 512, 1024 and 2048. The first time I tested this function writing outside the memory didn't write, but when I tested it in my machine it made a write at the 0 position. The stranger thing is that it doesn't happend with unoptimized code. Oh! if you wander about why such a complex test, beleive me if you don't check all you could detect any crazy value.
Set8x8MonoPattern(AF_DRIVER *af, unsigned char *pattern);Description
Downloads a monochrome (packed bit) pattern, for use by the DrawPattScan() and DrawPattRect() functions. This is always sized 8x8, and aligned with the top left corner of video memory: if other alignments are desired, the pattern will be prerotated before it is passed to this routine. DrawPattScan. DrawPattRect.
Set8x8ColorPattern(AF_DRIVER *af, int index, unsigned long *pattern);Description
Downloads a color pattern, for use by the DrawColorPattScan() and DrawColorPattRect() functions. This is always sized 8x8, and aligned with the top left corner of video memory: if other alignments are desired, the pattern will be prerotated before it is passed to this routine. The color values are presented in the native format for the current video mode, but padded to 32 bits (so the pattern is always an 8x8 array of longs). DrawColorPattScan. DrawColorPattRect. // ToDo: Make 2 versions
Use8x8ColorPattern(AF_DRIVER *af, int index);Description
Selects one of the patterns previously downloaded by Set8x8ColorPattern(). Set8x8ColorPattern.
SetLineStipple(AF_DRIVER *af, unsigned short stipple);Description
Sets the mask used for stipple lines. DrawStippleLine.
I'm not sure about it so here is my guess: TGUI9440 have a 16 bits register (GER44,GER45) to set the mask used for patterned lines so I guess that's this function is to setup this value.
SetLineStippleCount(AF_DRIVER *af, unsigned long count);Description
Sets the repeat counter for the mask used in stipple lines. DrawStippleLine.
I'm not sure about it so here is my guess: TGUI9440 have an 8 bits register (GER47) to set the scale of the pattern for patterned lines. A value of 0 means that each bit in the pattern is 1 dot, a value of 1 expands each pixel to 2 dots and so on.
DrawStippleLine(AF_DRIVER *af, unsigned long foreColor, unsigned long backColor, fixed x1, fixed y1, fixed x2, fixed y2);Description
Draws a stipple line (patterned, dotted). SetLineStipple sets the pattern used and SetLineStippleCount the scale. SetLineStipple. SetLineStippleCount.
Note: This function doesn't call drawline, it is almost the same code repeated. That's to increase speed because in this way I can make the Bresenham parameters calculation in parallel with the GE.
DrawRect(AF_DRIVER *af, unsigned long color, long left, long top, long width, long height);Description
Fills a rectangle in the current foreground mix mode.
DrawScan(AF_DRIVER *af, long color, long y, long x1, long x2);Description
Fills a scanline in the current foreground mix mode. Draws up to but not including the second x coordinate. If the second coord is less than the first, they are swapped. If they are equal, nothing is drawn.
DrawPattRect(AF_DRIVER *af, unsigned long foreColor, unsigned long backColor, long left, long top, long width, long height);Description
Fills a rectangle using the current mono pattern. Set pattern bits are drawn using the specified foreground color and the foreground mix mode, and clear bits use the background color and background mix mode.
DrawPattScan(AF_DRIVER *af, long foreColor, long backColor, long y, long x1, long x2);Description
Fills a scanline using the current mono pattern. Set pattern bits are drawn using the specified foreground color and the foreground mix mode, and clear bits use the background color and background mix mode.
DrawColorPattRect(AF_DRIVER *af, long left, long top, long width, long height);Description
Fills a rectangle using the current color pattern and mix mode.
DrawColorPattScan(AF_DRIVER *af, long y, long x1, long x2);Description
Fills a scanline using the current mono pattern. Set pattern bits are drawn using the specified foreground color and the foreground mix mode, and clear bits use the background color and background mix mode.
BitBlt(AF_DRIVER *af, long left, long top, long width, long height, long dstLeft, long dstTop, long op);Description
Blits from one part of video memory to another, using the specified mix operation. This must correctly handle the case where the two regions overlap.
SrcTransBlt(AF_DRIVER *af, long left, long top, long width, long height, long dstLeft, long dstTop, long op, unsigned long transparent);Description
Blits from one part of video memory to another, using the specified mix operation and skipping any source pixels which match the specified transparent color. Results are undefined if the two regions overlap.
BitBltSys(AF_DRIVER *af, void *srcAddr, long srcPitch, long srcLeft, long srcTop, long width, long height, long dstLeft, long dstTop, long op);Description
Copies from system memory to the screen.
SrcTransBltSys(AF_DRIVER *af, void *srcAddr, long srcPitch, long srcLeft, long srcTop, long width, long height, long dstLeft, long dstTop, long op, unsigned long transparent);Description
Copies from system memory to the screen, skipping any source pixels that match the specified transparent color.
PutMonoImage(AF_DRIVER *af, long foreColor, long backColor, long dstX, long dstY, long byteWidth, long srcX, long srcY, long width, long height, unsigned char *image);Description
Expands a monochrome bitmap from system memory onto the screen.
DrawTrap(AF_DRIVER *af, unsigned long color, AF_TRAP *trap);Description
Draws a filled trapezoid, using the current foreground mix mode.
TGUI9440 doesn't have trapezoids, I think it was introduced in 96xx chips. I implemented it using scan lines, I think that's faster than a software trapezoid.
SetCursor(AF_DRIVER *af, AF_CURSOR *cursor);Description
Sets the hardware cursor shape. // ToDo split it in various
SetCursorPos(AF_DRIVER *af, long x, long y);Description
Sets the hardware cursor position.
SetCursorColor(AF_DRIVER *af, unsigned char red, unsigned char green, unsigned char blue);Description
Sets the hardware cursor color.
Not supported by TGUI9440, I think 968x adds some registers for it.
ShowCursor(AF_DRIVER *af, long visible);Description
Turns the hardware cursor on or off.
SetBank(AF_DRIVER *af, long bank);Description
C-callable bank switch function.
SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT);Description
Palette setting routine. Palette values are in 8 bits format because some boards support 8 bits DAC and not only 6 bits.
GetDisplayStartStatus(AF_DRIVER *af);Description
Status poll for triple buffering. Not possible on the majority of present cards: this function is just a placeholder.
This must report if the Vertical Retrace Interval taked effect and the Display Start were transfered.
Lamentably TGUI9440 doesn't set 3C2.b7, that's a clear violation to the VGA standard, Trident people must do it, like CHIPS does.
SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT);Description
Hardware scrolling function. The waitVRT value may be one of:
-1 = don't set hardware, just store values for next page flip to use
0 = set values and return immediately
1 = set values and wait for retrace
SetActiveBuffer(AF_DRIVER *af, long index);Description
Sets which buffer is being drawn onto, for use in multi buffering systems (not used by Allegro).
I took it from the prototype driver and seems to be totally independent of the board.
SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT);Description
Sets which buffer is displayed on the screen, for use in multi buffering systems (not used by Allegro).
Copied from the prototype driver.
GetVideoModeInfo(AF_DRIVER *af, unsigned Mode, AF_MODE_INFO *modeInfo);Description
Retrieves information about this video mode, returning zero on success or -1 if the mode is invalid.
FindClosestVClk(unsigned fx, unsigned *VClkReg, unsigned *Divider);Description
This routine calculates the closest frecuency to fx that we can achieve with the 9440 PLL. The values to program the chip are stored in VClkReg and Divider.
Return Value
The closest available frecuency or (unsigned)-1 if the value is outside the range.
GetClosestPixelClock(AF_DRIVER *af, unsigned mode, unsigned long pixelClock);Description
Return Value
: The closest value available for the board or (unsigned)-1 if the value is outside the range.
SetVideoMode(AF_DRIVER *af, unsigned mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc);Description
Sets the video mode. This function have various features, be careful.
Mode is a 32 bits value, and not 16 bits as the first drafts propposed. Because a some nasty reasons isn't just a mode number but some sort of flags plus mode number. The lower 10 bits are the video mode number the rest of the bits have the following meaning:
0x8000 = don't clear video memory.
0x4000 = enable linear framebuffer.
0x2000 = enable multi buffering.
0x1000 = enable virtual scrolling.
0x0800 = use refresh rate control.
0x0400 = use hardware stereo.
Most of them are self-explanatory, and others aren't very clear yet.
The virtual screen size is requested by the virtualX/Y pair the driver will set a screen of at least this size, if isn't posible will return error. Note that the actual size could be greater. For this reason bytesPerLine is filled with the actual X virtual size (stride?).
You can request more than one buffer indicating it in numBuffers, if the RAM isn't enough the driver will return error.
Perhaps the hardest parameter to understand is crtc. This parameter provides a mechanism to allow setting the refresh rate and centering the screen. The mechanism is incomplet and SciTech people complements it with OEM extentions, I asked to make these extentions official and Kendall said he will consider it for Nucleus. Anyways, this pointer will be used by the driver if you use the 0x0800 flag, the members of the structure are:
unsigned short HorizontalTotal: Total pixels, visible and not visible.
unsigned short HorizontalSyncStart: Pixel where the horizontal sync pulse
starts.
unsigned short HorizontalSyncEnd: End of the pulse.
unsigned short VerticalTotal: Total lines, visible and not.
unsigned short VerticalSyncStart: Vertical sync pulse start.
unsigned short VerticalSyncEnd: End of the pulse.
unsigned char Flags: Various flags see below.
unsigned int PixelClock: Desired pixel clock, the driver will use the
closest available so you must check it with GetClosestPixelClock.
GetClosestPixelClock.
unsigned short RefreshRate: Just ignore it is for very old controllers that
have some specific crtc register values for each mode.
unsigned short NumBuffers: That's here only for compatibility issues related
to VBE/AF 1.0.
The possible flags are:
afDoubleScan (0x0001) Enable double scanned mode.
afInterlaced (0x0002) Enable interlaced mode.
afHSyncNeg (0x0004) Horizontal sync is negative.
afVSyncNeg (0x0008) Vertical sync is negative.
As you can see only the X/Y resolution is set by the driver and you control all the rest.
To use it you must first find information about the monitor (asking the user or using DDC?), then calculate the total and sync positions with the VESA GTF formula and the aid of GetClosestPixelClock and finally pass these values to the driver.
Important:
1) I don't care about LFB that's on all the time.
2) I expanded the short mode to unsigned mode because MGL 4.05 does it.
3) I added a propietary flag: 0x80000000: Don't set the palette. I think it
will be replaced by some OEM extention, avoid using it.
RestoreTextMode(AF_DRIVER *af);Description
Return Value
to text mode, shutting down the accelerator hardware.
EnableDirectAccess(AF_DRIVER *af);Description
Provides direct access to the video RAM. That's needed for boards where the accelerator blocks the use of the video RAM.
TGUI9440 does it only during the Blit operations so in my case I simply do a wait until de Graphics Engine finished your job. Note that this routine is here just for testing because isn't needed and isn't reported.
Example
EnableDirectAccess(af); .... Draw to the screen .... DisableDirectAccess(af);
DisableDirectAccess(AF_DRIVER *af);Description
Disables the direct access to the video RAM. That's needed for boards where the accelerator blocks the use of the video RAM.
TGUI9440 does it only during the Blit operations so in my case this function does nothing. Note that this routine is here just for testing because isn't needed and isn't reported.
WaitTillIdle(AF_DRIVER *af);Description
Waits until the accelerator finished your job. That's a very important function. Suppose you want to draw over a rectangle made with DrawRect, how can you be sure you won't draw under it? Waiting until the accelerator finished your job.
What I don't fully understand is the need of both: Enable/DisableDirectAccess and WaitTillIdle. I saw an e-mail by Kendall tallking about it.
The TGUI9440 waits until the Graphic Engine finished all the jobs.
ExtStub();Description
Vendor-specific extension hook: we don't provide any.
SetupDriver(AF_DRIVER *af);Description
The first thing ever to be called after our code has been relocated. This is in charge of filling in the driver header with all the required information and function pointers. We do not yet have access to the video memory, so we can't talk directly to the card.
InitDriver(AF_DRIVER *af);Description
The second thing to be called during the init process, after the application has mapped all the memory and I/O resources we need. This is in charge of finding the card, returning 0 on success or -1 to abort.
InitDriver(AF_DRIVER *af);Description
Return Value
to text mode, shutting down the accelerator hardware.
InitDriver(AF_DRIVER *af);Description
Provides direct access to the video RAM. That's needed for boards where the accelerator blocks the use of the video RAM.
TGUI9440 does it only during the Blit operations so in my case I simply do a wait until de Graphics Engine finished your job. Note that this routine is here just for testing because isn't needed and isn't reported.
Example
EnableDirectAccess(af); .... Draw to the screen .... DisableDirectAccess(af);
InitDriver(AF_DRIVER *af);Description
Disables the direct access to the video RAM. That's needed for boards where the accelerator blocks the use of the video RAM.
TGUI9440 does it only during the Blit operations so in my case this function does nothing. Note that this routine is here just for testing because isn't needed and isn't reported.
DumpValues(uchar *regs, int base, int cant, int last);Description
Dumps the values from the arrays to the screen.
TGUI9440SaveRegs(uchar *regs);Description
This routines captures the TGUI registers in an array. Not all are stored because isn't needed by now. In fact I'm storing a lot of registers that are not needed to store.
VGASaveRegs(uchar *regs, uchar *Sregs);Description
This function stores ALL the VGA registers in an array. Additionally it calls to the routine that stores the TGUI registers around 120 registers are stored.
TGUI9440LoadRegs(const uchar *regs);Description
Restores the TGUI registers from an array.
VGALoadRegs(const uchar *regs, const uchar *Sregs);Description
Restores the VGA registers from an array.
ReadVSync(int *start, int *end);Description
Return Value
the vertical sync start and end values. Not optimized because I think that's a very strange stuff.
SetVSync(int start, int end);Description
Sets the vertical sync start and end values. Not optimized because I think that's a very strange stuff.