[comp.sys.amiga.tech] Resources

dillon@CORY.BERKELEY.EDU (Matt Dillon) (05/04/88)

	I have been refining my ideas on disk resources.  What you see below
is the culmination of that (so far) in a preliminary document.  I intend
to implement this over the summer and into the fall semester.

Side note:  I think I'm going to add a 'read-only' flag and allow resources 
to be shared.  That is, the pointer returned for certain resources will be
allocated just once for that resource, even if many programs are request it.
The resource goes away when all references go away.

Side note II:  If enough people fall in love with this, it will *replace* 
IFF.  Why?  Because Usage-Wise, it is much easier to deal with and is much
more powerful.

	Enjoy,

						-Matt



			    RESOURCE.DOC

		PRELIMINARY DOCUMENT.  COMMENTS PLEASE!

I'm interested in any and all comments on the matter, especially any
ideas on 'standard' reserved structures (apart from those listed and those
in the Amiga includes).

GENERAL:

    In general, the main idea is to be able to specify all sorts of useful
    information, both for the program which uses the resources, and for the
    user to ALLOW HIM TO MODIFY the resources.	IFF does not cut it, as
    you will soon see.

    A basic requirement is to remove ALL WORK from the application program
    which uses the resources.  That is, the program should be able to
    simply GetRes(handle, "titlebitmap") and the call would return a
    completely resolved BitMap structure for use in its title screen.
    Structures which the programmer used to have to build by hand in
    static declarations can be made into resources and resolved
    automatically.

    As far as the application program is concerned, a resource has three
    components:

    (1) A RESOURCE NAME ... any name you care to apply to the resource
    (2) A STRUCTURE NAME    The name of the top level structure defining
	this resource
    (3) The RETURNED POINTER .. what the program gets from GetRes(), a
	pointer to the top level structure which is completely resolved
	and possibly containing pointers to lower level structures.

    The application program specifies the RESOURCE NAME in GetRes().
    It is safe to assume that the programmer knows the structure of his
    personal resources since he created them.	A resource editor, on
    the other hand, should be able to edit ANY resource, and thus lower
    level calls are provided to get more information about a resource
    (such as its STRUCTURE NAME and STRUCTURE FORMAT).  WildCard calls
    are also available.


TECHNICAL:

    how:	bitmask of search areas (0 highest priority).  Usually
		-1 is specified.
    to/from:	area # (0..3)

    area:	0	resources contained in this executable
		1	specified resource file (default:procname.rsrc)
		2	local.rsrc
		3	reserved
		4-31	reserved for now    (huh?)


    handle =	OpenResHandle()
		    Open new resource handle.  Multiple handles may
		    be openned if you wish.

		CloseResHandle(handle)
		    Close resource handle and remove ALL allocated resource
		    information

		GetResError (handle)
		    Get last error

		SetResFile  (handle, filename, how)
		    Set the resource file for area 1.

    ptr     =	GetRes	    (handle, resname , how)
		    Return a pointer to the requested resource or NULL

    value   =	GetResValue (handle, resname , how)   structures <= 8 bytes only.
		    Instead of allocating space for this resource, assume
		    it contains an integral value and return that value,
		    allocating nothing.

    char ** =	GetResList  (handle, wildcard, how)
		    char ** array, list of known resource names matching
		    the */? wildcard name

    char ** =	GetStrList  (handle, wildcard, how)
		    char ** array, list of known structures matching
		    the */? wildcard name.

    char ** =	GetResStrList(handle, strname, how)
		    list of resource names which are of the specified
		    structure format (by structure name)

    rinfo   =	GetResInfo  (handle, resname, how)
		    Get more detailed information about a resource

    sinfo   =	GetStrInfo  (handle, strname, how)
		    Get more detailed information about a structure

		FreeRes     (handle, ptr/ptr*/rinfo/sinfo)
		    Free various allocated items returned by other
		    calls.

    bool    =	CreateRes   (handle, rinfo, to, resolved)
		    Create (add) a new resource.  Two formats are 
		    allowed for the resource data: unresolved and
		    resolved.  E.G.  GetRes() returns a resolved
		    structure, GetResInfo() gives an unresolved structure.
		    Certain types of resources, such as dynamic resources, 
		    can only be created via the GetResInfo() format 
		    (unresolved).

    bool    =	CreateStr   (handle, sinfo, to)
		    Create (add) a new structure def

    bool    =	DeleteRes   (handle, resname, from)
		    Delete some resource

    bool    =	DeleteStr   (handle, strname, from)
		    Delete some structure def.


    RESINFO:
	Resource Information.  NOTE that the resource data block is for
	the entire structure of the resource, including all static
	sub-structures, all in one contiguous chunk (not placed in the
	proper memory types for the structures).

	[0] = resource name
	[1] = master structure name
	[2] = size of data
	[3] = ptr to resource data	(not defined in this document)

    STRINFO:
	Information about a structure.	Any referenced or subreferenced
	structures are included.  All structure ID's are renumbered
	according to their entry #, starting at ID 1.

	[0] = # of entries.  Each entry takes 2 array spots.
	[1] = master structure name	[2] = structure format
	[3] = structure name		[4] = structure format
	[5] = structure name		[6] = structure format
				...


	the structure format is not defined in this document.


STRUCTURE FORMAT, GENERAL CAPABILITIES:

    Structure ID's are tagged in bits 15 and 14 as follows:
	00 - embedded structure
	01 - parent pointer	(rest of ID not used)
	10 - self pointer	(rest of ID not used)
	11 - child pointer

	An ID of 0 is valid only for tag 11:  pointer to unknown
	structure

    This has been thought out, but is too complex to post at this
    stage.  Only the resource-editor needs to deal with the format
    that describes a particular resource structure.

    A resource structure is either (1) statically sized or
    (2) dynamically sized .. i.e. same structure name can have
    different sizes i.e. string data.  In the case of being dynamically
    sized, the format of the dynamic part of the structure is an array
    of the last 'type' in the structure definition.  Each structure also
    has a longword specifying the type of memory it can be placed in.

    dynamic Example:	A BitMap structure is a dynamic structure whos
    format is what you see in the include's but with only ONE plane
    pointer.  The structure is sized to fit as many plane pointers as
    required.  Another dynamic example:  You want a resource which contains
    a pointer to, say, 32K of cleared memory.  32K of zero's would NOT
    exist in the physical file, but would be allocated when you request
    the resource (i.e. if you have MEMF_CLEAR in the flags for some
    structure, no space is actually allocated in the physical file).

    Apart from the header, A structure is made up solely of other
    structures ... a list of structure ID's which refer to children
    (pointers to other structures), embedded structures (e.g. Node
    structure heads an IO request), self pointers (e.g. initialized List
    structure), or parent pointers (e.g. your resource is a doubly
    linked list).

    The child pointer type 'pointer to another structure' is used to give
    a single resource the capability to generate an entire menu with all
    pointers resolved if you wish.   Another example would be the
    capability to generate, say, a BitMap structure complete with data
    in CHIP.  Recursive structures are also allowed, and a general means of
    terminating a recursive structure is provided.



RESERVED STRUCTURE NAMES:
    Please limit name length to <64 bytes.

    void		no storage, always has ID of 0.
    byte or char	8 bit signed value
    word or short	16 bit signed value
    long		32 bit signed value
    ubyte		8 bit unsigned value
    uword		16 bit unsigned value
    ulong		32 bit unsigned value
    ffp 		32 bit fast floating pt number
    ieee		64 bit IEEE floating pt number


    version		short, version #
    revision		short, revision #
    revdate		revision date
    idstring		dynamic storage, identification string
    author		dynamic storage, author(s) of program
    copyright		dynamic storage, copyright notice
    comment		dynamic storage, textual comment
    expert		ubyte expert mode 0..255 (0 = dumb user)

    <all structures in the Amiga includes>

    give me some more names to reserve!!!

ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) (05/06/88)

In article <8805040914.AA24466@cory.Berkeley.EDU> dillon@CORY.BERKELEY.EDU (Matt Dillon) writes:
>
>	I have been refining my ideas on disk resources.  What you see below
>is the culmination of that (so far) in a preliminary document.  I intend
>to implement this over the summer and into the fall semester.
>
	I found it hard to follow in a few places; you were a bit too terse.
But aside from that, I have a few comments.

>Side note II:  If enough people fall in love with this, it will *replace* 
>IFF.  [ ... ]

	Based on this statement alone, I support Matt all the way :-).
I can't *stand* dealing with IFF.

>    value   =	GetResValue (handle, resname, how)   structures <= 8 bytes only.
>		    Instead of allocating space for this resource, assume
>		    it contains an integral value and return that value,
>		    allocating nothing.
>
	Duhhuh?  I don't geddit.

>    char ** =	GetResList  (handle, wildcard, how)
>		    char ** array, list of known resource names matching
>		    the */? wildcard name
>
	One of the good points the IFF designer made in his &^$@&^% document
was that you'll never be able to specify all the possible combinations of
whatever the programmer may care to match against.  Therefore, he asserted
that it was better to say something like:

	GetNextRes (handle, how);

	And let the application worry about excluding what it's not
interested in.  It also makes your job as the library author easier,
since you don't have to put in all the pattern matching stuff.

>    char ** =	GetStrList  (handle, wildcard, how)
>		    char ** array, list of known structures matching
>		    the */? wildcard name.
>
	I have a problem with your use of the abbreviation "str" to mean
"structure".  "Str" connotes the word "string" (character array) in my mind,
and would appreciate the use of "struct" or "struc" instead.

>    RESINFO:

	Things start to get muddy for me around here.  A clarification would
be much appreciated.

>    STRINFO:
>	Information about a structure.	Any referenced or subreferenced
>	structures are included.  All structure ID's are renumbered
>	according to their entry #, starting at ID 1.
>
	You lost me....

	Unless you have any objections, Matt, I'm going to cross-post this
to BIX, since David Joiner (talin@BIX) is interested in this very thing, and
would like to see a single standard.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Leo L. Schwab -- The Guy in The Cape  ihnp4!pacbell -\
 \_ -_		Recumbent Bikes:	      dual ---> !{well,unicom}!ewhac
O----^o	      The Only Way To Fly.	      hplabs / (pronounced "AE-wack")
"Work FOR?  I don't work FOR anybody!  I'm just having fun."  -- The Doctor

dillon@CORY.BERKELEY.EDU (Matt Dillon) (05/06/88)

>	I found it hard to follow in a few places; you were a bit too terse.
>But aside from that, I have a few comments.

	Yah, I know.  Sorry.  My intention is to start a discussion which
hopefully is a bit more well defined than the IPC discussion, which turned
into a huge mess.  Let me outline the essential concepts of my idea without
any of the technical mumbo jumbo.

(1)	At the application level ... a program which uses one or more
resources, I see an extremely simple interface that allows the program to
generate a pointer to a given structure, such as a BitMap structure, where
the entire structure has been filled in ... right down to the bit planes
themselves, and placed in the proper memory type (MEMF_CHIP for the bit
planes).  At the simplest level, the programmer will use a resource editor
to create such a resource and give a name, say "MyTitleScreen".  Then,
all the program needs to do to access it run time is:

	BITMAP *bm = GetRes("MyTitleScreen");

	Simple as that.
	
(2)	Where are resources kept?  I envision that resources will be kept
in several places, most noteably in the executable itself but NOT LOADED
INTO MEMORY.  That is, easily accessable, the user doesn't have to worry
about having to copy extranious files along with some executable, and any
changes to the resource become part of the executable.  Conceivably, the
user of the program would be able to use the resource editor and change
various defaults that are resources (for instance, he could modify the
MyTitleScreen resource).  (Technically, placing resources in executables
can be done by utilizing the overlay capability which leaves the filehandle,
used to LoadSeg() the first overlay segment, open and available).

	Independant resource files would also exist in various known
places... for instance, in S:SYS.RSRC .  The GetRes() call would first
search the executable, then some local file in the 'current' directory,
then S:SYS.RSRC .  Thus, a program would have complete access to system
standard resources and be able to overide any of the system standard
resource names with his own private resource names contained in the
executable or local file.  In fact, we can put an IFF header on such files
(but very little IFF structure).


(3)	This sounds neat and all that, but how the hell do we define the
structure of a resource which can be so complex?  A BitMap *is* complex in 
that it contains POINTERS to BITPLANES.  Other system structures are
even more complex.  A List structure contains pointers into itself (if empty),
and if you want a List of Nodes, say, you have the possibility of 
self-pointers, child-pointers (the 'next' element), and parent pointers
(the 'previous' element).

	Additionaly, various structures need to be in specific types of
memory.  The bitplanes in a BitMap structure need to be in CHIP while the
BitMap structure itself can be in FAST (or whatever is available).

	The Solution is obvious.  First of call, unlike IFF there are
a huge number of structures one might want to make into a resource.  Most
of the structures are taken directly from the Amiga include's (NewWindow,
NewScreen, Font, etc...).  Thus, part of the resource file must describe
the structure of the resources.  Fine.

			So what do we have?

	We have a "BitMap" structure named "MyTitleScreen", we have the
definition of a BitMap structure, and we have the data needed to fill
in the memory we allocate.

	"MyTitleScreen" is the name of the resource, 
	"BitMap" is the structure-name and structure of the resource.

	"<PickYourOwnName>" is the name of some resource,
	"<SomeStandardSystemStructure>" is the structure-name and 
		structure of the resource.

	Get it?  All we need is a definition on the format for structure
defs and we are home free.  A resource editor would be able to edit anybody's
resource!  And a resource can be as simple as a string or as complex as an
entire Menu!

	Technically, the definition of a structure would simply be a list
of structures contained in that structure, terminating with trivial
structures such as a 'char' or 'long'.  See previous document for more
details.

RESOURCE ACCESS:

	The resources that come with a program as part of that program
are known to the program.  The other wildcard calls I specified would be
used mainly by the resource editor which must be able to find arbitrary
resources.  However, I envision a possible use by application programs.
If you chose to have each menu column in a separate resource, you might
want to use the wildcarding to get a 'list' of resources for the purpose
of building a menu:  "MainMenu.??".

					---
				    ENHANCEMENTS

	I envision a couple enhancements for resources that go beyond
	my explanation above.

	(1) Shareable resources, where GetRes() would return a pointer
	    to a shared data structure, which goes away only when all
	    references to it go away.  Say, the 'default' system Font
	    or prefered screen to open new windows, or whatever.

	(2) Dynamically sized resources.  For instance, you have a resource
	    which is a character array.  The structure would be 'char',
	    but the actual resource would be specified to be larger.

	    A BitMap is a prime example:  The structure of the BitMap would
	    have only one PLANEPTR, but the data would be dynamically sized
	    to hold N PLANEPTR's.  The resource library would extend the
	    meaning of the last sub-structure (the one and only PLANEPTR) in
	    the BitMap structure to cover the additional space.

	(3) 'no-storage' resources.  I.E., if you specify a structure which
	    must be placed in 32K of MEMF_CLEAR|MEMF_CHIP memory.  Since
	    you know the memory must be zero'd, there is no need to waste
	    32K of zero's in the disk file.  Talk about useful!

						-Matt


P.S.  In terms of simplifying the command set, I intend to remove the
      requirement that one must obtain a 'handle' to a resource set and
      supply that in every call.  Refer to the previous document.  I
      also had a 'how' argument in many of the calls which specified
      where to look for the resource ... I intend to remove that as well
      and add a call 'SetResHow()' or something.  This simplifies most
      calls to a single argument.

      And if anybody can come up with a better set of function names,
      lay 'em on me!

peter@sugar.UUCP (Peter da Silva) (05/07/88)

I have one comment. You need to tag each resource somehow:

	BITMAP *bm = GetResource("MyTitleScreen", "BITMAP");

Otherwise, what happens when you change it into an audio sample?

Also, given the large number of things you might want, I can potentially
see this becoming quite a large library.

So far it seems very termcap-like. A printable version of the resources
would be handy.
-- 
-- Peter da Silva      `-_-'      ...!hoptoad!academ!uhnix1!sugar!peter
-- "Have you hugged your U wolf today?" ...!bellcore!tness1!sugar!peter
-- Disclaimer: These aren't mere opinions, these are *values*.

shf@well.UUCP (Stuart H. Ferguson) (05/07/88)

Stuff about resource files:

>                PRELIMINARY DOCUMENT.  COMMENTS PLEASE!

>    In general, the main idea is to be able to specify all sorts of useful
>    information, both for the program which uses the resources, and for the
>    user to ALLOW HIM TO MODIFY the resources.  IFF does not cut it, as
>    you will soon see.

Generally, it looks like a really great idea.  It would be really useful
even just for programming purposes to be able to define things in a
better way than static structures, or custom code to build dynamic
structures. 

Contrary to your claim, however, I did not see how IFF doesn't cut it.  
IFF just provides a standard way of storing chunks of bytes in a file -- 
you get to say what the chunks mean.  I don't see why you can't wrap up
what you've devised into a CAT or LIST of FORM RSRC or something like
that.  You don't have to like it, but it IS the standard after all. 

>    A basic requirement is to remove ALL WORK from the application program
>    which uses the resources.  

Right attitude.

>                               That is, the program should be able to
>    simply GetRes(handle, "titlebitmap") and the call would return a
>    completely resolved BitMap structure for use in its title screen.
>    Structures which the programmer used to have to build by hand in
>    static declarations can be made into resources and resolved
>    automatically.

This sounds really great, but things got a little opaque after this
point in the document.  Can you explain a little more about the
internals of your design?  Given that I only kind of half understood it,
my remaining comments may or may not be meaningful.

>    how:        bitmask of search areas (0 highest priority).  Usually
>                -1 is specified.
	:
>    area:       0       resources contained in this executable
>                1       specified resource file (default:procname.rsrc)
	:
	:

Hmm.  How are you going to get at the resources stored *in the
executable*?  Also, will GetRes() end up searching every level for
things?  How do you plan to keep this fast (especially with the current
DOS)? 

>    RESINFO:
>        Resource Information.  NOTE that the resource data block is for

Interesting, but not very illuminating.  How about some more about this?

>    STRINFO:
>        Information about a structure.  Any referenced or subreferenced
>        structures are included.  All structure ID's are renumbered
>        according to their entry #, starting at ID 1.

I take this to mean that each STRINFO refers to one complete structure, 
and that any structure pointers that a structure contains are resolved 
by using the ID tags internal to this instance of STRINFO.  Sounds 
semi-reasonable, I suppose, if this is actually what you meant.

>        [0] = # of entries.  Each entry takes 2 array spots.
>        [1] = master structure name     [2] = structure format
>        [3] = structure name            [4] = structure format

Does this mean that if structure A contains a pointer to structure B, 
then the STRINFO for A contains the format for A and for B?  What if you 
want to refer to structure B by itself, do you need a separate STRINFO
for that as well?  Seems innefficient and prone to problems.  If the
"structure format" for the same structure appears several places you'll 
need checkers to make sure all the structure definitions are the same.  
Why not have each structure defined exactly once and refered to only by 
reference from then on?

>        the structure format is not defined in this document.

Get it on paper quick if you haven't already.

>STRUCTURE FORMAT, GENERAL CAPABILITIES:
>    Structure ID's are tagged in bits 15 and 14 as follows:
...
>        01 - parent pointer     (rest of ID not used)

What if two higher-level structures point at this struct?  How does it 
tell which is the parent?  Seems like you need to use the ID for this 
case as well.

>RESERVED STRUCTURE NAMES:

An awful lot here.  How big is the resource file which defines all these 
going to be, and how fast will it be to read?  My fear in looking at 
this is that the resouce.library (?) will have to be a mini-compiler and 
reading all the structure definitions will take the kind of memory and 
time that a compiler takes.  Obvoiusly, since I don't know the internals 
my fears are probably ungrounded.  Please say something about efficiency
issues in your future postings. 

Good work!
-- 
		Stuart Ferguson		(shf@well.UUCP)
		Action by HAVOC		(shf@Solar.Stanford.EDU)

dillon@CORY.BERKELEY.EDU (Matt Dillon) (05/08/88)

>I have one comment. You need to tag each resource somehow:
>
>	BITMAP *bm = GetResource("MyTitleScreen", "BITMAP");
>
>Otherwise, what happens when you change it into an audio sample?

	It blows up.  Of course, since the programmer defined that
resource to be a BitMap, he knows what it is.  You bring up a good
point here.  The resources are tagged, obviously, since the resource
library needs to know the structure to 'decode' them.  The question
is, should I *force* the application program to also specify a structure
name along with the resource name?
	
>Also, given the large number of things you might want, I can potentially
>see this becoming quite a large library.
>
>So far it seems very termcap-like. A printable version of the resources
>would be handy.

	Huge in fact... think of all the neat things you could put in
there!  So far, a particular resource 'file' is broken up into three
parts:
	(1) structure defs
	(2) dictionary of resource names
	(3) Data pertaining to the resources

	I.E. (1) and (2) would be quite small in size ... one could read
all the structure defs and resource name dictionary in a single operation,
while (3) would be huge since it contains the actual data... but since
we know the location of the data we want from (2), access to (3) would
be fast.  

>Question in another posting on the structure format

	A structure is made of other structures.  For instance, a
BitMap is made up of the following structures: (uword,uword,ubyte,ubyte,
uword,ubyte*[0..N]).  Each 'structure' in a structure is referenced by
a 2 byte descriptor.  The upper two bits identify whether you want to
embed the sub-structure or have a pointer to the sub-structure (and
other possibilities).  This is what distinguishes, say, a MsgPort from
a pointer to a MsgPort.

	For structures containing pointers to sub-structures, the DATA
part of the resource would be not only for the master structure, but
also for any sub-strutures (or sub-sub-structures, etc...)

					-Matt
	

thomson@utah-cs.UUCP (Richard A Thomson) (05/09/88)

In article <8805080154.AA23107@cory.Berkeley.EDU> dillon@CORY.BERKELEY.EDU (Matt Dillon) writes:
>>I have one comment. You need to tag each resource somehow:
>>
>>	BITMAP *bm = GetResource("MyTitleScreen", "BITMAP");
>>
>>Otherwise, what happens when you change it into an audio sample?
>
>	It blows up.  Of course, since the programmer defined that
>resource to be a BitMap, he knows what it is.

OK, here we go again.  There's all this really neat talk about another tool
that could be of use to every Amiga programmer.  The question is this time,
will it be a library?  So far, I've seen two libraries come down the pike.
The first one I saw [not counting x.device files, which are sort of a lib-
rary] was the ARP library.  "Great!", I thought.  Here were all these nifty
tools for programmers supplied in a library!  That wonderful run-time shared
library that is largely LANGUAGE INDEPENDANT.  Now, for all you guys out there
with 2 megs of memory and a hard drive who program in C may not particularly
notice the gap here.  With a C compiler, you can just link and compile all
these programmer goodies that come across in C.  The rest of us limp along
with what we've got [relatively speaking; some find it easier to translate
the goodies into their language, or hook up the c object code to their
sytem].

I would just to request that if something like what Matt has suggested shows
up, I'd like to see it packaged as a library.  I'm not asking you to make
lots of different translations of your code in language x, that I happen to
use.  I can translate it if I need it bad enough.  [Language X has a superb
ability to mimic the structure of C code]  A library is much more useful.
Moreover, its useful right away!

>	Huge in fact... think of all the neat things you could put in
>there!  So far, a particular resource 'file' is broken up into three
>parts:
>	(1) structure defs
>	(2) dictionary of resource names
>	(3) Data pertaining to the resources
>
>	A structure is made of other structures.

It sounds to me like (3) is made up of some tree-like structure reflecting the
nested data bits inside one another.  Couldn't the mechanism for overlay trees
be used to reflect this?  Then you could use the existing DOS hooks to get your
data in.

>	For structures containing pointers to sub-structures, the DATA
>part of the resource would be not only for the master structure, but
>also for any sub-strutures (or sub-sub-structures, etc...)
>
>					-Matt

Perhaps you'd put the overlay segment name in here?


							-- Rich
-- 
USnail: Richard Thomson, Design Engineer, Oasis Technologies, 3190 MEB,
        University of Utah, Salt Lake City, Utah  84112
ARPA: thomson@cs.utah.edu	FONE: (801) 584-4555:      Talk to a machine;
UUCP: {bellcore, ihnp4, ut-sally}!utah-cs!redpine!thomson     they're lonely.

peter@sugar.UUCP (Peter da Silva) (05/11/88)

In article ... dillon@CORY.BERKELEY.EDU (Matt Dillon) writes:
>	The question
> is, should I *force* the application program to also specify a structure
> name along with the resource name?

I think so. It's an important security check. If it's going to be used like
IFF, it's going to be used with alien files. You need to be able to specify
what sort of thing you need, as well as its name.
-- 
-- Peter da Silva      `-_-'      ...!hoptoad!academ!uhnix1!sugar!peter
-- "Have you hugged your U wolf today?" ...!bellcore!tness1!sugar!peter
-- Disclaimer: These aren't mere opinions, these are *values*.

dillon@CORY.BERKELEY.EDU (Matt Dillon) (05/11/88)

:OK, here we go again.  There's all this really neat talk about another tool
:that could be of use to every Amiga programmer.  The question is this time,
:will it be a library?  So far, I've seen two libraries come down the pike.

	Definately.... my resource project will be a run-time library.

:>parts:
:>	(1) structure defs
:>	(2) dictionary of resource names
:>	(3) Data pertaining to the resources
:>
:>	A structure is made of other structures.
:
:It sounds to me like (3) is made up of some tree-like structure reflecting the
:nested data bits inside one another.  Couldn't the mechanism for overlay trees
:be used to reflect this?  Then you could use the existing DOS hooks to get your
:data in.

	Not possible.  A 'standard' resource file might have, say, 50
resources in it.  EACH resource might contain many sub structures.  For
instance, one has 50 small bitmaps and each bitmap will be made up of a BitMap
structure (the root) and plane data (children).  What a forest!

	The space overhead for having DOS resolve all of that would be
incredible.  Also, the overlay mechanism is meant for CODE ONLY, not data.
And, to top it all off, most overlay handlers cannot handle more than
a restricted number of overlay nodes (20 is usually the number).

					-Matt

papa@pollux.usc.edu (Marco Papa) (11/05/88)

This is from a fellow with bad news feed.

-----------------

Date: Thu, 3 Nov 88 09:20:25 EST
From: Joe A. Porkka <jap@syssun.cl.msu.edu>
Subject: HELP!

My news feed writer is broken.
Would you post the following to comp.sys.amiga.tech for me please?

Subject: Resources

If you want to claim the serial port (or parallel or some such) without
the supplied driver, you are supposed to use resources.lib to
get it exclusively. The RKM's are short of being crystal clear on how this
works. Anybody care to clarify how to claim the serial port for example?

jap@syssun.cl.msu.edu (Joe A. Porkka, MSU Network Services)

-----------------

-- Marco Papa 'Doc'
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
uucp:...!pollux!papa       BIX:papa       ARPAnet:pollux!papa@oberon.usc.edu
 "There's Alpha, Beta, Gamma and Diga!" -- Leo Schwab [quoting Rick Unland]
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

lphillips@lpami.van-bc.UUCP (Larry Phillips) (11/08/88)

 > This is from a fellow with bad news feed.

So true.

 > If you want to claim the serial port (or parallel or some such) without
 > the supplied driver, you are supposed to use resources.lib to
 > get it exclusively. The RKM's are short of being crystal clear on how this
 > works. Anybody care to clarify how to claim the serial port for example?

Well, if you _must_ claim the serial port in non-shared mode, I suppose
you would use GetMiscResource() and FreeMiscResource, though I don't
know the details. If you do succeed, please post a warning about your
program hogging the serial port.

-larry

--
"Intelligent CPU?  I thought you said Intel CPU!" 
        -Anonymous IBM designer-
+----------------------------------------------------------------+ 
|   //   Larry Phillips                                          |
| \X/    lpami.wimsey.bc.ca!lphillips or van-bc!lpami!lphillips  |
|        COMPUSERVE: 76703,4322                                  |
+----------------------------------------------------------------+

dan@cbmvax.UUCP (Dan Baker CATS) (11/12/88)

In article <13249@oberon.USC.EDU> papa@pollux.usc.edu (Marco Papa) writes:
>
>This is from a fellow with bad news feed...<text ommitted for brevity>
>
>If you want to claim the serial port (or parallel or some such) without
>the supplied driver, you are supposed to use resources.lib to
>get it exclusively. The RKM's are short of being crystal clear on how this
>works. Anybody care to clarify how to claim the serial port for example?
>

This question is covered in more detail in an upcoming article
in Amiga Mail.  Until then, here is a quick summary of the topic.

In order to get direct access to the parallel/serial hardware in a way that 
is compatible with multi-tasking, you should use the GetMiscResource() and
FreeMiscResource() routines.  These two routines let you temporarily bar
other tasks from using the resource.  You may then use the associated
hardware directly for your special purposes and then return the resource
back to the system for other tasks to use. (!!!)

GetMiscResource() and FreeMiscResource() are descirbed in Appendix C of the
ROM Kernel Manual: Libraries and Devices.  Since these two routines do not
have a library base pointer name, they can only be called from an assembly
language program.  Here's a working example that gets one of the two 
miscellaneous resources.  Code courtesy of Bryce Nesbitt.

   *
   * Assembly language fragment that grabs the serial port registers
   * (using the misc.resource), and never gives them back.  Of course
   * a real program would ALWAYS return a resource that it has taken over
   * after it was all done using it.  This program never ends.  It waits
   * forever.  This is also a bad thing to do in your programs.

   JSRLIB     MACRO
   XREF       _LVO\1
              JSR_LVO\1(A6)
   ENDM

   XREF       _AbsExecBase
   INCLUDE    "resources/misc.i"

              move.l  _AbsExecBase,a6
              lea.l   MiscName(pc),a1
              JSRLIB  OpenResource
              tst.l   d0
              beq.s   no_open
              move.l  d0,a6               ;resource base in A6

   ;
   ; The resource is now open.  Call one of it's library-like vectors.
   ;
              move.l  #MR_SERIALBITS,d0
              lea.l   MyName(pc),a1
              jsr     MR_ALLOCMISCRESOURCE(a6)
              tst.l   d0
              bne.s   no_get              ;Someone else got it

   ;
   ; We just stole the serial port registers.  Wait forever.
   ; Nobody else can use the serial port, including the serial.device!
   ;
              move.l  _AbsExecBase,a6
              moveq   #0,d0              ;Wait for nothing (forever)
              JSRLIB  Wait
   ;
   ;  INSTEAD OF WAITING FOREVER, YOU COULD PUT YOUR OWN
   ;  CODE HERE.  AFTER YOU ARE ALL DONE, RETURN THE 
   ;  RESOURCE WITH FREE_MISC_RESOURCE() !!  THANK YOU.
   ;
   no_get
   no_open    moveq   #21,d0
              rts

   MiscName   dc.b    'misc.resource',0
   MyName     dc.b    'Serial Port hog',0
              END


Note that there are two serial.device resources to take over, MR_SERIALBITS
and MR_SERIALPORT.  You should get both resources when you take over the
serial port to prevent other tasks from using them.  The parallel.device
also has two resources to take over.  See the resources/misc.h include file
for the relevant C definitions and structures. 

Under V1.3 and earlier versions of the Amiga system software, there is a bug
in the way the the serial and parallel port resources are handled.  That is,
the GetMiscResource() routine will always fail if the serial.device has
been used at all by another task - even if that task is done using the
resource.  In other words, once a printer driver has been activated, it will
keep the associated resource locked up preventing your task from using it.

One way around this is to cause a 'memory panic' with the Exec call
AllocMem(0x7FFFFFFFL,0L).  This will cause libraries and resources not
currently in use to be flushed.  However this method has some drawbacks.  It
is unfriendly to other tasks that may be running in the system.  If the user
goes back to a library-based task after a general memory expunge, the user
might be required to reload large libraries from floppy disk.  What is
needed is a less drastic way to get a resource back from a device driver
which has a hold on it.  The code shown below will do this:
 
  /*
   * A safe way to expunge ONLY a certain device.  The serial.device holds
   * on to the misc serial resource until a general expunge occurs.
   * This code attempts to flush ONLY the named device out of memory and
   * nothing else.  If it fails, no status is returned since it would have
   * no valid use after the Permit().  Code by Bryce Nesbitt.
   */
   #include "exec/types.h"
   #include "exec/execbase.h"

   void FlushDevice(char *);

   extern struct ExecBase *SysBase;
 
   void FlushDevice(name)
   char  *name;
   {
   struct Device *devpoint;

       Forbid();
       if( devpoint=(struct Device *)FindName(&SysBase->DeviceList,name) )
       RemDevice(devpoint);
       Permit();
   }


Hope this helps.


-- 
 Dan Baker, CATS

ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) (11/12/88)

In article <1947@van-bc.UUCP> lphillips@lpami.van-bc.UUCP (Larry Phillips) writes:
>Well, if you _must_ claim the serial port in non-shared mode, I suppose
>you would use GetMiscResource() and FreeMiscResource, though I don't
>know the details.  [ ... ]

	Okay, I'm gonna ask this question again.  I'm not deaf; I have heard
the answer before.

	How do you CloseResource() something that you've OpenResource()d?

	The answer has been, "You don't," but this answer has some
interesting implications.

	Suppose I want the use of one of the CIA ports.  I would call
OpenResource() on the relevant port, and dance on it.  While I'm dancing on
it, it'd be real nice if I could be sure that no one else will be dancing on
it.  One would think that the OpenResource()/CloseResource() pair (if it
existed) would arbitrate access to the relevant resource.

	However, since there is no CloseResource(), this implies that, when
I OpenResource() something, someone else can OpenResource() the same thing,
and we can fight in most entertaining ways, sure to cause crashing of
programs and pulling of hairs.

	So.  Given the lack of CloseResource(), does this mean that
OpenResource() does not guarantee exclusive access?  If this is so, how does
one arbitrate the access to "resources" to prevent collisions?

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Leo L. Schwab -- The Guy in The Cape	INET: well!ewhac@ucbvax.Berkeley.EDU
 \_ -_		Recumbent Bikes:	UUCP: pacbell > !{well,unicom}!ewhac
O----^o	      The Only Way To Fly.	      hplabs / (pronounced "AE-wack")
"Work FOR?  I don't work FOR anybody!  I'm just having fun."  -- The Doctor

peter@sugar.uu.net (Peter da Silva) (11/13/88)

Could you publish '.fd' files for the resource library so we could use bind
to create the high-level calls for it?
-- 
		    Peter da Silva  `-_-'  peter@sugar.uu.net
		     Have you hugged  U  your wolf today?

	      Disclaimer: My typos are my own damn business.

mlelstv@faui44.informatik.uni-erlangen.de (Michael van Elst ) (11/15/88)

In article <7636@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
>	Suppose I want the use of one of the CIA ports.  I would call
>OpenResource() on the relevant port, and dance on it.  While I'm dancing on
>it, it'd be real nice if I could be sure that no one else will be dancing on
>it.  One would think that the OpenResource()/CloseResource() pair (if it
>existed) would arbitrate access to the relevant resource.
>
>...
>	So.  Given the lack of CloseResource(), does this mean that
>OpenResource() does not guarantee exclusive access?  If this is so, how does
>one arbitrate the access to "resources" to prevent collisions?
>

The answer is simple.
OpenResource just gives you access to the resource library. It
doesn't allocate or arbitrate anything.
Thus you don't have to CloseResource it.

To allocate the ports you have to open misc.resource and
call GetMiscResource and FreeMiscResource to arbitrate access to
the port bits.

I wrote a small program that uses the parallel port to drive
a GAL programmer. If someone is interested, I may mail the source

				Michael van Elst

E-mail: UUCP: ...uunet!unido!fauern!faui44!mlelstv

dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) (11/16/88)

ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) Writes:
:	How do you CloseResource() something that you've OpenResource()d?
:
:	The answer has been, "You don't," but this answer has some
:interesting implications.
:
:	Suppose I want the use of one of the CIA ports.  I would call
:OpenResource() on the relevant port, and dance on it.  While I'm dancing on
:it, it'd be real nice if I could be sure that no one else will be dancing on
:it.  One would think that the OpenResource()/CloseResource() pair (if it
:existed) would arbitrate access to the relevant resource.
:
:	However, since there is no CloseResource(), this implies that, when

	No No.  OpenResource() does *not* allocate anything, it simply
returns a pointer to the resource structure which is already in RAM.
The idea is to then use vectors in that resource (like a library) to do the 
actual allocation and deallocation of various items the resource controls.

	A given resource name accessed by OpenResource() is likely to
arbitrate several resources.  For example, arbitration of the 4 floppy
drives is done by a single resource.  Arbitration of the serial port,
parallel port, and other associated bits is all done with call vectors
in the misc.resource .  The two cia resources (ciaa, ciab) each arbitrate
all the various interrupt sources and control functions individually.
Not only does OpenResource() NOT guarentee exclusive access, it also makes
little sense for it to do so.

						-Matt