/****************************************************************************
**
**  Name:  LCODE.C
**
**  Description:
**      Loader routines which process code records.
**
**  Status:  CODED
**
**  $Log:   S:/tbird/mt2_68k/l695/lcode.c_v  $
** 
**    Rev 1.0   13 Feb 1997 08:50:44   gene
** Initial revision.
** 
**    Rev 1.0   07 Sep 1995 10:32:04   gene
** Initial revision.
** 
**    Rev 1.19   03 Aug 1993 17:27:52   nghia
** Removed LERR_xxxx to use standard error codes.
** 
**    Rev 1.18   08 Mar 1993 10:18:26   nghia
** Cleanup and added function comment block.
** 
**    Rev 1.17   21 Oct 1992 16:19:12   courtney
** Cleaned up error reporting to use string resource.
** 
**    Rev 1.16   25 Sep 1992 20:55:56   courtney
** Minor revisions.
** 
**    Rev 1.15   14 Sep 1992 10:37:26   courtney
** Removed ifdef bracketing.
** 
**    Rev 1.14   14 Sep 1992 10:33:54   courtney
** Switch to TMalloc.
** 
**    Rev 1.13   24 Jul 1992 15:33:00   doug
** get access and verify from memory server
** 
**    Rev 1.12   22 Jul 1992 16:42:16   doug
** conversion to generic shared data
** 
**    Rev 1.11   07 May 1992 15:53:30   courtney
** Cleanup.
** 
**    Rev 1.10   01 Apr 1992 15:57:12   courtney
** Cleanup.
** 
**    Rev 1.9   17 Mar 1992 13:14:00   mindy
** we never registered on SD_FILL_RESULTS but instead registered on 
** SD_FILL_COMMAND twice.
** 
**    Rev 1.8   04 Mar 1992 12:48:56   doug
** use write command read response for fill
** 
**    Rev 1.7   18 Feb 1992 17:55:32   courtney
** Revised registration on fill result SDS member to use result of
** MakeProcInstance in passing the callback parameter.
** 
**    Rev 1.6   14 Feb 1992 13:25:52   courtney
** Added callback LdrFillResult, for completion of memory write for code
** loading.
** 
**    Rev 1.5   10 Feb 1992 12:51:28   courtney
** Removed shared data headers (added to ldr.c).
** 
**    Rev 1.4   05 Feb 1992 13:21:26   courtney
** Added casts on parameters to SdRegister calls.
** 
**    Rev 1.3   30 Jan 1992 15:51:32   courtney
** Changes to reflect new shared data memory buffers, for downloading
** code.  These members are MC68030-specific.
** 
**    Rev 1.2   09 Jan 1992 16:57:14   courtney
** Checks LocalAlloc/Lock returns.
** 
**    Rev 1.1   31 Dec 1991 10:52:36   courtney
** Revised alloc's to be Local, not Global.
** 
**    Rev 1.0   12 Dec 1991 13:42:04   courtney
** Initial revision.
**
**  $Header:   S:/tbird/mt2_68k/l695/lcode.c_v   1.0   13 Feb 1997 08:50:44   gene  $
**
**  Copyright (C) 1991 Microtek International.  All rights reserved.
**
*****************************************************************************/
#ifndef __LDR__
#include "ldr.h"
#endif

#ifndef _HEAP
#include "heap.h"
#endif

#ifndef __ERR__
#include "err.h"
#endif

/* Later, grab as many code buffers as possible!! (not all will be available
** sequentially, so will have to keep index
*/
CODEBUF CodeBuffers[NUM_LOAD_BUFFERS];

/* Register code buffers with SDS, and allocate section index to UNUSED
** What are the error returns that SDS can return?
** These now use the real memory SDS names.
*/

/*
** Strategy: SDS memory buffers are allocated once, at the start of a Load
** session, and kept registered for the duration of the load.  Then freed
** when load is complete.  No one else will be able to use them.  Actually,
** ldr.c should be able to free them before symbols are loaded..
*/
/******************************************************************************
**
**  RegisterCodeBufs
**
******************************************************************************/
RETCODE RegisterCodeBufs(VOID)
{
   U16 i;
   RETCODE err;

   for (i = 0; i < NUM_LOAD_BUFFERS; i++) {
      /* register semaphore */
      if ((err = SdRegisterSemaphore(SD_FILL_SEMAPHORE, NULLPTR,
            (DESCRIPTOR FAR *)&CodeBuffers[i].sds_semaphore)) != GOOD) {
         /* clean up first, unregister, etc. */
         return (err);
      }
      /* get member index */
      if ((err = SdGetMemberIndex(CodeBuffers[i].sds_semaphore,
            (MEMBER_INDEX FAR *)&CodeBuffers[i].sds_mbr)) != GOOD) {
         /* unregister semaphore here */
         return (err);
      }

      /* register members and allocate buffer for each entry */
      if ((err = SdnRegister(SDN_FILL_ACCESS+CodeBuffers[i].sds_mbr, NULLPTR,
            (DESCRIPTOR FAR *)&CodeBuffers[i].sds_access)) != GOOD) {
         return (err);
      }
      if ((err = SdnRegister(SDN_FILL_VERIFY+CodeBuffers[i].sds_mbr, NULLPTR,
            (DESCRIPTOR FAR *)&CodeBuffers[i].sds_verify)) != GOOD) {
         return (err);
      }
      if ((err = SdnRegister(SDN_FILL_OFFSET+CodeBuffers[i].sds_mbr, NULLPTR,
            (DESCRIPTOR FAR *)&CodeBuffers[i].sds_offset)) != GOOD) {
        return (err);
      }
      if ((err = SdnRegister(SDN_FILL_SPACE+CodeBuffers[i].sds_mbr, NULLPTR,
            (DESCRIPTOR FAR *)&CodeBuffers[i].sds_space)) != GOOD) {
         return (err);
      }
      if ((err = SdnRegister(SDN_FILL_LENGTH+CodeBuffers[i].sds_mbr, NULLPTR,
            (DESCRIPTOR FAR *)&CodeBuffers[i].sds_nbytes)) != GOOD) {
         return (err);
      }
      if ((err =SdnRegister(SDN_FILL_PATLENGTH+CodeBuffers[i].sds_mbr,NULLPTR,
            (DESCRIPTOR FAR *)&CodeBuffers[i].sds_plength)) != GOOD) {
         return (err);
      }
      /* actual data bytes */
      if ((err = SdnRegister(SDN_FILL_BUFFER+CodeBuffers[i].sds_mbr, NULLPTR,
            (DESCRIPTOR FAR *)&CodeBuffers[i].sds_pbuffer)) != GOOD) {
         return (err);
      }
      /* writing this member will trigger the download */
      if ((err = SdnRegister(SDN_FILL_COMMAND+CodeBuffers[i].sds_mbr, NULLPTR,
            (DESCRIPTOR FAR *)&CodeBuffers[i].sds_command)) != GOOD) {
         return (err);
      }
      if ((err = SdnRegister(SDN_FILL_RESULTS+CodeBuffers[i].sds_mbr, NULLPTR,
            (DESCRIPTOR FAR *)&CodeBuffers[i].sds_result)) != GOOD) {
         return (err);
      }

      /* allocate buffer for each */
      if ((CodeBuffers[i].ldr_pbuf = (LPSTR)TMalloc(MAX_LBUFFSIZE)) == NULL) {
         return(ER_NO_MEMORY);
      }

      /* Initialize CodeBuffers loader-specific fields */
      CodeBuffers[i].ldr_sindex = UNUSED;
      CodeBuffers[i].ldr_written = FALSE;
      CodeBuffers[i].ldr_result = FALSE;
	}

    return (GOOD);
}  /* RegisterCodeBufs */

/******************************************************************************
**
**  UnregisterCodeBufs
**
******************************************************************************/
RETCODE UnregisterCodeBufs(VOID) {
   U16 i;
   RETCODE err;

   for (i = 0; i < NUM_LOAD_BUFFERS; i++) {
      /* free buffer */
      if (TFree(CodeBuffers[i].ldr_pbuf) != GOOD)
         return(ER_BAD_FREE);

      /* Should not return on error without first trying to
      free/unregister *all* members */
      /* unregister members */
      if ((err = SdUnRegister(CodeBuffers[i].sds_space)) != GOOD) {
         return (err);
      }
      if ((err = SdUnRegister(CodeBuffers[i].sds_offset)) != GOOD) {
         return (err);
      }
      if ((err = SdUnRegister(CodeBuffers[i].sds_nbytes)) != GOOD) {
         return (err);
      }
      if ((err = SdUnRegister(CodeBuffers[i].sds_plength)) != GOOD) {
         return (err);
      }
      if ((err = SdUnRegister(CodeBuffers[i].sds_pbuffer)) != GOOD) {
         return (err);
      }
      if ((err = SdUnRegister(CodeBuffers[i].sds_command)) != GOOD) {
         return (err);
      }
      if ((err = SdUnRegister(CodeBuffers[i].sds_result)) != GOOD) {
         return (err);
      }
      if ((err = SdUnRegister(CodeBuffers[i].sds_access)) != GOOD) {
         return (err);
      }
      if ((err = SdUnRegister(CodeBuffers[i].sds_verify)) != GOOD) {
         return (err);
      }
      /* Unregister semaphore - this is the *last* member to be freed */
      if ((err = SdUnRegisterSemaphore(CodeBuffers[i].sds_semaphore)) != GOOD) {
         return (err);
      }
	}
    return(GOOD);
}  /* UnregisterCodeBufs */

/******************************** E O F ***********************************/

