/**
 * This class owns the instruction set table and offers services to handles it.
 * <BR>You can read the source of this class <A HREF="./InstructionSet.java.html"> here</A>.
 */
public abstract class InstructionSet {

	/**
	 * Number of instructions in set.
	 */
	protected static final int NbInstructions = 35;

	/**
	 * Returns the InstructionInformation corresponding to the given mnemonic.
	 * @param mn Mnemonic.
	 */
	public static InstructionInformation Find(String mn) {	// find following to mnemonic
		int i;
		for(i = 0 ; i < NbInstructions ; i++) {
			if(Instructions[i].Mnemonic().compareTo(mn) == 0)
				return Instructions[i];
		}
		return null;
	}

	/**
	 * Returns the InstructionInformation corresponding to the given opcode.
	 * @param op Opcode.
	 */
	public static InstructionInformation Find(int op) {	// find following to Opcode
		int i;
		for(i = 0 ; i < NbInstructions ; i++) {
			if(Instructions[i].Opcode() == (op & Instructions[i].Mask()))
				return Instructions[i];
		}
		return null;
	}

	/**
	 * This method dumps the instruction set to System.out.
	 */
	public static void DumpTable() {
		int i;
		for(i = 0 ; i < NbInstructions ; i++) {
			System.out.println(Instructions[i].Mnemonic() + "\t" + Instructions[i].NbOperandes() + "\t" +
					   /*Instructions[i].Help() + "\t" */+ Instructions[i].NbCycles() + "\t" +
					   Utils.bin(Instructions[i].Opcode(), 14, 4) + "\t" + Utils.bin(Instructions[i].Mask(), 14, 4));
		}
	}


	protected static InstructionInformation Instructions[] = {
		new InstructionInformation("addwf",	2, "Add W and f",			1, 0x0700, 0x3F00, OpcodeType.FileAndDest,	 1),
		new InstructionInformation("andwf",	2, "AND W with f",			1, 0x0500, 0x3F00, OpcodeType.FileAndDest,	 2),
		new InstructionInformation("clrf",	1, "Clear f",				1, 0x0180, 0x3F80, OpcodeType.File,		 3),
		new InstructionInformation("clrw",	0, "Clear W",				1, 0x0100, 0x3F80, OpcodeType.NoOperande,	 4),
		new InstructionInformation("comf",	2, "Complement f",			1, 0x0900, 0x3F00, OpcodeType.FileAndDest,	 5),
		new InstructionInformation("decf",	2, "Decrement f",			1, 0x0300, 0x3F00, OpcodeType.FileAndDest,	 6),
		new InstructionInformation("decfsz",	2, "Decrement f, Skip if 0",		3, 0x0B00, 0x3F00, OpcodeType.FileAndDest,	 7),
		new InstructionInformation("incf",	2, "Increment f",			1, 0x0A00, 0x3F00, OpcodeType.FileAndDest,	 8),
		new InstructionInformation("incfsz",	2, "Increment f, Skip if 0",		3, 0x0F00, 0x3F00, OpcodeType.FileAndDest,	 9),
		new InstructionInformation("iorwf",	2, "Inclusive OR W with f",		1, 0x0400, 0x3F00, OpcodeType.FileAndDest,	10),
		new InstructionInformation("movf",	2, "Move f",				1, 0x0800, 0x3F00, OpcodeType.FileAndDest,	11),
		new InstructionInformation("movwf",	1, "Move W to f",			1, 0x0080, 0x3F80, OpcodeType.File,		12),
		new InstructionInformation("nop",	0, "No Operation",			1, 0x0000, 0xFF9F, OpcodeType.NoOperande,	13),
		new InstructionInformation("rlf",	2, "Rotate Left f through Carry",	1, 0x0D00, 0x3F00, OpcodeType.FileAndDest,	14),
		new InstructionInformation("rrf",	2, "Rotate Right f through Carry",	1, 0x0C00, 0x3F00, OpcodeType.FileAndDest,	15),
		new InstructionInformation("subwf",	2, "Substract W from f",		1, 0x0200, 0x3F00, OpcodeType.FileAndDest,	16),
		new InstructionInformation("swapf",	2, "Swap nibbles in f",			1, 0x0E00, 0x3F00, OpcodeType.FileAndDest,	17),
		new InstructionInformation("xorwf",	2, "Exclusive OR W with f",		1, 0x0600, 0x3F00, OpcodeType.FileAndDest,	18),

		new InstructionInformation("bcf",	2, "Bit Clear f",			1, 0x1000, 0x3C00, OpcodeType.FileAnd3BitsConst,19),
		new InstructionInformation("bsf",	2, "Bit Set f",				1, 0x1400, 0x3C00, OpcodeType.FileAnd3BitsConst,20),
		new InstructionInformation("btfsc",	2, "Bit Test f, Skip if Clear",		3, 0x1800, 0x3C00, OpcodeType.FileAnd3BitsConst,21),
		new InstructionInformation("btfss",	2, "Bit Test f, Skip if Set",		3, 0x1C00, 0x3C00, OpcodeType.FileAnd3BitsConst,22),


     		new InstructionInformation("addlw",	1, "Add literal and W",			1, 0x3E00, 0x3E00, OpcodeType.Literal8Bits,	23),
     		new InstructionInformation("andlw",	1, "AND literal with W",		1, 0x3900, 0x3F00, OpcodeType.Literal8Bits,	24),
     		new InstructionInformation("call",	1, "Call subroutine",			2, 0x2000, 0x3800, OpcodeType.Literal11Bits,	25),
     		new InstructionInformation("clrwdt",	0, "Clear Watchdog Timer",		1, 0x0064, 0xFFFF, OpcodeType.NoOperande,	26),
     		new InstructionInformation("goto",	1, "Go to address",			2, 0x2800, 0x3800, OpcodeType.Literal11Bits,	27),
     		new InstructionInformation("iorlw",	1, "Inclusive OR literal with W",	1, 0x3800, 0x3F00, OpcodeType.Literal8Bits,	28),
     		new InstructionInformation("movlw",	1, "Move literal to W",			1, 0x3000, 0x3C00, OpcodeType.Literal8Bits,	29),
     		new InstructionInformation("retfie",	0, "Return from interrupt",		2, 0x0009, 0xFFFF, OpcodeType.NoOperande,	30),
     		new InstructionInformation("retlw",	1, "Return with literal in W",		2, 0x3400, 0x3C00, OpcodeType.Literal8Bits,	31),
     		new InstructionInformation("return",	0, "Return from Subroutine",		2, 0x0008, 0xFFFF, OpcodeType.NoOperande,	32),
     		new InstructionInformation("sleep",	0, "Go into standby mode",		1, 0x0063, 0xFFFF, OpcodeType.NoOperande,	33),
     		new InstructionInformation("sublw",	1, "Substract W from literal",		1, 0x3C00, 0x3E00, OpcodeType.Literal8Bits,	34),
     		new InstructionInformation("xorlw",	1, "Exclusive OR literal with W",	1, 0x3A00, 0x3F00, OpcodeType.Literal8Bits,	35)
		};

}