[comp.sys.amiga] serial expansion structures

jesup@pawl16.pawl.rpi.edu (Randell E. Jesup) (01/19/88)

[ This is a better version of the file I posted yesterday.  There is more
  explanation, and I have enxtended the structures to allow naming of other
  types of hardware as well (such as parallel ports).  This has been posted on 
  Bix as well.   -  Randell Jesup ]

/* This is a first cut at the in-memory data structures for the mapping and
   to identify what serial boards are in the system.  I've tried to make
   sure it is easily expanded in the future.  Comments and suggestions would
   be greatly appreciated, even more so from people doing serial expansion
   boards.  These are by no means graven in silly putty. :-)
   	Randell Jesup, Lunge Software, 13 Frear Ave, Troy, NY 12180
   	(518) 272-2942
*/

/* The structures were designed for easy use with the Exec list-handling */
/* routines.								 */
/* I've tried to make these multiples of 8 bytes long.			 */

/* explanation of structures:
	Each type of expansion board may have several boards.
	Each board may have several units.
	Each unit may have several names (mappings).

	There are lists of boards, units, and mappings for each type of
	expansion board.

	Each mapping is linked to it's unit, each unit is linked to
	it's board.  This allows you to find what unit a mapping is for.

	In addition, boards are linked to their units, and units are
	linked to their mappings, in singly linked lists, so one may
	traverse, for example, all mappings of a unit.
*/

#define ALL_BOARD_TYPES	0x0000FFFF
#define MAP_RESERVED	~(ALL_BOARD_TYPES)

#define MAPB_SERIAL	0
#define MAPB_PARALLEL	1
#define MAPF_SERIAL	(1L << MAPB_SERIAL)
#define MAPF_PARALLEL	(1L << MAPB_PARALLEL)

#define MAPPERLIB_NAME	"mapper.library"
#define MAPPER_VERSION	33

struct Mapping {
	struct Node MappingNode;
	/* ln_Name points to null-terminated name, allocmem'ed */
	/* Flags should be NULL for now! */
	/* Note: prioritized node - 0 is default */
	/* Type should be 0 for now */
	struct Mapping *NextMapping;	/* next mapping for same unit */
	struct ExpansionUnit *Unit;	/* which unit associated with */
	WORD MapReserved;		/* set to 0!!! */
};

struct ExpansionUnit {
	struct Node UnitNode;
	UWORD UnitNumber;
	ULONG Flags;			/* 0 for now */
	struct ExpansionUnit *NextUnit;	/* all units of a board are linked */
	struct SerialBoard *Board;	/* links back to board */
	struct Mapping *FirstMapping;	/* mappings for this unit */
	CPTR  UnitData;			/* for private use by driver */
	CPTR  UnitReserved;		/* Future expansion */
};

struct ExpansionBoard {
	struct Node BoardNode;	/* ln_Name must be set to device name! */
		        /* Note: not with any path eg: myserial.device */
	UWORD NumUnits;		/* units on this board */
	ULONG Flags;		/* 0 for now */
	ULONG ManufacturerID;
	ULONG ProductID;
	CPTR  BoardAddress;	/* address board was assigned */
	CPTR  BoardData;	/* for driver private use */
	struct Device *Device;	/* null means not loaded */
	UBYTE *DeviceName;	/* file name of device to load */
				/* include path. eg: DEVS:myserial.device */
	struct ExpansionUnit *FirstUnit;
	/* The other units are linked through NextUnit to FirstUnit */
	CPTR  BoardReserved[2];	/* leave NULL!!!! */
};

struct ExpansionType {
	struct Node TypeNode;
	ULONG Flags;			/* MAPF_SERIAL for serial ports */
	struct List BoardList;		/* list of ExpansionBoards */
	struct List UnitList;		/* list of ExpansionUnits */
	struct List MappingList;	/* list of names (prioritized) */
	CPTR TypeReserved;
};

struct MapperBase {
	struct Library MapLibrary;
	ULONG Flags;			/* NULL for now */
	struct Semaphore MapperAccess;	/* MUST obtain before looking */
					/* at or modifying lists */
	struct List TypeList;		/* Find the type you want */
					/* points to struct ExpansionType */
	CPTR Reserved[4]; /* I want a bunch of space for expansion here */
};

/*
 *	To access any of the lists, you MUST obtain the semaphore!!!!
 *
 *	This is designed so the name mapper can be used for other types
 *	of expansion hardware, such as parallel ports (or anything else).
 *	You should set the MAPF_SERIAL flag in the ExpansionType structures
 *	for a serial port.
 *
 * 	The MapperBase, ExpansionBoard and ExpansionUnit structure lists
 *	should remain in memory after creation.  The Mapping structures can
 *	be released; note the name was obtained by AllocMem(strlen(name)+1,
 *	MEMF_PUBLIC).  Do not release a Mapping structure if the
 *	MapReserved field is non-null (for safe expansion).
 *
 *	All these structures should be in public memory.  The private data
 *	areas for the drivers are meant for data storage when the driver
 *	isn't loaded (or hasn't been loaded yet.)
 *
 *	The code attached to each icon in the expansion drawer should
 *	create a ExpansionBoard structure for each board it is handling.
 *	It should create a ExpansionUnit structure for each unit on the
 *	board.  Finally, it should create a Mapping structure for each
 *	mapping specified in the icon.  Note: the lists of Mappings are
 *	prioritized, default is 0.
 *
 *	The syntax for the tooltypes in the icons is:
 *		<name>     := <non-whitespace chars excluding ':'>;
 *			     /* should these be case sensitive? */
 *			     /* if so, what about foreign languages? */
 *			     /* should whitespace be allowed? */
 *		<mapping>  := <name>[:<priority>];
 *		<tooltype> := Unit_<number>=<mapping>[|<mapping>...]
 *
 *	General flowchart for expansion drawer code:
 *		<init>
 *		<open mapper library>
 *		<if open failed> {
 *			<create library, then open>
 *			<create XSER: handler entry in handler list>
 *		}
 *		<Obtain semaphore for lists>
 *		<if your expansion type doesn't exist> {
 *			<create ExpansionType structure for your type>
 *		}
 *		<GetDiskObject for the tooltypes>
 *		<for each board you will handle> {
 *			<do any board init needed>
 *			<mark board as configed>
 *			<create and add ExpansionBoard struct>
 *			<for each unit> {
 *				<create and add ExpansionUnit struct>
 *				<for each mapping for the unit> {
 *					<create and add Mapping struct>
 *				}
 *			}
 *		}
 *		<release semaphore, close mapper library>
 *		<do anything else you want>
 *		<clean up, release stuff like libraries>
 *		<if driver not loaded now and not in rom>
 *			<return NULL>
 *		<else do whatever, return non-NULL>
 *
 */

Comments, suggestions, or outright attacks :-) are welcomed.

     //	Randell Jesup			      Lunge Software Development
    //	Dedicated Amiga Programmer            13 Frear Ave, Troy, NY 12180
 \\//	beowulf!lunge!jesup@steinmetz.UUCP    (518) 272-2942
  \/    (uunet!steinmetz!beowulf!lunge!jesup) BIX: rjesup