Writing a Picasso96 Hardware Driver

This is version 0.5 of this document. If you have any questions or additions, please mail them to me.


Contents

1. Introduction
2. Writing a new Driver
2.1 Overview
2.2 In Detail
3. Development Setup
3.1 Environment
3.2 Languages


Introduction

This document should help the programmer of card and chip drivers to get an idea of what is necessary to build them, what functionality is needed and in which context the card and chip functions are called.

Graphics boards for the Amiga usually consist of two major components, the Amiga expansion card with the glue logic and the optional video switch and a standard PC-VGA chip. Therefore Picasso96 hardware drivers are usually divided into two parts, a card driver that handles the board specific issues and a chip driver for the VGA display controller. The purpose is to have similar graphics boards like for example the PicassoII(+), the GVP Spectrum and the Piccolo share the same chip driver and only use different card drivers. This ensures that once the board specific drivers are written, the boards simultaneously get any extensions and improvements made on the chip side.

But this separation is not mandatory. If a driver needs to be monolithic or its code will not be used by other similar products, all functionality and code can be put into one single driver module.

Picasso96 board hardware drivers are libraries that currently have only two function calls in addition to the standard library calls:

FindCard is called in the first stage of the board initialisation and configuration and is used to look for a free and unconfigured board of the type the driver is capable of managing. If it finds one, it immediately reserves it for use by Picasso96, usually by clearing the CDB_CONFIGME bit in the flags field of the ConfigDev struct of this expansion card. But this is only a common example, a driver can do whatever it wants to mark this card as used by the driver. This mechanism is intended to ensure that a board is configured and used by one driver only. Usually FindBoard also fills some fields of the BoardInfo struct supplied by the caller, the rtg.library, for example the MemoryBase, MemorySize and RegisterBase fields.

InitCard is called in a second stage after the rtg.library allocated other system resources like memory. During this call, all fields of the BoardInfo structure that need to be filled must be initialized. A driver that consists of two separate parts like a card driver and a chip driver calls the init function of the chip driver at that time.

If the board has features that are not the same as the chip driver assumes, like for example, the board uses a different RAM layout than the chip expects or uses other tricks like the changed red and blue lines on the Piccolo, PiccoloSD64 and Spectrum cards, the right time to change the affected parts of the initialisation is after the chip initialisation is completed. Now you can change the RAM configuration or the available RGBFormats without any problems.

The graphics board data and functions are held in one control structure, the BoardInfo structure. It consists of all data that is important for the rtg.library. There is constant data like the memory base or library base pointers, function pointers that point to card or chip specific routines like video switch control or blitter access, and dynamic data used by the rtg.library, like e.g. the current video mode and the active viewport.


Writing a new Driver

If you start a new driver from scratch you should do it in a few steps:
  1. get the driver to work as a dumb frame buffer,
  2. get the optional hardware sprite working,
  3. get the blitter working,
  4. add special features like flicker fixer, video modules and stuff.

Overview

Basic Functionality
What is needed to get a card to work as a basic dumb frame buffer?

Constant data:

Functions:

Hardware Sprite Support
What is needed to get a card to work with hardware sprite?

Blitter Support
What is needed to get a card to work with blitter accelleration?

Basically you don't need to support all functions immediately as there are default CPU handling routines that can do all the stuff, but if the chip or card offer blitter or some special conversion hardware, there are function pointers that can be overwritten by your driver. Many of the functions also have a xyzDefault routine that points to the CPU function and which can be called if your driver decides not to handle a special case that is not implemented. This way you can focus on those functions that are more important first and implement the other ones as you find time for them.

Extra Stuff
Special Features
My board has unusual hardware options that need special support

I need to override some Picasso96 system functions

In Detail

Constant data:
RegisterBase:
This is not referenced from rtg.library, it is merely for you to look it up. Normally this is located at the base address of the PC I/O base so that e.g. the timing sequencer index register is located at $3C4 from it, but it can be at any offset you choose, maybe some other offset is more useful to you.
This is needed by the chip driver as well as by the card driver in most cases and is therefore placed in the global constant data.

MemoryBase:
This is the start address of the linear addressable memory of the graphics board. It is needed for direct accesses by the rtg.library.

MemoryIOBase:
This is the base address of the memory mapped IO area. It can be used by the chip driver but is usually initialised by the card driver. It is not referenced from rtg.library.

MemorySize:
This is the size in bytes of the memory on the board minus the size of reserved memory used e.g. for sprite data like with the Cirrus chips or a buffer for blitting (masks or temp buffers).

MemorySpaceBase:
This is the base of the address space occupied by the onboard memory. It is used to set the MMU of 040 or 060 processor boards to use non-serialised or imprecise caching mode respectively. Must be defined if boardinfo flag BIF_CACHEMODECHANGE is set.

MemorySpaceSize:
The size of the memory area. Must be defined if boardinfo flag BIF_CACHEMODECHANGE is set.

BoardName:
A pointer to the name of your board. You will have to supply this.

BoardType:
A constant value to identify your board by the rtg.library. You should get a constant assigned by the Picasso96 development team. In the mean time you can use an unused value.

BitsPerCannon:
The number of significant bits your RAMDAC uses in CLUT based modes. Usually either 6 (64 different shades) or 8 (256 shades) bits per gun.

Flags:
A field of bits that determine what features your board offers, first the hardware bits:
BIB_HARDWARESPRITE
If set, this type of board has support for a hardware sprite. You will have to supply the sprite functions, too.
BIB_NOMEMORYMODEMIX
If set, then this board cannot handle access to planar screens while displaying chunky ones and vice versa.
BIB_NEEDSALIGNMENT
This one is not yet implemented.
BIB_CACHEMODECHANGE
If set, the CPU caching mode of the board memory is set to non-serialised (040) or imprecise (060). You will have to fill the MemorySpaceBase and MemorySpaceSize fields.
BIB_DBLSCANDBLSPRITEY
If set, then the y-position of the hardware sprite must be doubled when a double scan screen is displayed. This is normally the case for hardware sprites that are not controlled by the VGA chip but rather by the RAMDAC like on the Merlin board.
BIB_ILACEHALFSPRITEY
If set, then the y-position of the hardware sprite must be the half of the actual y-position whenever a interlace screen is displayed. This is normally the case for hardware sprites that are not controlled by the VGA chip but rather by the RAMDAC like on the Merlin board.
BIB_ILACEDBLROWOFFSET
If set, in interlace modes, the VGA chip needs the offset to the first pixel in the next row of the current frame as row offset, i.e. during the even frame the odd lines between have to be skipped by adjusting in this value. This is so far only true for the Tseng ET4000 series.
BIB_FLICKERFIXER
This board is equipped with a flicker fixer device that is treated as a special feature.
BIB_VIDEOCAPTURE
This board is equipped with video capture capability which is also treated as a special feature.
BIB_VIDEOWINDOW
This board is equipped with video window capability which is also treated as a special feature.
BIB_BLITTER
If set, this board has a blitter. When available, the present hardware should at least support acceleration of basic operations. This bit determines if invisible bitmaps (e.g. cliprects) are stored on the board considering that blitter operations on the board are faster than CPU operations in system memory. You should be able to do memory transfers within the memory of the graphics card.

Now, the user and system modifyable bits.

BIB_HIRESSPRITE
If set, mouse has double horizontal resolution, 2*32 bits per line like AGA, otherwise 2*16 bits like ECS.
BIB_BIGSPRITE
User wants a big sprite image, double each pixel in x and y direction.
BIB_BORDEROVERRIDE
User wants to override system overscan border prefs.
BIB_BORDERBLANK
User wants border blanking, i. e. no overscan border.
BIB_INDISPLAYCHAIN
If set, this board switches the Amiga video signal.
BIB_QUIET
Not yet implemented, intended to disable startup screens or messages.
BIB_NOMASKBLITS
If set, the user wants blitting that does not use bit masks. This will speed things up with blitters that can not use masks like the Cirrus chip.
BIB_NOC2PBLITS
The user selected to use CPU for planar to chunky conversions. This might be faster on some high powered Amigas. You don't have to care about this.
BIB_NOBLITTER
The user selected to disable all blitter functions. You don't have to care about this, too.

SoftSpriteFlags:
If your board has a hardware sprite that can not be used in some modes, you can set the bit of the RGBFormat(s) of this mode. The rtg.library will the use a software sprite with this mode(s). For example, the CirrusGD542X can not use the hardware sprite in the TrueColor mode, so the RGBFF_B8G8R8 value is or'ed to this flag field.

RGBFormats:
All RGB formats that the board can use for screen modes are or'ed together in this field, e.g. the CirrusGD542X uses: RGBFF_PLANAR|RGBFF_CHUNKY|RGBFF_B8G8R8|RGBFF_R5G6B5PC|RGBFF_R5G5B5PC

MaxHorValue and MaxVerValue:
The maximum horizontal and vertical values that the chip can handle for the CRTC setting in planar, chunky, HiColor, TrueColor and TrueAlpha modes.

MaxHorResolution and MaxVerResolution:
The maximum horizontal and vertical resolutions that the chip can handle for bitmaps (that might even pan) in planar, chunky, HiColor, TrueColor and TrueAlpha modes.

The difference between those values is: MaxHorValue and MaxVerValue stand for the maximum values you can use e.g. for CRTC_HorizontalTotal, i.e. what is displayable. MaxHorResolution and MaxVerResolution on the other hand stand for how big a screen bitmap may be of which maybe only a small part is displayed, e.g. a 2048x2048 bitmap is displayed on a 640x480 screen. So, the "Value"s stand for limits of e.g. CRTC_HorizontalTotal and the "Resolution"s stand for limits of CRTC_RowOffset.

PixelClockArray:
A pointer to a field of longwords that represent the pixel clock rates (in Hz) the board can handle. This is obsolete as of now. All clocks are queried via GetPixelClock() by the Picasso96 system software.

PixelClockCount:
This indicates how many different clocks are available in planar, chunky, HiColor, TrueColor and TrueAlpha modes, respectively.

Functions:
If not noted otherwise, registers d0/d1/a0/a1 are scratch.
AllocCardMem:
Synopsis:AllocCardMem(bi, size, force, system);
Inputs:a0:struct BoardInfo *bi
d0:ULONG size
d1.w:BOOL force
d2.w:BOOL system

This function allocates a chunk of graphics board memory from the available free board memory and returns a pointer to that chunk. If the flags force and system are set, the function may internally free other chunks to be able to get that much memory. But therefore a mechanism is needed that is available in the rtg.library only. Therefore you should leave this function alone.

FreeCardMem:
Synopsis:FreeCardMem(bi, membase);
Inputs:a0:struct BoardInfo *bi
a1:APTR membase

This function frees a chunk of graphics board memory. The size of the memory must be accounted for internally. Normally, you will leave this function as it is, too.

SetSwitch:
Synopsis:SetSwitch(bi, state);
Inputs:a0:struct BoardInfo *bi
d0.w:BOOL state

This function should set a board switch to let the Amiga signal pass through when supplied with a 0 in d0 and to show the board signal if a 1 is passed in d0. You should remember the current state of the switch to avoid unneeded switching. If your board has no switch, then simply supply a function that does nothing except a RTS.

SetColorArray:
Synopsis:SetColorArray(bi, startindex, count);
Inputs:a0:struct BoardInfo *bi
d0.w:UWORD startindex
d1.w:UWORD count

When this function is called, your driver has to fetch "count" color values starting at "startindex" from the CLUT field of the BoardInfo structure and write them to the hardware. The color values are always between 0 and 255 for each component regardless of the number of bits per cannon your board has. So you might have to shift the colors before writing them to the hardware.

SetDAC:
Synopsis:SetDAC(bi, RGBFormat);
Inputs:a0:struct BoardInfo *bi
d7:RGBFTYPE RGBFormat

This function is called whenever the RGB format of the display changes, e.g. from chunky to TrueColor. Usually, all you have to do is to set the RAMDAC of your board accordingly.

SetGC:
Synopsis:SetGC(bi, mi, border);
Inputs:a0:struct BoardInfo *bi
a1:struct ModeInfo *mi
d0:BOOL border

This function is called whenever another ModeInfo has to be set. This function simply sets up the CRTC and TS registers to generate the timing used for that screen mode. You should not set the DAC, clocks or linear start adress. They will be set by other functions when appropriate.

SetPanning:
Synopsis:SetPanning(bi, Memory, Width, XOffset, YOffset, RGBFormat);
Inputs:a0:struct BoardInfo *bi
a1:UBYTE *Memory
d0:UWORD Width
d1:WORD XOffset
d2:WORD YOffset
d7:RGBFTYPE RGBFormat

This function sets the view origin of a display which might also be overscanned. In register a1 you get the start address of the screen bitmap as an Amiga memory address. You will have to subtract the base address of the board memory from that value to get the memory start offset within the board. Then you get the offset in pixels of the left upper edge of the visible part of an overscanned display. From these values you will have to calculate the LinearStartingAddress fields of the CRTC registers and set the correct values for pixel panning if supported by your VGA chip.

CalculateBytesPerRow:
Synopsis:CalculateBytesPerRow(bi, Width, RGBFormat);
Inputs:a0:struct BoardInfo *bi
d0:UWORD Width
d7:RGBFTYPE RGBFormat
Result:d0:UWORD Count

This function calculates the amount of bytes needed for a line of "Width" pixels in the given RGBFormat. The S3 Trio64 for example only supports blitter operations only for some fixed line lengths and therefore the supplied width value has to be rounded up.

CalculateMemory:
Synopsis:CalculateMemory(bi, Memory, RGBFormat);
Inputs:a0:struct BoardInfo *bi
a1:UBYTE *Memory
d7:RGBFTYPE RGBFormat
Result:d0:UBYTE *Address

This function transforms logical into physical memory addresses. This is normally the same value except for planar bitmaps that use physical offset addresses that are only a forth of the logical offset because the VGA chips store these bitmaps in a different way.
Chip architectures that offer byte-swapping capabilities could use this function to translate the logical address to the desired aperture window.

GetCompatibleFormats:
Synopsis:GetCompatibleFormats(bi, RGBFormat);
Inputs:a0:struct BoardInfo *bi
d7:RGBFTYPE RGBFormat
Result:d0:ULONG mask of formats

This function gets a long work representing all RGBFormats that can coexist simultaneously on the board with a bitmap of the supplied RGBFormat. This is used when a bitmap is put to the board in order to check all bitmaps currently on board if they have to leave. This is for example the case with Cirrus based boards where all chunky and Hi/TrueColor bitmaps must leave whenever a planar bitmap needs to be put to the board, because the formats cannot share the board due to restrictions by that VGA chips.

SetDisplay:
Synopsis:SetDisplay(bi, state);
Inputs:a0:struct BoardInfo *bi
d0:BOOL state

This function enables and disables the video display. On VGA chips this is usually done by changing bit 5 of the TS_TSMode register. The display will become black but the display syncs are still generated.

ResolvePixelClock:
Synopsis:ResolvePixelClock(bi, mi, clock, RGBFormat);
Inputs:a0:struct BoardInfo *bi
a1:struct ModeInfo *mi
d0:LONG pixelclock
d7:RGBFTYPE RGBFormat
Result:d0:ULONG index

This function returns the index number of the pixel clock rate that suits best to the clock rate and RGBFormat supplied according to the clock rates available and writes the corresponding clock parameters to the ModeInfo structure.

GetPixelClock:
Synopsis:GetPixelClock(bi, mi, index, RGBFormat);
Inputs:a0:struct BoardInfo *bi
a1:struct ModeInfo *mi
d0:ULONG index
d7:RGBFTYPE RGBFormat
Result:d0:ULONG pixelclock

This function retrieves the effective pixel clock at position "index" of the pixel clock array. On some chips you have to take the given RGBFormat into account, e.g. with the CirrusGD542X you have to divide the raw pixel clock by three to get the effective pixel clock when using TrueColor modes.

SetClock:
Synopsis:SetClock(bi);
Inputs:a0:struct BoardInfo *bi

This function writes the clock parameters of the ModeInfo that is currently active (bi->ModeInfo) to the hardware.

SetMemoryMode:
Synopsis:SetMemoryMode(bi, RGBFormat);
Inputs:a0:struct BoardInfo *bi
d7:RGBFTYPE RGBFormat

This function sets the memory interface of the chip to use an appropriate setting for the given RGBFormat. For example when using RGBFB_PLANAR, you will have to disable "chain 4 mode". It will be called each time system functions access the onboard memory using the specified RGBFormat.
If you have to configure the board to allow another access mode, e.g. byte-swapping, this would be the right place.
This function must preserve all registers!

SetWriteMask:
Synopsis:SetWriteMask(bi, mask);
Inputs:a0:struct BoardInfo *bi
d0:UBYTE mask

This function sets the TS_WritePlaneMask register which is used for planar modes.
This function must preserve all registers!

SetClearMask:
Synopsis:SetClearMask(bi, mask);
Inputs:a0:struct BoardInfo *bi
d0:UBYTE mask

This function sets the GDC_EnableSetReset register to the "mask" value and clears the GDC_SetReset register. This is used for planar modes.

SetReadPlane:
Synopsis:SetReadPlane(bi, plane);
Inputs:a0:struct BoardInfo *bi
d0:UBYTE plane

This function sets the GDC_ReadPlaneSelect register to the "plane" value. This is used for planar modes.

WaitVerticalSync:
Synopsis:WaitVerticalSync(bi);
Inputs:a0:struct BoardInfo *bi

This function waits for the next vertical retrace.

SetInterrupt:
Synopsis:SetInterrupt(bi, state);
Inputs:a0:struct BoardInfo *bi
d0:state

This function disables or enables the optional board interrupts. Interrupts are disabled automatically during screen switches to avoid problems.

WaitBlitter:
Synopsis:WaitBlitter(bi);
Inputs:a0:struct BoardInfo *bi

This function waits for the completion of any pending blitter operations.

SetSprite:
Synopsis:SetSprite(bi, activate, RGBFormat);
Inputs:a0:struct BoardInfo *bi
d0:BOOL activate
d7:RGBFTYPE RGBFormat

This function activates or deactivates the hardware sprite.

SetSpritePosition:
Synopsis:SetSpritePosition(bi, RGBFormat);
Inputs:a0:struct BoardInfo *bi
d7:RGBFTYPE RGBFormat

This function sets the hardware mouse sprite position according to the values in the BoardInfo structure.
MouseX and MouseY are the coordinates relative to the screen bitmap. XOffset and YOffset must be subtracted to account for possible screen panning.

SetSpriteImage:
Synopsis:SetSpriteImage(bi, RGBFormat);
Inputs:a0:struct BoardInfo *bi
d7:RGBFTYPE RGBFormat

This function gets new sprite image data from the MouseImage field of the BoardInfo structure and writes it to the board.
There are three possible cases:

  • BIB_HIRESSPRITE is set:
    skip the first two long words and the following sprite data is arranged as an array of two longwords. Those form the two bit planes for one image line respectively.
  • BIB_HIRESSPRITE and BIB_BIGSPRITE are not set:
    skip the first two words and the following sprite data is arranged as an array of two words. Those form the two bit planes for one image line respectively.
  • BIB_HIRESSPRITE is not set and BIB_BIGSPRITE is set:
    skip the first two words and the following sprite data is arranged as an array of two words. Those form the two bit planes for one image line respectively. You have to double each pixel horizontally and vertically. All coordinates used in this case already assume a zoomed sprite, only the sprite data is not zoomed yet. You will have to compensate for this when accounting for hotspot offsets and sprite dimensions.

SetSpriteColor:
Synopsis:SetSpriteColor(bi, index, red, green, blue, RGBFormat);
Inputs:a0:struct BoardInfo *bi
d0.b:index
d1.b:red
d2.b:green
d3.b:blue
d7:RGBFTYPE RGBFormat

This function changes one of the possible three colors of the hardware sprite.

BlitPlanar2Chunky:
Synopsis:BlitPlanar2Chunky(bi, bm, ri, SrcX, SrcY, DstX, DstY, SizeX, SizeY, MinTerm, Mask);
Inputs:a0:struct BoardInfo *bi
a1:struct BitMap *bm
a2:struct RenderInfo *ri
d0.w:SrcX
d1.w:SrcY
d2.w:DstX
d3.w:DstY
d4.w:SizeX
d5.w:SizeY
d6.b:MinTerm
d7.b:Mask

This function is currently used to blit from planar bitmaps within system memory to chunky bitmaps on the board. Watch out for plane pointers that are 0x00000000 (represents a plane with all bits "0") or 0xffffffff (represents a plane with all bits "1").

FillRect:
Synopsis:FillRect(bi, ri, X, Y, Width, Height, Pen, Mask, RGBFormat);
Inputs:a0:struct BoardInfo *bi
a1:struct RenderInfo *ri
d0.w:X
d1.w:Y
d2.w:Width
d3.w:Height
d4.l:Pen
d5.b:Mask
d7.l:RGBFormat

This function fills a rectangular area on the board with a given pen or Hi/TrueColor value. It is called by BltBitMap, BltPattern, SetRast and to clear or init a bitmap on the board.

InvertRect:
Synopsis:InvertRect(bi, ri, X, Y, Width, Height, Mask, RGBFormat);
Inputs:a0:struct BoardInfo *bi
a1:struct RenderInfo *ri
d0.w:X
d1.w:Y
d2.w:Width
d3.w:Height
d4.l:Mask
d7.l:RGBFormat

This function is used to invert a rectangular area on the board. It is called by BltBitMap, BltPattern and BltTemplate.

BlitRect:
Synopsis:BlitRect(bi, ri, SrcX, SrcY, DstX, DstY, SizeX, SizeY, Mask, RGBFormat);
Inputs:a0:struct BoardInfo *bi
a1:struct RenderInfo *ri
d0.w:SrcX
d1.w:SrcY
d2.w:DstX
d3.w:DstY
d4.w:SizeX
d5.w:SizeY
d6.b:Mask
d7.l:RGBFormat

This function is used to copy a rectangle within one pixel area on the board. It is called by BltBitMap.

BlitTemplate:
Synopsis:BlitTemplate(bi, ri, template, X, Y, Width, Height, Mask, RGBFormat);
Inputs:a0:struct BoardInfo *bi
a1:struct RenderInfo *ri
a2:struct Template *template
d0.w:X
d1.w:Y
d2.w:Width
d3.w:Height
d4.w:Mask
d7.l:RGBFormat

This function is used to paint a template on the board memory using the blitter. It is called by BltPattern and BltTemplate. The template consists of a b/w image using a single plane of image data which will be expanded to the destination RGBFormat using ForeGround and BackGround pens as well as draw modes.

BlitPattern:
Synopsis:BlitPattern(bi, ri, pattern, X, Y, Width, Height, Mask, RGBFormat);
Inputs:a0:struct BoardInfo *bi
a1:struct RenderInfo *ri
a2:struct Pattern *pattern
d0.w:X
d1.w:Y
d2.w:Width
d3.w:Height
d4.w:Mask
d7.l:RGBFormat

This function is used to paint a pattern on the board memory using the blitter. It is called by BltPattern, if a AreaPtrn is used with positive AreaPtSz. The pattern consists of a b/w image using a single plane of image data which will be expanded repeatedly to the destination RGBFormat using ForeGround and BackGround pens as well as draw modes. The width of the pattern data is always 16 pixels (one word) and the height is calculated as 2^Size. The data must be shifted up and to the left by XOffset and YOffset pixels at the beginning.

DrawLine:
This function is currently not used.

BlitRectNoMaskComplete:
Synopsis:BlitRectNoMaskComplete(bi, sri, dri, SrcX, SrcY, DstX, DstY, SizeX, SizeY, OpCode, RGBFormat);
Inputs:a0:struct BoardInfo *bi
a1:struct RenderInfo *sri
a2:struct RenderInfo *dri
d0.w:SrcX
d1.w:SrcY
d2.w:DstX
d3.w:DstY
d4.w:SizeX
d5.w:SizeY
d6.b:OpCode
d7.l:RGBFormat

This function is used to blit a rectangle from one area of pixels to another area using all possible opcodes but without mask.

ResetChip:
Synopsis:ResetChip(bi);
Inputs:a0:struct BoardInfo *bi

This function is currently not used. Its purpose will be to provide a mechanism to initialize the card after a Picasso96API client has used the board with direct accesses to the hardware.

SetDPMSLevel:
Synopsis:SetDPMSLevel(bi, DPMSLevel);
Inputs:a0:struct BoardInfo *bi
d0:ULONG DPMSLevel

This function sets the DPMS level supplied. Valid values are (see boardinfo.h):

  • DPMS_ON (normal operation),
  • DPMS_STANDBY (Optional state of minimal power reduction),
  • DPMS_SUSPEND (Significant reduction of power consumption),
  • DPMS_OFF (Monitor off, lowest level of power consumption)

GetFeatureAttrs:
CreateFeature:
SetFeatureAttrs:
DeleteFeature:
These functions handle the use of special features like flicker fixer, video and other modules. If you need these, please call for assistance. :-))

Dynamic data:
The remaining parts of the BoardInfo structure are for exclusive use by the rtg.library and you must not modify any data contained there. You should not even depend on anything there. If you think that you might need anything from it think twice and if you are still convinced you need it, ask us for a viable solution. We reserve to change the internal implementation and behaviour for further system enhancements.

Development Setup

Environment

If you start by changing one of the supplied driver sources you should set up your programming environment like this:
  1. create a Picasso96Develop directory,
  2. add an assign "p96:" to it,
  3. extract the CardDevelop.lha and Develop.lha archives to this directory,
  4. get current versions of PhxAss and PhxLnk from Aminet and install them,
  5. change the SMakeFile in p96:HardWare to use "P96:Include" instead of "P96:PublicInclude" and change the line "all: $(CARDS) $(CHIPS)" to "all: <names of the targets you have got sources for...>",
  6. try to make the targets for the supplied source files.
This setup assumes that you have the SAS C compiler installed. We make use of the capabilities of SMake. If you want to use another make utility you might have to adjust the makefile.

If the assembler or compiler gives errors about being unable to find an include file you might want to use SnoopDOS to get an idea which one is affected. You might give the source the absolute path of this include file or include its home directory in the list of include directories.

If you are not successful in building the drivers, please call for assistance.

Languages

I would prefer to use C for programming my code. Is there any problem?

No, not at all.
All you have to care for is that your code uses register arguments as defined and that your routines are written to the BoardInfo structure during initialisation.

Do not use global variables! If you need any global data, use the ChipData and CardData fields of the BoardInfo structure!


This document is currently under development.
tabt, July, 13th 1997