/*****************************************************************************

  Project:	STACK-MACHINE SIMULATOR
  Filename:	DataSegment.java
  Written by:	Ettore Pasquini, 1999
  
Il DataSegment è un'area della memoria in cui sono mem. i dati. Tale area viene vista come un vettore di elementi, a cui la macchina accede attraverso opportune operazioni di I/O attraverso l'uso di registri.

 *****************************************************************************/

import java.util.*;
import StackMachine;
import CodeSegment;
import MachineSignal;


public class DataSegment extends Segment{
  private DataVector memory;
 
  public DataSegment(){
	setBase(0);
	memory= new DataVector();	// creo un vettore vuoto
  }

  public DataSegment( int baseaddr ){
	setBase(baseaddr);
	memory= new DataVector();
  }

  public DataSegment(int initcapacity, int baseaddr){
	//il vettore viene creato esternamente, e poi viene passato il rif.
	setBase(baseaddr);
	memory = new DataVector(initcapacity);
  }

  public int length(){ return memory.size(); }

  public void init(){ memory.fillWithZeroes(); }

  public int read( Register sourceADDRreg ) 
				      throws InvalidDataReadAddressException{
	return memory.readDatumAt( sourceADDRreg.contents() - base() );
  }

  public void write(Register sourceDATAreg, Register targetADDRreg)
				      throws InvalidDataWriteAddressException{
     /*
	System.out.println( "\nTR1(srcdata)= "+sourceDATAreg.contents() + 
		"\nTR2(addr)= " + targetADDRreg.contents() );
     */

	memory.writeDatumAt(	sourceDATAreg.contents(), 
				targetADDRreg.contents() - base());
  }

  public DataVector getDataVector(){ return memory;}

  public String toString(){
	return  "\t" + "DS base_addr.=\t" + Integer.toString(base()) + 
		"\t" + "DS length=\t" + memory.size() + "\n  DS:" +
		memory.stringView(this);
  }
	
}//DataSegment

/**********/

class DataVector extends Vector{

  public DataVector(){ super();}

  public DataVector(int initcapacity){
	super();
	int i=0;
	while( i < initcapacity ){
		addElement( new Integer(0) );
		i++;
	}
  }

  public int readDatumAt(int addr) throws InvalidDataReadAddressException{
	int x=0;
	try{
		Integer d= (Integer) this.elementAt(addr);
		x = d.intValue();
	}
	catch( ArrayIndexOutOfBoundsException aioobe ){
		throw new InvalidDataReadAddressException();
	}
	return x;
  }

  public void writeDatumAt( int newdatum, int addr)
				throws InvalidDataWriteAddressException{
	try{
		setElementAt( (new Integer(newdatum)), addr );
	}
	catch( ArrayIndexOutOfBoundsException aioobe ){
		throw new InvalidDataWriteAddressException();
	}
  }

  public void fillWithZeroes(){
	int i=0;
	int length= this.size();
	while( i< length ){
		//qui non è possibile incorrere in errore
		setElementAt( new Integer(0) , i );
		i++;
	}
  }

  public void init(int lung){
	setSize(lung);
	fillWithZeroes();
  }

  public String stringView(DataSegment DS){
	int lung= this.size();
	int i=0;
	int baseaddr=DS.base();
	String temp = " ADDR\tVAL\n ----\t---";
	while (i<lung){
		try{
			temp = temp+ "\n " + Integer.toString(i+baseaddr) +
							"\t" + readDatumAt(i);
		}
		catch( InvalidDataReadAddressException idrae ){
			//...ma dovrebbe essere impossibile entrare qui...
			temp = temp + "ReadError";
		}
		i++;
	}
	return temp;
  }
}//DataVector

