Janus 2.1 Programming

This is a brief description of the janus code V2.1. This code supports low level access to the 'janus" system — the link between a PC and an Amiga.

THE PUBLIC ROUTINES
AddServiceAllocJanusMemAllocJRememberAllocServiceMem
AttachJRemember CallServiceDeleteServiceFreeJanusMem
FreeJRememberFreeServiceMemGetJanusStartGetService
JanusInitLockJanusLockJanusLockAttemptJanusMemBase
JanusMemToOffsetJanusMemTypeJanusOffsetToMemJanusUnLock
JBCopyLockServiceDataMakeBytePtrMakeWordPtr
ReleaseServiceTranslateJanusPtrUnlockServiceData

Descriptions

  • The code is packaged as a library (specifically "janus.library"), which is loaded during Autoconfig procedure.
  • All routines that return a value return it in D0. There is a link library for C routines,'jlib.lib".

AddService -- Adds a Janus Service to the system

SYNOPSIS

resultcode = AddService (ServiceData, , AppID , LocalID , MemSize, MemType, SignalNum, Flags)
D0:0-15 A0 D0 D1:0-15 D2:0-15 D3:0-15 D4:0-15 D5:0-15
  • SHORT AddService(struct ServiceData **,ULONG,USHORT,USHORT,USHORT,SHORT,USHORT);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
This routine adds a Janus service to the system. Please refer to the Janus Services reference documentation for a description of services and adding a service to the system.
The ServiceData argument you supply must be an address of a pointer to a ServiceData structure. If the service is successfully added, when this call returns your pointer will point to the ServiceData structure of your newly-added service. If the call fails your pointer will be equal to NULL. The address, if non-NULL, will be an address in Janus memory's word-access address space.
Your ServiceData is set equal to NULL if AddService() fails. This provides you with a convenient way to test whether or not you have to call DeleteService() during your clean-up routine.
For example:

struct ServiceData *SData = NULL;
result = AddService(&SData, ...);
myExit();
{
  if (SData) DeleteService(SData);
  exit(0);
}

The Application ID, and LocalID that you provide are used by other programs to rendevous with your service. The Application ID that you use should be gotten from Commodore-Amiga, Inc. Do not use an Application ID of your own making, for you risk a collision with someone else's use of the same ID number. The LocalID is defined by you to mean anything you want it to mean. Anyone who wants to rendevous with your service needs to know both your Application ID and your Local ID.

SignalNumber is the number of the signal bit that you will use to Wait() for CallService() signals. Typically you will get your SignalNumber from the Exec function AllocSignal().

The Flags argument lets you specify details about the type of service you want to add. Please refer to the Janus Services reference documentation and the services.[hi] include file for information regarding the arguments that may be provided to the AddService() call via the Flags argument.

This routine returns a code which is either JSERV_OK or some error-return code. The codes that this routine may return are defined in services.[hi].

If you call AddService() successfully, you are obliged to call DeleteService() sooner or later.

INPUTS

ServiceData= address of a pointer to a ServiceData structure. After this call, the pointer will be set to either the word-access address of the newly-added service's ServiceData structure, or NULL if the call to this routine failed
AppID= a 32-bit Application ID number for the service you want to add. This number is assigned to you by Commodore-Amiga, Inc.
REMINDER: do not use a number of your own making, as other software may then invalidly rendevous with your service.
LocalID= a 16-bit Local ID number of your own choosing
MemSize= the size of the memory block to be allocated for this service, if any. Set this arg to zero if you want no memory allocated for this service
MemType= the type of memory to be allocated for this service, if any. If the MemSize arg above is zero, this argument is ignored
SignalNumber= the number of the signal bit that you will Wait() on when waiting to receive CallService() signals. The SignalNumber is usually gotten from a call to Exec's AllocSignal() Flags = flags describing any special treatment you want during the processing of your AddService() call. See services.[hi] and the Janus Services reference document for details and definitions

RESULT

resultcode= a code describing the result of your call to AddService().
  This will be JSERV_OK if all went well, or some error-return code if the call failed for any reason. The codes that this routine may return are defined in services.[hi].

SEE ALSO CallService(), DeleteService(), GetService(), ReleaseService()


AllocJanusMem -- Allocate memory from the special Janus RAM

SYNOPSIS

MemPtr= AllocJanusMem (Size, Type);
D0   D0 D1
  • APTR AllocJanusMem(ULONG,ULONG);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Allocates memory of the specified size and type from the special Janus RAM. The type argument is used to describe the memory area from which you want the allocation made (e.g. buffer, parameter, or others as they come available) and into which address space you want the pointer to point (e.g. byte-access, word-access, others). Please refer to the Janus/memory.h include file for a description of Janus memory type and address flags.

If memory of the desired size and type is not available, this routine returns NULL.

INPUTS

Size= size of memory (in bytes) that you wish to allocate
Type= type of Janus memory that you wish to allocate, the type specifier describes both the area of memory and the address space of the resultant pointer. (see janus/memory,h)

RESULT

MemPtr= pointer to your newly allocated memory, or NULL if the allocation failed.

EXAMPLE
UBYTE *ByteParameterPtr;
USHORT *WordParameterPtr;
UBYTE *ByteBufferPtr;
USHORT *WordBufferPtr;
ByteParameterPtr = (UBYTE *)AllocJanusMem(100, MEMF_PARAMETER | MEM_BYTEACCESS);
WordParameterPtr = (UBYTE *)AllocJanusMem(100, MEMF_PARAMETER | MEM_WORDACCESS);
ByteBufferPtr = (UBYTE *)AllocJanusMem(100, MEMF_BUFFER | MEM_BYTEACCESS);
WordBufferPtr = (UBYTE *)AllocJanusMem(100, MEMF_BUFFER | MEM_WORDACCESS);

SEE ALSO FreeJanusMem()


AllocJRemember -- Allocate Janus memory and link into a Remember list

SYNOPSIS

MemPtr = AllocJRemember (JRememberKey, Size, Type)
D0   A0 D0:0-15 D1:0-15
  • APTR AllocJRemember(RPTR *,USHORT,USHORT);
  • From assembly, expects JanusBase in A6

FUNCTION
This routine gets memory for you by calling the Janus library's AllocJanusMem() routine, but also adds the details of the allocation into a master list so that you make just one call the FreeJRemember() routine at a later time to free all the memory you allocated. You don't have to remember the details of all of your allocations. This allows you to allocate memory dynamically, as needed, without requiring you to undergo the bookkeeping required to free at a later time every last byte that you allocated. This also allows you to fail part way through a series of allocations and almost effortlessly free up any memory you had already allocated.

You create the "anchor" for the allocation master list by declaring an RPTR in Janus memory initializing that pointer to NULL. This pointer is called the JRememberKey, and is used by calls to AllocJRemember() and FreeJRemember(). The address of your pointer is passed to both AllocJRemember() and FreeJRemember().

The Size and Type arguments are the same as those passed to the AllocJanusMem() function. Please refer to the AllocJanusMem() documentation for a description of these arguments.

If the call succeeds, you are returned a pointer to the Janus memory that you desire. If the call fails, a NULL is returned.

If you have JRememberKeys from two separate calls to AllocJRemember(), you can merge one key into the other using the AttachJRemember() routine.

This routine performs the analogy of the Intuition AllocRemember() call, except that it works with the special Janus memory. For a complete explanation of the need for and use of Remember-style memory allocation and deallocation, see the Intuition reference manual. For a quick overview of Intuition memory, see illustration 11.1 of the Intuition manual.

INPUTS

JRememberKey= Pointer to an RPTR that is to be used as the JRememberKey. Before your very first call to AllocJRemember(), the RPTR should be set to NULL. After that, the Janus library will manage the contents of the pointer for you. The RPTR MUST reside in Janus memory!
Size= the size in bytes of the memory allocation.
Type= the type of the desired memory. Please refer to the AllocJanusMem() documentation for details about this field

RESULT

MemPtr= a pointer to the Janus memory you've requested, or NULL if no memory was available.

EXAMPLE
RPTR JRememberKey;
JRememberKey = NULL;
if (ptr = AllocJRemember(&JRememberKey, BUFSIZE, MEMF_BUFFER))
{
/* Use the ptr memory */
}
FreeJRemember(&JRememberKey, TRUE);

SEE ALSO intuition.library/AllocRemember(), AttachJRemember(), FreeJRemember()


AllocServiceMem -- Allocate Janus memory linked to a ServiceData structure

SYNOPSIS

MemPtr= AllocServiceMem (ServiceData , Size , Type)
D0   A0 D0:0-15 D1:0-15
  • APTR AllocServiceMem(struct ServiceData *,USHORT,USHORT);
  • From assembly, expects JanusBase in A6

FUNCTION
This routine allocates memory for you and records the details of the allocation in the specified ServiceData structure. This memory, unless you free it explicitly with a call to FreeServiceMem(), will be automatically freed when the service is deleted and removed from the system.

This routine calls the Janus library's AllocJRemember() call for you, using the ServiceData's JRememberKey field to record the parameters of the allocation for you. You may then free the memory using the FreeServiceMem() routine. Alternatively, you may pay no further attention to this memory allocation because after the service is deleted and all users have released it, any memory allocated using the ServiceData's JRememberKey will be freed using the FreeJRemember() function.

You are allowed to call this routine whether you have acquired the ServiceData address from AddService() or GetService().

The ServiceData structure pointer that you provide to this routine doesn't have to point to any particular Janus memory-access address space (although it must point to Janus memory of course). What this means is that if you translate the ServiceData pointer you get from AddService() or GetService() from word-access to byte-access or anything else, you don't have to translate it back before calling AllocServiceMem().

The Size and Type arguments are the same as those passed to the AllocJanusMem() function. Please refer to the AllocJanusMem() documentation for a description of these arguments.

If the call succeeds, you are returned a pointer to the Janus memory that you desire. If the call fails, a NULL is returned.

INPUTS

ServiceData= address of a ServiceData structure. This may point to any type of Janus memory-access address, not necessarily word-access
Size= the size in bytes of the memory allocation.
Type= the type of the desired memory. Please refer to the AllocJanusMem() documentation for details about this field

RESULT

MemPtr= a pointer to the Janus memory you've requested, or NULL if no memory was available.

EXAMPLE
struct ServiceData *SData;
if (GetService(&SData, ...) == JSERV_OK))
{
  ptr1 = AllocServiceMem(SData, 100, MEMF_BUFFER | MEM_BYTEACCESS);
  ptr2 = AllocServiceMem(SData, 100, MEMF_BUFFER | MEM_BYTEACCESS);
  ReleaseService(SData);
}

SEE ALSO FreeServiceMem()


AttachJRemember -- Attach the list of one Janus memory key to another

SYNOPSIS

VOID AttachJRemember (ToKey , FromKey);
  A0 A1
  • VOID AttachJRemember(RPTR *,RPTR *);
  • From assembly, expects JanusBase in A6

FUNCTION
This routine accepts two Janus RememberKeys created by calls to AllocJRemember() and attaches the contents of the FromKey to the ToKey. In the process, FromKey is set equal to NULL. The result is that ToKey is comprised of a list of all the memory allocations, while FromKey points, correctly, to no list.

If either key points to NULL, as the result, for instance, of a failed call to AllocJRemember(), no problem. This routine detects those cases and handles them appropriately.

A common use for this type of routine:

  • make a series of local memory allocations using AllocJRemember()
  • if any allocations fail, abandon ship by calling FreeJRemember() to free up the local list
  • if all allocations succeed use AttachJRemember() to add the list to a global list of allocations, which is freed in the end using FreeJRemember() when your program is terminating

INPUTS

ToKey= Pointer to an RPTR that is the JRememberKey that is going to receive the list pointed to by FromKey The RPTR MUST be in Janus memory!
FromKey= Pointer to an RPTR that is the JRememberKey that has the list that's going to be attached ToKey, after which the FromKey variable will be set to NULL The RPTR MUST be in Janus memory!

RESULT
None

EXAMPLE
RPTR GlobalJKey = NULL;

exampleAllocJ(&GlobalJKey);
exampleAllocJ(&GlobalJKey);
exampleAllocJ(&GlobalJKey);
FreeJRemember(&GlobalJKey, TRUE);

exampleAllocJ(globalkey)
RPTR *globalkey;
{
   BOOL success;
   RPTR localkey;

   success = FALSE;
   localkey = NULL;

   if(AllocJRemember(&localkey,10000,MEMF_BUFFER | MEM_WORDACCESS))
   if(AllocJRemember(&localkey,100 ,MEMF_BUFFER | MEM_WORDACCESS))
   if(AllocJRemember(&localkey,1 ,MEMF_BUFFER | MEM_WORDACCESS))
     success = TRUE;

   if (success) AttachJRemember(globalkey, &localkey);
     else FreeJRemember(&localkey, TRUE);
}

SEE ALSO intuition.library/AllocRemember(),AllocJRemember(),FreeJRemember()


CallService -- Signal all other users of the Janus Service

SYNOPSIS

VOID CallService (ServiceData)
  A0
  • VOID CallService(struct ServiceData *);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
This routine sends a signal to the users of the service associated with the specified ServiceData structure. Note that the task that calls CallService() will not be signalled as a result of the call.

The ServiceData structure pointer that you provide to this routine doesn't have to point to any particular Janus memory-access address space (although it must point to Janus memory of course). What this means is that if you translate the ServiceData pointer you get from AddService() or GetService() from word-access to byte-access or anything else, you don't have to translate it back before calling CallService().

INPUTS

ServiceData= address of a ServiceData structure.
  This may point to any type of Janus memory-access address, not necessarily word-access

RESULT
None

EXAMPLE
struct ServiceData *SData = NULL;
if (GetService(&SData, ...) == JSERV_OK)
{
   /* Note that turning SData into a byte pointer doesn't hurt */
   SData = (struct ServiceData *)MakeBytePtr(SData);
   CallService(SData);
   ReleaseService(SData);
}

SEE ALSOAddService(), DeleteService(), GetService(), ReleaseService()


DeleteService -- Delete a Janus Service

SYNOPSIS

VOID DeleteService (ServiceData)
  A0
  • VOID DeleteService(struct ServiceData *);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
After you are through with a service that you have added to the system, you initiate the process of removing the service from the system by calling DeleteService(). The service will then be marked as SERVICE_DELETED and all users of the service will be signalled, at which time they are supposed to notice that the service has been deleted and call ReleaseService().

After calling this routine, subsequent attempts to GetService() will find the service not present, and a subsequent call to AddService() with the same Application ID and Local ID will succeed, even though this particular instance of the service may not have been completely removed from the system yet (the service isn't completely removed until all users of the service have made the ReleaseService() call).

If you call AddService() successfully, you are obliged to call DeleteService() sooner or later.

The ServiceData structure pointer that you provide to this routine doesn't have to point to any particular Janus memory-access address space (although it must point to Janus memory of course). What this means is that if you translate the ServiceData pointer you get from AddService() into a byte-access pointer or anything else, you don't have to translate it back before calling ReleaseService().

INPUTS

ServiceData= address of a ServiceData structure.
  This may be any type of Janus memory-access address, not necessarily word-access

RESULT
None

EXAMPLE
struct ServiceData *SData = NULL;
if (AddService(&SData, ...) == JSERV_OK)
{
   /* Note that turning SData into a byte pointer doesn't hurt */
   SData = (struct ServiceData *)MakeBytePtr(SData);
   DeleteService(SData);
}

SEE ALSOAddService(), CallService(), GetService(), ReleaseService()


FreeJanusMem -- Free Janus memory allocated with AllocJanusMem()

SYNOPSIS

FreeJanusMem (Ptr, Size);
  A1 D0
  • VOID FreeJanusMem(APTR,ULONG);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Free a block of Janus memory that was allocated with a call to AllocJanusMem().

INPUTS

Ptr= address of the Janus memory to be freed. Note that this pointer can point to any type or address space of Janus memory
Size= the size of the block of memory to be freed

RESULT
None

SEE ALSOAllocJanusMem()


FreeJRemember -- Free memory allocated by calls to AllocJRemember()

SYNOPSIS

VOID FreeJRemember (JRememberKey, ReallyForget)
  A0 D0:0-15
  • VOID FreeJRemember(RPTR *,BOOL);
  • From assembly, expects JanusBase in A6

FUNCTION
This function frees up Janus memory allocated by the AllocJRemember() function. It will either free up just the JanusRemember structures, which supply the link nodes that tie your allocations together, or it will deallocate both the link nodes AND your memory buffers too.

If you want to deallocate just the JanusRemember structure link nodes, you should set the ReallyForget argument to FALSE. However, if you want FreeJRemember() to really forget about all the memory, including both the JanusRemember structure link nodes and the buffers allocated with earlier calls to AllocJRemember(), then you should set the ReallyForget argument to TRUE.

Note that this routine sets your JRememberKey variable to NULL.

INPUTS

JRememberKey= Pointer to an RPTR that is to be used as the JRememberKey. Before your very first call to AllocJRemember(), the RPTR should be set to NULL. After that, the Janus library will manage the contents of the pointer for you.
The RPTR MUST reside in Janus memory!
ReallyForget= a BOOL FALSE or TRUE describing, respectively, whether you want to free up only the Remember nodes or if you want this procedure to really forget about all of the memory, including both the nodes and the memory buffers pointed to by the nodes.

RESULT
None

EXAMPLE
RPTR JRememberKey;
JRememberKey = NULL;
while (AllocJRemember(&JRememberKey, BUFSIZE, MEMF_BUFFER)) ;
   FreeJRemember(&JRememberKey, TRUE);

SEE ALSOAllocJRemember(), intuition.library/FreeRemember(), AttachJRemember()


FreeServiceMem -- Free mem added to a ServiceData by AllocServiceMem()

SYNOPSIS

VOID FreeServiceMem (ServiceData, MemPtr)
  A0 A1
  • VOID FreeServiceMem(struct ServiceData *,APTR);
  • From assembly, expects JanusBase in A6

FUNCTION
This routine frees memory that had been allocated with a call to AllocServiceMem(). You can choose to free a single block of memory or all the memory of the ServiceData structure.

The ServiceData structure pointer that you provide to this routine doesn't have to point to any particular Janus memory-access address space (although it must point to Janus memory of course). What this means is that if you translate the ServiceData pointer you get from AddService() or GetService() from word-access to byte-access or anything else, you don't have to translate it back before calling FreeServiceMem().

Note that the address of the ServiceData structure that you supply to this routine must be the same address that you passed to the associated AllocServiceMem() call, if any.

The MemPtr argument may be one of two things:

  • the pointer to memory returned by a call to AllocServiceMem() (using the same ServiceData structure as the one provided to this call), or
  • NULL to designate that you want all (if any) of the ServiceData's allocated memory to be freed (note that this does not include freeing the memory allocated at time of AddService()

Note that only memory allocated by AllocServiceMem can be freed. The memory allocated for the service during AddService() cannot be deleted using FreeServiceMem(), not even if you call FreeServiceMem() with a MemPtr argument of NULL.

You are allowed to call this routine whether you have acquired the ServiceData address from AddService() or GetService().

INPUTS

ServiceData= address of a ServiceData structure. This may point to any type of Janus memory-access address, not necessarily word-access
MemPtr= a pointer to the Janus memory returned by a call to AllocJanusMem(), or NULL if you want to delete all of the ServiceData's memory

RESULT
None

EXAMPLE
struct ServiceData *SData;
if (GetService(&SData, ...) == JSERV_OK))
{
   /* Allocate a bunch of memory */
   AllocServiceMem(SData, 100, MEMF_BUFFER | MEM_BYTEACCESS);
   AllocServiceMem(SData, 100, MEMF_BUFFER | MEM_BYTEACCESS);
   ptr1 = AllocServiceMem(SData, 100, MEMF_BUFFER | MEM_BYTEACCESS);

   /* Free the last one allocated */
   FreeServiceMem(SData, ptr1);

   /* Free all the rest */
   FreeServiceMem(SData, NULL);

   ReleaseService(SData);
}

SEE ALSOAllocServiceMem()


GetJanusStart -- Get the address of the base of the Janus board

SYNOPSIS

MemPtr= GetJanusStart();
  D0
  • APTR GetJanusStart(VOID);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Returns the address of the base of the Janus board.

INPUTS
None

RESULT
MemPtr = address of the base of the Janus board


GetService -- Gets a Janus Service

SYNOPSIS

resultcode= GetService (ServiceData, AppID, LocalID, SignalNumber, Flags)
D0:0-15   A0 D0 D1:0-15 D2:0-15 D3:0-15
  • SHORT GetService(struct ServiceData *,ULONG,USHORT,SHORT,USHORT);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
This routine gets a Janus service from the system. Please refer to the Janus Services reference documentation for a complete description of services and getting a service from the system.

The ServiceData argument you supply must be an address of a pointer to a ServiceData structure. If the service is successfully acquired, when this call returns your pointer will point to the ServiceData structure of your newly-acquired service. If the call fails your pointer will be equal to NULL. The address, if non-NULL, will be an address in Janus memory's word-access address space.

Your ServiceData is set equal to NULL if GetService() fails. This provides you with a convenient way to test whether or not you have to call ReleaseService() during your clean-up routine.

For example:
struct ServiceData *SData = NULL;
result = GetService(&SData, ...);
myExit();
myExit()
{
   if (SData) ReleaseService(SData);
     exit(0);
}

The AppID, or Application ID, and LocalID that you provide are used to rendevous with a service that is added by some other program. You must learn of the Application ID and Local ID of the service from the creator of the service before you can call GetService().

SignalNumber is the number of the signal bit that you will use to Wait() for CallService() signals. Typically you will get your SignalNumber from the Exec function AllocSignal().

The Flags argument lets you specify details about the type of service you want to get. Please refer to the Janus Services reference documentation and the services.[hi] include file for information regarding the arguments that may be provided to the GetService() call via the Flags argument.

This routine returns a code which is either JSERV_OK or some error-return code. The codes that this routine may return are defined in services.[hi].

If you call GetService() successfully, you are obliged to call ReleaseService() sooner or later.

INPUTS

ServiceData= address of a pointer to a ServiceData structure.
After this call, the pointer will be set to either the word-access address of the newly-acquired service's ServiceData structure, or NULL if the call to this routine failed
AppID= a 32-bit Application ID number for the service you want to find
LocalID= a 16-bit Local ID number of the service you want to find
SignalNumber= the number of the signal bit that you will Wait() on when waiting to receive CallService() signals.
The SignalNumber is usually gotten from a call to Exec's AllocSignal()
Flags= flags describing any special treatment you want during the processing of your GetService() call.
See services.[hi] and the Janus Services reference document for details and definitions

RESULT
resultcode = a code describing the result of your call to GetService().
This will be JSERV_OK if all went well, or some error-return code if the call failed for any reason.
The codes that this routine may return are defined in services.[hi].

SEE ALSOAddService(), CallService(), DeleteService(), ReleaseService()


JanusInitLock -- Prepare a Janus-style lock byte in Janus memory

SYNOPSIS

VOID JanusInitLock (BytePtr);
  A0
  • VOID JanusInitLock(UBYTE *);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Initialize a Janus-style lock on a byte of Janus memory to the unlocked state. Lock bytes MUST be initialized by JanusInitLock() before being used by JanusLock() or JanusUnlock().

Note that the pointer you specify as the argument to this routine must point to a byte-access address space of Janus memory.

INPUTS
BytePtr = pointer to a lock byte in byte-access address space of Janus memory

RESULT
When control returns to you, you have initialized the lock

SEE ALSOJanusLock(), JanusLockAttempt(), JanusUnlock()


JanusLock -- Get a Janus-style lock on a byte of Janus memory

SYNOPSIS

(BytePtr);

VOID JanusLock (BytePtr);
  A0
  • VOID JanusLock(UBYTE *);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Gets a Janus-style lock on a byte of Janus memory.

This lock cannot be achieved by both the Amiga and the PC simultaneously, so it's safe for the two processors to use this as a mechanism by which they can share memory. By requiring both sides to get a lock on a certain byte of memory before accessing the shared memory, each can avoid interfering with the other's usage of the memory.

Note that the pointer you specify as the argument to this routine must point to a byte-access address space of Janus memory.

The lock byte must be initialized by JanusInitLock() before the first time it's used as a lock. After being used as a lock byte, the system manages the value of the byte and you should not modify it. All lock bytes provided by the system (the one in the ServiceData structure, for instance) are initialized for you.

Note that the lock mechanism is appropriate only for Amiga/PC locks. Amiga programs that wish to lock one another out of Janus memory should use either Forbid()/Permit() or ObtainSemaphore()/ReleaseSemaphore().

This routine tries for the lock until it's gotten. You may wish to consider using JanusLockAttempt(), which tries just once to get the lock.

INPUTS
BytePtr = pointer to a lock byte in byte-access address space of Janus memory.
This byte must be initialized by JanusInitLock() before the first time it's used as a lock byte

RESULT
When control returns to you, you have achieved the desired lock

EXAMPLE
struct ServiceData *SData;

if (GetService(&SData, ...) == JSERV_OK)
{
   SData = (struct ServiceData *)MakeBytePtr(SData);
   JanusLock(&SData->ServiceDataLock);
   /* Now the ServiceData and its memory buffers are yours
   * to play with with impugnity.
   */
   JanusUnlock(&SData->ServiceDataLock);
   ReleaseService(SData);
}

SEE ALSOJanusLockAttempt(), JanusUnlock(), JanusInitLock()


JanusLockAttempt -- Try once to get a Janus-style lock on a byte

SYNOPSIS

result= JanusLockAttempt (BytePtr);
D0:0-15   A0
  • BOOL JanusLockAttempt(UBYTE *);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Tries once to gets a Janus-style lock on a byte of Janus memory.

This function performs the same function as the janusLock() function, except that JanusLock() will try until it succeeds, whereas this routine will try just once and will return a BOOL TRUE or FALSE to you depending on whether it was successful or not respectively. See the JanusLock() description for details about getting a lock on Janus memory.

Note that the pointer you specify as the argument to this routine must point to a byte-access address space of Janus memory.

INPUTS
BytePtr = pointer to a lock byte in byte-access address space of Janus memory.
This byte must be initialized by JanusInitLock() before the first time it's used as a lock byte

RESULT
result = BOOL TRUE if you got the lock, FALSE if you didn't

EXAMPLE
struct ServiceData *SData;

if (GetService(&SData, ...) == JSERV_OK)
{
   SData = (struct ServiceData *)MakeBytePtr(SData);
   if (JanusLockAttempt(&SData->ServiceDataLock))
   {
     /* Now the ServiceData and its memory buffers are yours
     * to play with with impugnity.
     */
     JanusUnlock(&SData->ServiceDataLock);
   }
   ReleaseService(SData);
}

SEE ALSOJanusLock(), JanusUnlock(), JanusInitLock()


JanusMemBase -- Return the base of the specified type of Janus memory

SYNOPSIS

MemPtr = JanusMemBase (Type);
D0   D0
  • APTR JanusMemBase(ULONG);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Accepts a Janus memory type as an argument and returns the base of Janus memory of the specified type. By "base" we mean the address of the first memory element (which has a Janus memory offset of 0x0000. The type includes the Janus memory area (e.g. buffer, parameter) and the memory-access address space (e.g. byte-access, word-access).

INPUTS
Type = the Janus memory type specifier that describes the Janus memory area of interest

RESULT
MemPtr = pointer to the first element of the Type of Janus memory

SEE ALSOJanusMemType(), JanusMemToOffset, JanusOffsetToMem(), TranslateJanusPtr()


JanusMemToOffset -- Create a Janus memory offset from a Janus pointer

SYNOPSIS

Offset = JanusMemToOffset (MemPtr)
D0:0-15   D0
  • USHORT JanusMemToOffset(APTR);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Turns a Janus memory pointer into a Janus memory offset.

Remember, garbage in gets garbage out. The MemPtr argument must point to Janus memory for the result to be valid.

INPUTS
MemPtr = the Janus memory pointer to be translated into a Janus offset

RESULT
Offset = 16-bit Janus memory offset of the MemPtr argument

SEE ALSOJanusMemType(), JanusOffsetToMem(), SetParamOffset()


JanusMemType -- Return the Janus memory type of the specified pointer

SYNOPSIS

Type = JanusMemType (MemPtr);
D0   D0
  • ULONG JanusMemType(APTR);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Accepts a Janus memory pointer as an argument and returns the Janus memory type specifier that describes the Janus memory to which the pointer points. The type includes the Janus memory area (e.g. buffer, parameter) and the memory-access address space (e.g. byte-access, word-access).

Remember, garbage in gets garbage out. The MemPtr argument must point to Janus memory for the result to be valid.

INPUTS
MemPtr = pointer to Janus memory

RESULT
Type = the Janus memory type specifier that describes the Janus memory to which the MemPtr arg refers.

SEE ALSOJanusMemBase(), JanusMemToOffset, JanusOffsetToMem(), TranslateJanusPtr()


JanusOffsetToMem -- Create a pointer from a Janus offset and type

SYNOPSIS

MemPtr = JanusOffsetToMem (Offset, Type)
D0   D0:0-15 D1:0-15
  • APTR JanusOffsetToMem(USHORT,USHORT);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Turns a Janus memory offset and a type specifier into a normal memory pointer.

INPUTS
Offset = 16-bit Janus memory offset Type = Janus memory type specifier, which includes information such as whether the pointer should point to buffer or parameter memory,whether you want word-access or byte-access address space, and others

RESULT
MemPtr = the desired 68000 memory pointer

SEE ALSOJanusMemType(), JanusMemToOffset(), GetParamOffset()


JanusUnlock -- Release a Janus-style lock on a byte of Janus memory

SYNOPSIS

VOID JanusUnlock (BytePtr);
  A0
  • VOID JanusUnlock(UBYTE *);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Release a Janus-style lock on a byte of Janus memory that has been locked via a call to JanusLock() or JanusLockAttempt().

Note that the pointer you specify as the argument to this routine must point to a byte-access address space of Janus memory.

INPUTS
BytePtr = pointer to a lock byte in byte-access address space of Janus memory

RESULT
When control returns to you, you have released the lock

EXAMPLE
struct ServiceData *SData;

if (GetService(&SData, ...) == JSERV_OK)
{
   SData = (struct ServiceData *)MakeBytePtr(SData);
   JanusLock(&SData->ServiceDataLock);
   /* Now the ServiceData and its memory buffers are yours
   * to play with with impugnity.
   */
   JanusUnlock(&SData->ServiceDataLock);
   ReleaseService(SData);
}

SEE ALSOJanusLock(), JanusLockAttempt(), JanusInitLock()


JBCopy -- Copy Janus memory as efficiently as possible

SYNOPSIS

VOID JBCopy (Source, Destination, Length);
  A0 A1 D0
  • VOID JBCopy(APTR,APTR,ULONG);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Copies an arbitrarily-aligned block of Janus memory as efficiently as possible.

INPUTS

  • Source = address of start of memory block to be copied
  • Destination = address of destination of memory block to be copied
  • Length = length of memory block to be copied

RESULT
None


LockServiceData -- Lock the ServiceData for exclusive use

SYNOPSIS

VOID LockServiceData (ServiceData)
  A0
  • VOID LockServiceData(struct ServiceData *);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Locks up a ServiceData for exclusive use. Does everything you should do before using the ServiceData fields.

Currently, this function on the Amiga side does:

  •  ObtainSemaphore(ServiceData->sd_Semaphore);
  •  JanusLock(&ServiceData->sd_ServiceDataLock);

On the PC side this function does:

  •  JanusLock(&ServiceData->sd_ServiceDataLock);

INPUTS
ServiceData = address of a ServiceData structure (doesn't matter what type of memory the pointer points to)

RESULT
None

SEE ALSOUnlockServiceData()


MakeBytePtr -- Make any Janus memory pointer into a byte-access ptr

SYNOPSIS

BytePtr = MakeBytePtr(OldPtr);
D0 A0
  • UBYTE *MakeBytePtr(APTR);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
This routine accepts a valid Janus memory pointer of any type and translates it into a Janus byte-access address space memory pointer. If you have a pointer and you don't know its type, or if you know the type isn't byte-access and what you want is byte-access, then this is the routine for you.

INPUTS
OldPtr = the Janus memory pointer that you want to translate

RESULT
BytePtr = the desired byte-access memory pointer

SEE ALSOMakeWordPtr(), TranslateJanusPtr()


MakeWordPtr -- Make any Janus memory pointer into a word-access ptr

SYNOPSIS

WordPtr = MakeWordPtr (OldPtr);
D0   A0
  • USHORT *MakeWordPtr(APTR);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
This routine accepts a valid Janus memory pointer of any type and translates it into a Janus word-access address space memory pointer. If you have a pointer and you don't know its type, or if you know the type isn't word-access and what you want is word-access, then this is the routine for you.

INPUTS
OldPtr = the Janus memory pointer that you want to translate

RESULT
WordPtr = the desired word-access memory pointer

SEE ALSOMakeBytePtr(), TranslateJanusPtr()


ReleaseService -- Release a Janus Service

SYNOPSIS

VOID ReleaseService (ServiceData)
  A0
  • VOID ReleaseService(struct ServiceData *);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
After you are through using a service or after you detect that a service's ServiceData structure has its SERVICE_DELETED flag set, you release your usage of the service by calling ReleaseService(). After all who are attached to a service have released it, the service can then be removed from the system.

If you call GetService(), you are obliged to call ReleaseService() sooner or later.

The ServiceData structure pointer that you provide to this routine doesn't have to point to any particular Janus memory-access address space (although it must point to Janus memory of course). What this means is that if you translate the ServiceData pointer you get from AddService() or GetService() from word-access to byte-access or anything else, you don't have to translate it back before calling ReleaseService().

INPUTS
ServiceData = address of a ServiceData structure. This may be any type of Janus memory-access address, not necessarily word-access

RESULT
None

EXAMPLE
struct ServiceData *SData = NULL;
if (GetService(&SData, ...) == JSERV_OK)
{
   /* Note that turning SData into a byte pointer doesn't hurt */
   SData = (struct ServiceData *)MakeBytePtr(SData);
   CallService(SData);
   ReleaseService(SData);
}

SEE ALSOAddService(), CallService(), DeleteService(), GetService()


TranslateJanusPtr -- Translate a Janus memory pointer to a new type

SYNOPSIS

MemPtr = TranslateJanusPtr (OldPtr, Type);
D0   A0 D0:0-15
  • APTR TranslateJanusPtr(APTR,USHORT);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Translates the specified Janus memory pointer to point to the memory-access address space specified by the type argument. Ignores all portions of the type argument except for the memory-access specification, which is to say that if pointer points to parameter memory, for instance, then it will still point to parameter memory when finished, except that the pointer will be adjusted for the desired memory access address space. This is one of the few Janus memory routines which doesn't require a completely well-formed type argument.

INPUTS
OldPtr = the Janus memory pointer that you want to translate Type = the specifier for the memory-access address space to which you want the pointer translated

RESULT
MemPtr = the desired memory pointer

EXAMPLE
UBYTE *byteptr;
USHORT *wordptr;
if (byteptr = (UBYTE *)AllocJanusMem(100, MEMF_BUFFER | MEM_BYTEACCESS))
{
   /* Note that neither MEMF_BUFFER nor MEMF_PARAMETER needs to be
   * supplied in the type argument in the following call.
   */
   wordptr = TranslateJanusPtr(byteptr, MEM_WORDACCESS);
}

SEE ALSOMakeBytePtr(), MakeWordPtr()


UnlockServiceData -- Unlock a ServiceData locked with LockServiceData()

SYNOPSIS

VOID UnlockServiceData (ServiceData)
  A0
  • VOID UnlockServiceData(struct ServiceData *);
  • From assembly: A6 has pointer to JanusBase

FUNCTION
Unlocks a ServiceData that had been locked by a call to LockServiceData(). Undoes everything that LockServiceData() does.

Currently, this function on the Amiga side does:

  • JanusUnlock(&ServiceData->sd_ServiceDataLock);
  • ReleaseSemaphore(ServiceData->sd_Semaphore);

On the PC side this function does:

  • JanusUnlock(&ServiceData->sd_ServiceDataLock);

INPUTS
ServiceData = address of a ServiceData structure (doesn't matter what type of memory the pointer points to)

RESULT
None

SEE ALSOLockServiceData()

Last Update: 03.07.2022