/*

File: segment.c
Author: Neil Cafferkey
Copyright (C) 1999-2001 Neil Cafferkey

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.

*/

#include "memory_protos.h"
#include "segment_protos.h"
#include "bank_protos.h"
#include "config_protos.h"
#include "string_set_protos.h"


/* Function: CreateSegment
 * =======================
 * Creates a Segment.
 */

Segment CreateSegment(ULONG original_base,ULONG size)
{
   Segment segment=Malloc(sizeof(Segment_imp));

   segment->original_base=original_base;
   segment->size=size;
   segment->bank_count=0;

   return segment;
}


/* Function: ReadSegment
 * =====================
 */

Segment ReadSegment(TEXT *file_name)
{
   Config config=ReadConfig(file_name);

   ULONG original_base=GetNumericConfigOption(config,"Base Address:");
   ULONG length=GetNumericConfigOption(config,"Length:");

   Segment segment=CreateSegment(original_base,length);

   StringSet bank_names=GetStringSetConfigOption(config,"Banks:");

   while(!IsEmptySet(bank_names))
      PutBankInSegment(segment,ReadBank(TakeFromSet(bank_names)));

   KillConfig(config);

   return segment;
}


/* Function: PutBankInSegment
 * ==========================
 */

VOID PutBankInSegment(Segment segment,Bank bank)
{
   segment->banks[segment->bank_count++]=bank;
   return;
}


/* Function: GetSegmentBank
 * ========================
 */

Bank GetSegmentBank(Segment segment,ULONG bank_no)
{
   ULONG i;
   BOOL found=FALSE;

   for(i=0;(i<segment->bank_count)&&!found;i++)
      found=(GetBankNumber(segment->banks[i])==bank_no);

   if(found)
      return segment->banks[i-1];
   else
      return NULL;
}


/* Function: OffsetIsInSegment
 * ===========================
 */

BOOL OffsetIsInSegment(Segment segment,ULONG offset)
{
   return (offset>=segment->original_base)&&
      (offset<segment->original_base+segment->size);
}


/* Function: KillSegment
 * =====================
 */

VOID KillSegment(Segment segment)
{
   ULONG i;

   for(i=0;i<segment->bank_count;i++)
      KillBank(segment->banks[i]);
   Free(segment,sizeof(Segment_imp));

   return;
}


