/**
 * <BR>You can read the source of this class <A HREF="./DebuggablePIC_std.java.html"> here</A>.
 */
public class DebuggablePIC_std extends PIC_std implements DebuggablePIC {

	protected final int MaxBPs = 10;

// Constructors
	/**
	 * Creates a new DebuggablePIC_std without any program.
	 */
	public DebuggablePIC_std() {
		FR = new DebuggableFileRegisters();
		Fl = new DebuggableFlash();
		Stack = new int[8];
		BPs = new int[MaxBPs];
		NBPs = 0;
	}

	/**
	 * Creates a new DebuggablePIC_std without any program with an UI.
	 */
	public DebuggablePIC_std(DigitalComponentUI dui) {
		super(dui);
		FR = new DebuggableFileRegisters();
		Fl = new DebuggableFlash();
		Stack = new int[8];
		BPs = new int[MaxBPs];
		NBPs = 0;
	}

	/**
	 * Creates a new DebuggablePIC_std with a program.
	 * @param prog The program.
	 */
	public DebuggablePIC_std(CompiledProgram prog) {
		FR = new DebuggableFileRegisters();
		Fl = new DebuggableFlash(prog);
		Stack = new int[8];
		BPs = new int[MaxBPs];
		NBPs = 0;
	}

// Execution control
	public void Trace() {
		ExecInstruction();
	}

	public void ReprogramFlash(CompiledProgram prog) {
		super.ReprogramFlash(prog);
		((DebuggableFileRegisters)FR).setSymbolicInfos(prog.getVariableSymb());
	}
// Internal access
	public int getPC() {
		return PC;
	}

	public void setPC(int n) {
		PC = n;
	}

	public int getW() {
		return W;
	}

	public void setW(int n) {
		W = n;
	}

	public int getSP() {
		return StackPointer;
	}

	public void setSP(int n) {
		StackPointer = n;
	}

	public int getStack(int Level) {
		return Stack[Level];
	}

	public void setStack(int Level, int n) {
		Stack[Level] = n;
	}

	public DebuggableFlash getFlashMemory() {
		return (DebuggableFlash)Fl;
	}

	public DebuggableFileRegisters getFileRegisters() {
		return (DebuggableFileRegisters)FR;
	}

// Display methods
	public String[] getStateForDisplay() {
		String s[] = {"PC=" + Utils.hex(PC, 3, 4),
				"W = " + Utils.hex(W, 2, 4),
				"SP=  " + StackPointer};
		return s;
	}

	public String DisplayInstruction() {
		return Disassembler.Disassemble(Fl.Read(PC));
	}

	public String[] getStackForDisplay() {
		int i;
		String s[] = new String[8];

		for(i = 0 ; i < 8 ; i++)
			s[i] = Utils.hex(Stack[i], 3, 3);

		return s;
	}

	public String[] getFlashForDisplay() {
		return ((DebuggableFlash)Fl).Display();
	}

	public String getFlashRefresh(int n, String s) {
		String t;

		if(isBreakpoint(n))
			t = "B";
		else
			t = " ";
		if(n == PC)
			t += ">";
		else
			t += " ";

		return s.substring(0, Disassembler.OffsetSize + 2) + t + s.substring(Disassembler.OffsetSize + 4);
	}

	public String[] getBreakpointsForDisplay() {
		int i;
		String s[] = new String[NBPs];

		for(i = 0 ; i < NBPs ; i++)
			s[i] = Utils.hex(BPs[i], 3, 3);

		return s;
	}

// Breakpoints methods
	public int getBreakpoint(int n) {
		return BPs[n];
	}

	public void setBreakpoint(int n) {
		if(!isBreakpoint(n) && (NBPs + 1 < MaxBPs))
			BPs[NBPs++] = n;
	}

	protected int BreakpointNum(int n) {
		int i;

		for(i = 0 ; i < NBPs ; i++)
			if(BPs[i] == n)
				return i;

		return -1;
	}

	public boolean isBreakpoint(int n) {
		return (BreakpointNum(n) == -1) ? false : true;
	}

	public void removeBreakpoint(int n) {
		if(isBreakpoint(n)) {
			int i, k = BreakpointNum(n);

			for(i = k ; i < NBPs - 1; i++)
				BPs[i] = BPs[i + 1];

			NBPs--;
		}
	}

	protected int BPs[], NBPs;
}