Article # 50, added by Geoworks, historical record
| first | previous | index | next | last |

The structure of GEODEs (both disk and memory).




This file contains the specification and technical design for the
structure of GEODEs, both on disk and in memory.

The original file is located in /s/p/Spec/geode.doc and was last updated
$Id: geode.doc,v 1.25 89/09/28 19:24:29 tony Exp $

****************************************************************************

geodeContents:
geodeGoals		- Goals and objectives for GEODEs
geodeOverview		- Overview of GEODEs
geodeDisk		- GEODE structure on disk
geodeCoreBlock		- Structure of a GEODE's core block
geodeLibraries		- Implementation of libraries
geodeRelocations	- Implementation of relocation tables
geodeResources		- Implementation of resources
geodeDrivers		- Implementation of drivers

****************************************************************************

Goals and objectives for GEODEs
-------------------------------
geodeGoals:

	PC GEOS supports many different types of files and processes.  Some
of these are: applications, drivers, libraries and resources.  These things,
called "GEODEs" (a geode is a special lump of rock that, if you break it open,
contains all sorts of beautiful crystals inside. The analogy seems apt),
share a common structure.  This common structure:

	* Be protected mode compatible.

	* Allows flexibility -- a driver can easily have initialized data, an
	  associated process and resources.

	* Conserves code -- The same kernel code loads any code segment,
	  whether part of an application, a driver or a library.

	* Allows objects to be loaded as resources.

****************************************************************************

Overview of GEODEs
------------------
geodeSummary:
See also	[ contents, geodeContents, codeFlowContents ]

A GEODE is a combination of:

On disk:
	* A signature that marks the file as being a geode
	* A header that contains name, version, type and resource tables
	* Resources (blocks of code or data)
	* For each resource, a table of relocations for that resource

In memory:
	* A "core block" that contains the system variables (many of which
	  come from the geode header on disk)
	* A "dgroup" that contains the initialized and uninitialized data
	  for the geode.  This segment also contains the stack for the first
	  thread (if a process)
	* For each thread: a stack segment for the thread
	* Resource segments that contain data loaded from the resources on disk

	Examples of GEODEs and their typical components are:

	* Applications -- Code, initialized data, event queue, stack, resources
			  and possibly an imported library table.
	* Library -- Code, an exported library table and possibly initialized
		     data, stack and resources.
	* Driver -- Code, an exported library table and possibly initialized
		    data, stack and resources.

GEODE structure on disk
-----------------------
geodeDisk:
See also	[ contents, geodeContents, geosFileStructure ]
		[ appCallKernel ]

	GEODEs are MS-DOS files with the extension ".geo".

	The file is composed of several parts which appear in this order:

	* The header which is a fixed size and contains basic information about
	  the GEODE.  Since the header is discarded after loading the GEODE,
	  pieces of information that are only needed during the loading process
	  are kept here.

	* The core data information which is variable sized and contains tables
	  depending on the composition of the GEODE.  This information is
	  loaded into the core block and is left there.  Thus pieces of
	  information that are needed at any time while the GEODE is active
	  are kept here.

	* Load tables (OPTIONAL).  Tables only needed while loading GEODE.

	* Initialized data (OPTIONAL).

	* Resource segments (code and/or data) (OPTIONAL).

	The structure of the file is:

name			size	description
----			----	-----------

	*** HEADER ***

				*** Generic file information ***
				*** This part will be common to all PC
				*** GEOS files.
geodehSignature		dword	signature -- "GEOS" with high bits of G, O set
geodehAttibutes		word	flags, see [ geodeAttributes ]
geodehFileType		word	GEODE file type, see [ geodeAttributes ]
geodehVersion		word	version of GEODE format - 1 for now
geodehResourceCount	word	number of resources
geodehImportLibraryCount word	number of imported libraries
geodehUDataSize		word	size of uninitialized data

					*** Object information
geodehClassOffset	word	offset of geode's class table (if any)
geodehClassSegment	word	segment of geode's class table (if any)

					*** User interface information
geodehAppObjChunkHandle	word	LMem handle of application object
geodehAppObjResource	word	Resource ID of application object


	*** CORE DATA INFORMATION ***

				*** Standard information
GH_geodeHandle		word	handle to this segment (0 in file)

				*** Generic information ***
GH_geodeAttr		word	COPY OF geodehAttributes
GH_geodeFileType	word	COPY OF geodehFileType
GH_geodeVersion		word	COPY OF geodehVersion
GH_geodeSerial		word	Serial number for geode (set by exe2geos)

GH_geodeName		8 byte	name (permanent name of GEODE) (must match
				library name and file name if a library)
GH_geodeNameExt		4 byte	name extension
GH_geodeRevision	word	revision of GEODE
GH_geodeRefCount	word	reference count for GEODE

				*** Driver variables
GH_driverTabOff		word	offset (in memory) of driver table (table is
				part of idata)
GH_driverTabSegment	word	resource ID of driver table (converted to
				segment when loaded)

				*** Exported library information
GH_libraryEntryOff	word	offset of library entry routine
GH_libraryEntrySegment	word	resource ID of library entry routine table
				(converted to segment when loaded)
GH_exportLibTabOff	word	Offset to entry point table for
				exported library routines
GH_exportLibTabSegment	word	resource ID of entry point table (converted to
				segment when loaded)

				*** Imported library information ***
GH_libCount		word	number of imported library table entries
GH_libOffset		word	offset (in memory) of imported library table
				(0 in file)

				*** Resource information ***
GH_resCount		word	number of resources
GH_resHandleOff		word	offset (in memory) of resource handle table
				(0 in file)
GH_resPosOff		word	offset (in memory) of resource position table
				(0 in file)
GH_resRelocOff		word	offset (in memory) of resource relocation size
				table
				(0 in file)

	*** END OF CORE DATA ***

	*** LOAD TABLES ***

				*** Imported library table (OPTIONAL) ***
geodeLibraryTable	#libs*8	imported library table, each entry being the
				name of the library.

				*** Resource table ***
geodeResourceHandles	#res*2	size of each resource
geodeResourceFilePos	#res*4	position of each code module in file
geodeResourceRelocSize	#res*2	size of each module's relocation table
geodeResourceFlags	#res*2	allocation flags for each resource (high byte
				currently unused)

	*** RESOURCE SEGMENTS (MUST BE AT LEAST ONE) ***

				*** For each resource segment
			???	resource
			#rel*2	relocation table

Structure of a GEODE
--------------------
geodeCoreBlock:
See also	[ contents, geodeContents ]

	In memory, every GEODE has a core block.  The core block is a fixed
block that contains information about the GEODE.  The core block contains:

	* GEODE global variables: version, type, name, etc.

	* Process variables: Valid only if this GEODE is a process

	* Imported library table (optional)

	* Resource tables

name		size	description
----		----	-----------
	*** GEODE global variables

	*** The first variables are a copy of the core block information
	    from the GEODE file.

				*** General variables
GH_geoHandle		word	handle to GEODE's .geo file
GH_parentProcess	word	handle of parent process
GH_nextGeode		word	segment address of next GEODE on list

	*** The remaining state variables are only present if the GEODE is
	*** a process

				*** Object information
PH_geodeClass		dword	pointer to geode's class structure
PH_appObject
PH_vmHandle
PH_savedBlockPtr

PH_firstThread
PH_processAttr
PH_processStatus

PH_eventFrontPtr
PH_eventBackPtr
PH_eventCounter
PH_eventSem

PH_stdFileHandles
PH_lastPath
PH_currentPath

	*** Resource table (optional)

resourceHandles		#res*2	handle of each resource
resourceFilePos		#res*4	position of each code module in file
resourceRelocSize	#res*2  size of each module's relocation table

	*** Imported library table (optional)

librarySegTable		#libs*2	segment address of library's core block

Relocations
-----------
geodeRelocations:
See also	[ contents, geodeContents ]

	When PC GEOS loads in resources, several types of references
need to be relocated.  A relocation table immediately follows the data for
each resource.  Each relocation entry is two words: one word being relocation
data and the other word being the offset of the relocation.  The first word of
data at the relocation gives additional information.

Relocation entry in table:

DeclareEnum	GeodeRelocationSources, byte

	; Relocation to a kernel entry point.
	;	GRE_extra - unused
	;	word at relocation - kernel entry point number
	Enum	GeodeRelocationSources, GRS_KERNEL

	; Relocation to a library entry point.
	;	GRE_extra - imported library number
	;	word at relocation - library entry point number
	Enum	GeodeRelocationSources, GRS_LIBRARY

	; Relocation to a resource of the geode.  This is never used with
	; GRT_OFFSET or GRT_FAR_PTR since the linker eliminates GRT_OFFSET and
	; convert GRT_FAR_PTR to GRT_SEGMENT.
	;	GRE_extra - unused
	;	word at relocation - resource number
	;	for GRT_CALL - word at relocation+2 - offset of call
	Enum	GeodeRelocationSources, GRS_RESOURCE	;geode's resource


DeclareEnum	GeodeRelocationTypes, byte

	; Relocation to a far pointer to an entry point (4 bytes).  If the
	; target is movable then the segment is replaced by the handle>>4.  The
	; second word of data at the target is not used.
	Enum	GeodeRelocationTypes, GRT_FAR_PTR

	; Relocation to the offset of an entry point (2 bytes).
	Enum	GeodeRelocationTypes, GRT_OFFSET

	; Relocation to the segment of an entry point (2 bytes).  If the
	; target is movable then the segment is replace by the handle>>4.
	Enum	GeodeRelocationTypes, GRT_SEGMENT

	; Relocation to the handle of an entry point (2 bytes).
	Enum	GeodeRelocationTypes, GRT_HANDLE

	; Relocation to a call to a possibly movable routine (5 bytes).  The
	; offset stored points to the byte AFTER the call opcode.  If the
	; target is fixed, behavior is the same as GRT_FAR_PTR.  If the
	; target is movable, the call opcode is replaced with a software
	; interrupt and the other three bytes are replaced with data that
	; defines the call.
	;    Library calls:
	;	bytes 0 and 1:INT LIBRARY_CALL_INT
	;	byte 2: high byte of library handle
	;	byte 3: (low byte of library handle) | (high 4 bits of entry #)
	;		
	;	byte 4: low byte of library entry #
	;    Geode resource calls:
	;	Sixteen Software interrupts are used for geode resource calls
	;	with the low four bits of the interrupt number being the
	;	low byte of the handle to call
	;	bytes 0 and 1:INT RESOURCE_CALL_INT..RESOURCE_CALL_INT+15
	;	byte 2: high byte of handle
	;	byte 3 and 4: offset of call
	Enum	GeodeRelocationTypes, GRT_CALL


GeodeRelocationInfo	record	GRI_SOURCE:4=GeodeRelocationSources, GRI_TYPE:4=GeodeRelocationTypes


GeodeRelocationEntry	struc
    GRE_info	db	GeodeRelocationInfo
    GRE_extra	db	?			;extra data depending on source
    GRE_offset	dw	?			;offset of relocation
GeodeRelocationEntry	ends


GEODE management
----------------
geodeManagement:
See also	[ contents, geodeContents ]

	PC GEOS keeps a linked list of all GEODEs in the system.  The
list is ordered chronologically, the first GEODE in the list is the
oldest, the last GEODE in the list is the youngest.  This ordering is
maintained by adding new GEODEs at the end of the list.

	When a GEODE is loaded the internal routine FindMatchingGeode
is called to see if another instance of the GEODE is already loaded.
If this is the case, the shared resource handles are copied from the first
instance.

	When a GEODE is removed (via GeodeRemove), it is removed
from the GEODE list and the routine FindMatchingGeode is called.  If
it returns TRUE, the shared resource handles are not freed. If the handles
are owned by the removed geode, their ownership changes to the next instance
of the geode still around.

	The GEODE variable geodeRefCount is set to (PROCESS + DRIVER)
when the GEODE is loaded.  Each call to the internal routine
UseLibrary increments geodeRefCount, each call to FreeLibrary
decrements it.  When the count reaches zero the GEODE is removed from
memory.

	Entry into the GEODE management routines GeodeLoad and
GeodeRemove is controlled by the semaphore geodeSem.

General GEODE routines
----------------------
geodeRoutines:
See also	[ contents, geodeContents ]

GeodeInfoSystem:
	Desc:	Return information about the GEODEs in the system.
	Pass:
	Return:	word - number of drivers loaded
		word - number of libraries loaded
		word - number of processes loaded
		word - total number of GEODEs loaded
		word - number of system GEODEs

GeodeLoad:
	Desc:	Load a GEODE and take action depending on its type.  If the
		GEODE is a process, a process is created.  If the GEODE is a
		library, the library is loaded and initialized.  If the GEODE
		is a driver, the driver is loaded and initialized
	Pass:	word - attributes to match
		word - attributes to NOT match
		word - flags for file type to match (0 matches all)
	Return:	word - error code

GeodeEnum:
	Desc:	Enumerate the current GEODEs in the system.  The
		GeodeInfoSystem routine can be called to find the number of
		GEODEs loaded.
	Pass:	pointer - buffer for GeodeEnumStruct structures
		word - max number of structures that can fit in the buffer
		word - attributes to match
		word - attributes to NOT match
	Return:	in buffer - names and handles of geodes
		word - number of geodes found

GeodeFind:
	Desc:	Find a GEODE given its name.  Note that this routine might
		return handles to drivers and libraries that are in the
		kernel (handle < 80h).  These handles can only be used for
		the driver and library functions.
	Pass:	pointer - name of GEODE to find
		word - attributes to match
		word - attributes to NOT match
	Return:	word - handle of driver

GeodeInfo:
	Desc:	Return information about a GEODE
	Pass:	word - handle of GEODE to get info for
	Return:	word - GEODE attributes
		word - GEODE segment address
		word - GEODE type

Drivers
-------
geodeDrivers:
See also	[ contents, geodeContents ]

	Drivers are primarily used to link PC GEOS to the hardware.  Drivers
are linked together with the nextDriver field in the core block.  Drivers
are accessed through a single entry point, their strategy routine.  This
routine is located in the first code block at the offset given in the core
block.

	A driver's strategy address is obtained by calling GeodeInfo to get the
driver's info table address and looking up the strategy routine in this table.

	The strategy routine is passed a function number that selects the
driver function to execute.  The function number is passed in the DI.  The
functions are listed in "Driver Functions" below.

GeodeRemoveDriver:
	Desc:	Remove a driver
	Pass:	word - handle of driver to remove
	Return:

GeodeInfoDriver:
	Desc:	Return information about a driver
	Pass:	word - handle of driver to get info for
	Return:	pointer - driver's info table

GeodeInfoDefaultDriver:
	Desc:	Return information about default drivers
	Pass:	none
	Return:	word - handle of default video driver

	Drivers have a information table in them that can be accessed
externally.  The table is pointed to by driverTable.  The first part of the
table is the same for all dirvers, the rest is driver type specific.  The
standard first part is:

strategy		dword		;segment:offset of strategy routine
driverAttributes	word		;device attributes for driver
driverType		word		;type of driver


Library routines
----------------
geodeLibraries:
See also	[ contents, geodeContents ]

	Libraries provide a means for sharing code between applications.
Libraries are referred to by name.  The name of the library is the permanent
name of its GEODE.  When a GEODE is loaded, all libraries used by the GEODE are
loaded by calling the kernel routine UseLibrary.

	Libraries are accessed via the first code block which must be fixed.
Library entry points can be anywhere in this code block.

	The kernel keeps track of libraries by linking them together in a
list pointed to by libraryListPtr.

	The (internal) kernel routines to implement libraries are:

UseLibrary:
	Desc:	Use the given library.  If it is not loaded, find it and
		load it.  If it is loaded, increment is reference count.
	Pass:	pointer - name of library to use
	Return:	word - handle of library

	Libraries must have one special routine, "LibraryEntry".  The
LibraryEntry routine is called to initialize and to exit the library.  This
routine is called each time a process uses or stops using the library.

LibraryEntry:
	Desc:	Initialize or exit a library.
	Pass:	di - LibraryCallTypes:
			LCT_ATTACH - When loaded
			LCT_DETACH - When about to go away
		cx:dx - data from command line
		ds - core block for library
	Return:	none
	Can destroy:	ax, bx, cx, dx, si, di, bp, ds, es


Resources
---------
geodeResources:
See also	[ contents, geodeContents ]

	Resources are segments of data belonging to the GEODE.  Resources are
identified by handles.  The handles are memory handles with the "otherInfo"
field reserved.

	In addition to these routines, the heap routines can be used with
resource handles.  Specifically, MemUnlock will unlock a locked
resource and MemDiscard will remove a resource from memory.


GeodeLockResource:
	Desc:	Use the given resource.  If it is not loaded, allocate a block
		of memory for it and load it.  Lock the resource.
	Pass:	word - resource handle
	Return:	word - segment address of resource (locked)


Geode Attributes and Types
--------------------------
geodeAttributes:
See also	[ contents, geodeContents ]

	The geodeAttributes word is defined as:

	bit 15: set for process
	bit 14: set for library
	bit 13: set for driver
	bit 12: set for resource file
	bit 11: set for auto-exec
	bit 10: set if GEODE file must be kept open after loading
	bit 9:  set if GEODE is a system GEODE (part of the kernel)
	bit 8: set if GEODE is multi-launchable (will be clear, e.g., for
	       drivers).
	bits 7-0: reserved

	The geodeType word is defined as:

	1 - Application
	2 - Library
	3 - Driver

    	This is used primarily to indicate where to find the .geo file if it's
not in the current directory (e.g. if a geode is found in the Application
source tree, its geodeType would be Application).

	The driverAttributes word is defined as:

	bit 15: set if driver supports "file system" interface
	bit 14: set if driver is a character device (valid only if bit 15 set)

	The driverType word is defined as:

	1 - Video driver
	2 - Input device driver
	3 - Mass storage block device driver
	4 - Serial I/O character device driver
	5 - Parallel I/O character device driver


Driver Functions
----------------
driverFunctions:
See also	[ contents, geodeContents ]

	Driver function numbers are multiples of two to allow faster access
to a jump table.  The following driver functions are available:

Number	Name		Description
------	----		-----------

	0 - 4 *** These functions are available for all drivers

0	DR_INIT		Initialize the driver
			Pass: ds - driver's core block
			Return: carry - set if error
			Destoyed: ax, bx, cx, dx, si, di, bp, ds, es

2	DR_EXIT		Exit the driver
			Pass: ds - driver's core block
			Return: none
			Destoyed: ax, bx, cx, dx, si, di, bp, ds, es

	4 - 9998 *** These functions are driver type dependent

	10000 - ... *** These functions are predefined but are only available
			if the corresponding driver attribute bit is set.


exe2geos
--------

	exe2geos is a tool that converts ".exe" and ".map" files output by
link86 into ".geo" files.

Symbol				Description
------				-----------
PERM_{name} = 1			Permanent name of geode is {name}
NEXT_EXT_{name} = 1		Name extension of geode is {name}
_REFL_{name} = {value}		Allocation flags for resource {name} are {value}
_PCM_{number} = {addr}		Relocation to resourceHandles+2*modNum needs
				to be done at {addr}
_LH_{number} = {addr}		Relocation to library number needs
				to be done at {addr}
REVISION = {value}		This is revision {value} of this geode
PROCESS = {value}		Geode is a process if {value} non-zero
DRIVER = {value}		Geode is a driver if {value} non-zero
LIBRARY = {value}		Geode is a library if {value} non-zero
MULTI_LAUNCHABLE = {value}	Geode is multi-launchable if {value} non-zero
AUTO_EXEC = {value}		Geode is an auto-exec file if {value} non-zero
FILE_TYPE = {value}		geodeFileType set to {value}
eventQueue = {addr}		Address of event queue is {addr}
EVENT_SIZE = {value}		Event queue is {value} bytes long
librarySegTable = {addr}	librarySegTable is at {addr}
NUMBER_OF_LIBRARIES = {value}	Geode imports {value} libraries
resourceHandles = {addr}	Table resourceHandles is at {addr}
resourceFilePos = {addr}	Table resourceFilePos is at {addr}
resourceRelocSize = {addr}	Table resourceRelocSize is at {addr}
NUMBER_OF_RESOURCES = {value}	Geode has {value} resources
exportLibraryTable = {addr}	Table exportLibraryTable is at {addr}

	Process only
_mT_Process = {addr}		Process method table is at {addr}
_hT_Process = {addr}		Process handler table is at {addr}
_mC_Process = {number}		Process has {number} methods

	Library only
LibraryEntry = {addr}		Library entry point is {addr}

	Driver only
DriverTable = {addr}		Driver info table is at {addr}


Segment			Description
-------			-----------
gdata			applvars
idata			initialized data and code in core block (in any)
udata			uninitialized data
sSize			stacks
{name} 'CODE'		resource module {name}
{name} 'LBRY'		library definitions of imported library {name}
{any} 'KERN'		definitions for PC GEOS kernel