/*

File: bank.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 "bank_protos.h"
#include "memory_protos.h"
#include "sequence_protos.h"
#include <stdio.h>
#include "config_protos.h"
#include "address_protos.h"

#include <assert.h>


/* Function: CreateBank
 * ====================
 * Creates a Bank.
 */

Bank CreateBank(MemType mem_type,ULONG original_base,TEXT *file_name,
   UWORD bank_no)
{
   ULONG length;
   Address *addresses,*p;

   /* Allocate memory for the new bank */

   Bank bank=Malloc(sizeof(Bank_imp));

   /* Put parameters into the new bank */

   bank->mem_type=mem_type;
   bank->original_base=original_base;
   bank->data=ReadSequence(file_name);
   length=GetSequenceLength(bank->data);
   bank->data_file_name=file_name;
   bank->bank_no=bank_no;
   bank->addresses=addresses=Malloc(length*sizeof(Address));

   /* Initialise address array */

   for(p=addresses+length;p>addresses;*(--p)=NULL);

   assert(bank->addresses[10]==NULL);
   assert(bank->addresses[27]==NULL);

   return bank;
}


/* Function: ReadBank
 * ==================
 * Reads a bank into memory from a file.
 */

Bank ReadBank(TEXT *file_name)
{
   Config config=ReadConfig(file_name);

   MemType mem_type=(MemType)GetNumericConfigOption(config,"Memory Type");
   ULONG original_base=GetNumericConfigOption(config,"Base Address:");
   TEXT *data_file_name=GetStringConfigOption(config,"Data File:");
   UWORD bank_no=GetNumericConfigOption(config,"Bank Number:");

   KillConfig(config);

   return CreateBank(mem_type,original_base,data_file_name,bank_no);
}


/* Function: PutAddressInBank
 * ==========================
 */

VOID PutAddressInBank(Bank bank,Address address)
{
   bank->addresses[GetAddressOffset(address)-bank->original_base]=address;

   return;
}


/* Function: GetBankAddress
 * ========================
 */

Address GetBankAddress(Bank bank,ULONG offset)
{
   assert((offset>=0)&&(offset<66000));
   assert(bank->original_base==0x1000);
   return bank->addresses[offset-(bank->original_base)];
}


/* Function: GetBankContents
 * =========================
 */

UBYTE *GetBankContents(Bank bank,ULONG offset)
{
   return GetSequenceContents(bank->data,offset-bank->original_base);
}


/* Function: OffsetIsInBank
 * ========================
 */

BOOL OffsetIsInBank(Bank bank,ULONG offset)
{
   return (offset>=bank->original_base)&&
      (offset<bank->original_base+GetSequenceLength(bank->data));
}


/* Function: GetBankBase
 * =====================
 */

ULONG GetBankBase(Bank bank)
{
   return bank->original_base;
}


/* Function: GetBankLength
 * =======================
 */

ULONG GetBankLength(Bank bank)
{
   return GetSequenceLength(bank->data);
}


/* Function: GetBankNumber
 * =======================
 */

UWORD GetBankNumber(Bank bank)
{
   return bank->bank_no;
}


/* Function: GetBankDataFileName
 * =============================
 */

TEXT *GetBankDataFileName(Bank bank)
{
   return bank->data_file_name;
}


/* Function: KillBank
 * ==================
 */

VOID KillBank(Bank bank)
{
   KillSequence(bank->data);
   KillString(bank->data_file_name);
   Free(bank,sizeof(Bank_imp));

   return;
}


