#include <stdio.h>
#include "mem_M68K.h"
#include "mem_S68K.h"


static char Dbg_Str[32];
static char Dbg_EA_Str[16];
static char Dbg_Size_Str[3];
static char Dbg_Cond_Str[3];

static unsigned short (*Next_Word)();
static unsigned int (*Next_Long)();


char *Make_Dbg_EA_Str(int Size, int EA_Num, int Reg_Num)
{
	int i;
	Dbg_EA_Str[15] = 0;

	switch(EA_Num)
	{
		case 0:
			// 000 rrr  Dr
			sprintf(Dbg_EA_Str, "D%.1d%c", Reg_Num, 0);
			break;

		case 1:
			// 001 rrr  Ar
			sprintf(Dbg_EA_Str, "A%.1d%c", Reg_Num, 0);
			break;

		case 2:
			// 010 rrr  (Ar)
			sprintf(Dbg_EA_Str, "(A%.1d)%c", Reg_Num, 0);
			break;

		case 3:
			// 011 rrr  (Ar)+
			sprintf(Dbg_EA_Str, "(A%.1d)+%c", Reg_Num, 0);
			break;

		case 4:
			// 100 rrr  -(Ar)
			sprintf(Dbg_EA_Str, "-(A%.1d)%c", Reg_Num, 0);
			break;

		case 5:
			// 101 rrr  d16(Ar)     dddddddd dddddddd
			sprintf(Dbg_EA_Str, "$%.4X(A%.1d)%c", Next_Word(), Reg_Num, 0);
			break;

		case 6:
			// 110 rrr  d8(Ar,ix)   aiiizcc0 dddddddd
			i = Next_Word() & 0xFFFF;
			if (i & 0x8000)
				sprintf(Dbg_EA_Str, "$%.2X(A%.1d,A%.1d)%c", i & 0xFF, Reg_Num, (i >> 12) & 0x7, 0);
			else
  				sprintf(Dbg_EA_Str, "$%.2X(A%.1d,D%.1d)%c", i & 0xFF, Reg_Num, (i >> 12) & 0x7, 0);
			break;

		case 7:
			switch(Reg_Num)
			{
				case 0:
					// 111 000  addr16      dddddddd dddddddd
					sprintf(Dbg_EA_Str, "($%.4X)%c", Next_Word(), 0);
					break;

				case 1:
					// 111 001  addr32      dddddddd dddddddd ddddddddd dddddddd
					sprintf(Dbg_EA_Str, "($%.8X)%c", Next_Long(), 0);
					break;

				case 2:
					// 111 010  d16(PC)     dddddddd dddddddd
					sprintf(Dbg_EA_Str, "$%.4X(PC)%c", Next_Word(), 0);
					break;

				case 3:
					// 111 011  d8(PC,ix)   aiiiz000 dddddddd
					i = Next_Word() & 0xFFFF;
					if (i & 0x8000)
						sprintf(Dbg_EA_Str, "$%.2X(PC,A%.1d)%c", i & 0xFF, (i >> 12) & 0x7, 0);
					else
						sprintf(Dbg_EA_Str, "$%.2X(PC,D%.1d)%c", i & 0xFF, (i >> 12) & 0x7, 0);
					break;

				case 4:
					// 111 100  imm/implied
					switch(Size)
					{
						case 0:
							sprintf(Dbg_EA_Str, "#$%.2X%c", Next_Word() & 0xFF, 0);
							break;

						case 1:
							sprintf(Dbg_EA_Str, "#$%.4X%c", Next_Word(), 0);
							break;

						case 2:
							sprintf(Dbg_EA_Str, "#$%.8X%c", Next_Long(), 0);
							break;
					}
					break;
			}
			break;
		}

	return(Dbg_EA_Str);
}


char *Make_Dbg_Size_Str(int Size)
{
	Dbg_Size_Str[2] = 0;
	sprintf(Dbg_Size_Str, ".?");

	switch(Size)
	{
		case 0:
			sprintf(Dbg_Size_Str, ".B");
			break;

		case 1:
			sprintf(Dbg_Size_Str, ".W");
			break;

		case 2:
			sprintf(Dbg_Size_Str, ".L");
			break;
	}

	return(Dbg_Size_Str);
}


char *Make_Dbg_Size_Str_2(int Size)
{
	Dbg_Size_Str[2] = 0;
	sprintf(Dbg_Size_Str, ".?");

	switch(Size)
	{
		case 0:
			sprintf(Dbg_Size_Str, ".W");
			break;

		case 1:
			sprintf(Dbg_Size_Str, ".L");
			break;
	}

	return(Dbg_Size_Str);
}

char *Make_Dbg_Cond_Str(int Cond)
{
	Dbg_Cond_Str[2] = 0;
	sprintf(Dbg_Cond_Str, "??");

	switch(Cond)
	{
		case 0:
			sprintf(Dbg_Cond_Str, "Tr");
			break;

		case 1:
			sprintf(Dbg_Cond_Str, "Fa");
			break;

		case 2:
			sprintf(Dbg_Cond_Str, "HI");
			break;

		case 3:
			sprintf(Dbg_Cond_Str, "LS");
			break;

		case 4:
			sprintf(Dbg_Cond_Str, "CC");
			break;

		case 5:
			sprintf(Dbg_Cond_Str, "CS");
			break;

		case 6:
			sprintf(Dbg_Cond_Str, "NE");
			break;

		case 7:
			sprintf(Dbg_Cond_Str, "EQ");
			break;

		case 8:
			sprintf(Dbg_Cond_Str, "VC");
			break;

		case 9:
			sprintf(Dbg_Cond_Str, "VS");
			break;

		case 10:
			sprintf(Dbg_Cond_Str, "PL");
			break;

		case 11:
			sprintf(Dbg_Cond_Str, "MI");
			break;

		case 12:
			sprintf(Dbg_Cond_Str, "GE");
			break;

		case 13:
			sprintf(Dbg_Cond_Str, "LT");
			break;

		case 14:
			sprintf(Dbg_Cond_Str, "GT");
			break;

		case 15:
			sprintf(Dbg_Cond_Str, "LE");
			break;
    }

	return(Dbg_Cond_Str);
}


char *M68KDisasm(unsigned short (*NW)(), unsigned int (*NL)())
{
	int i;
	unsigned short OPC;
	char Tmp_Str[32];

	Dbg_Str[31] = 0;
	Tmp_Str[31] = 0;

	Next_Word = NW;
	Next_Long = NL;

	OPC = Next_Word();

	sprintf(Dbg_Str, "Unknow Opcode%c", 0);

	switch(OPC >> 12)
	{
		case 0:

		if (OPC & 0x100)
		{
			if ((OPC & 0x038) == 0x8)
			{
				if (OPC & 0x080)
					//MOVEP.z Ds,d16(Ad)
					sprintf(Dbg_Str, "MOVEP%-3sD%.1d,#$%.4X(A%.1d)%c", Make_Dbg_Size_Str_2((OPC & 0x40) >> 6), (OPC & 0xE00) >> 9, Next_Word(), OPC & 0x7, 0);
				else
					//MOVEP.z d16(As),Dd
					sprintf(Dbg_Str, "MOVEP%-3s#$%.4X(A%.1d),D%.1d%c", Make_Dbg_Size_Str_2((OPC & 0x40) >> 6), Next_Word(), OPC & 0x7, (OPC & 0xE00) >> 9, 0);
			}
			else
			{
				switch((OPC >> 6) & 0x3)
				{
					case 0:
						//BTST  Ds,a
						sprintf(Dbg_Str, "BTST    D%.1d,%s%c", (OPC & 0xE00) >> 9, Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 7), 0);
						break;

					case 1:
						//BCHG  Ds,a
						sprintf(Dbg_Str, "BCHG    D%.1d,%s%c", (OPC & 0xE00) >> 9, Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 7), 0);
						break;

					case 2:
						//BCLR  Ds,a
						sprintf(Dbg_Str, "BCLR    D%.1d,%s%c", (OPC & 0xE00) >> 9, Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 7), 0);
						break;

					case 3:
						//BSET  Ds,a
						sprintf(Dbg_Str, "BSET    D%.1d,%s%c", (OPC & 0xE00) >> 9, Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 7), 0);
						break;
				}
			}
		}
		else
		{
			switch((OPC >> 6) & 0x3F)
			{
				case 0:
					//ORI.B  #k,a
					i = Next_Word() & 0xFF;
					sprintf(Dbg_Str, "ORI.B   #$%.2X,%s%c", i, Make_Dbg_EA_Str(0, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 1:
					//ORI.W  #k,a
					i = Next_Word() & 0xFFFF;
					sprintf(Dbg_Str, "ORI.W   #$%.4X,%s%c", i, Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 2:
					//ORI.L  #k,a
					i = Next_Long();
					sprintf(Dbg_Str, "ORI.L   #$%.8X,%s%c", i, Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 8:
					//ANDI.B  #k,a
					i = Next_Word() & 0xFF;
					sprintf(Dbg_Str, "ANDI.B  #$%.2X,%s%c", i & 0xFF, Make_Dbg_EA_Str(0, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 9:
					//ANDI.W  #k,a
					i = Next_Word() & 0xFFFF;
					sprintf(Dbg_Str, "ANDI.W  #$%.4X,%s%c", i, Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 10:
					//ANDI.L  #k,a
					i = Next_Long();
					sprintf(Dbg_Str, "ANDI.L  #$%.8X,%s%c", i, Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 16:
					//SUBI.B  #k,a
					i = Next_Word() & 0xFF;
					sprintf(Dbg_Str, "SUBI.B  #$%.2X,%s%c", i & 0xFF, Make_Dbg_EA_Str(0, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 17:
					//SUBI.W  #k,a
					i = Next_Word() & 0xFFFF;
					sprintf(Dbg_Str, "SUBI.W  #$%.4X,%s%c", i, Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 18:
					//SUBI.L  #k,a
					i = Next_Long();
					sprintf(Dbg_Str, "SUBI.L  #$%.8X,%s%c", i, Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 24:
					//ADDI.B  #k,a
					i = Next_Word() & 0xFF;
					sprintf(Dbg_Str, "ADDI.B  #$%.2X,%s%c", i & 0xFF, Make_Dbg_EA_Str(0, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 25:
					//ADDI.W  #k,a
					i = Next_Word() & 0xFFFF;
					sprintf(Dbg_Str, "ADDI.W  #$%.4X,%s%c", i, Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 26:
					//ADDI.L  #k,a
					i = Next_Long();
					sprintf(Dbg_Str, "ADDI.L  #$%.8X,%s%c", i, Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 32:
					//BTST  #n,a
					i = Next_Word() & 0xFF;
					sprintf(Dbg_Str, "BTST    #%d,%s%c", i, Make_Dbg_EA_Str(0, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 33:
					//BCHG  #n,a
					i = Next_Word() & 0xFF;
					sprintf(Dbg_Str, "BCHG    #%d,%s%c", i, Make_Dbg_EA_Str(0, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 34:
					//BCLR  #n,a
					i = Next_Word() & 0xFF;
					sprintf(Dbg_Str, "BCLR    #%d,%s%c", i, Make_Dbg_EA_Str(0, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 35:
					//BSET  #n,a
					i = Next_Word() & 0xFF;
					sprintf(Dbg_Str, "BSET    #%d,%s%c", i, Make_Dbg_EA_Str(0, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 40:
					//EORI.B  #k,a
					i = Next_Word() & 0xFF;
					sprintf(Dbg_Str, "EORI.B  #$%.2X,%s%c", i & 0xFF, Make_Dbg_EA_Str(0, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 41:
					//EORI.W  #k,a
					i = Next_Word() & 0xFFFF;
					sprintf(Dbg_Str, "EORI.W  #$%.4X,%s%c", i, Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 42:
					//EORI.L  #k,a
					i = Next_Long();
					sprintf(Dbg_Str, "EORI.L  #$%.8X,%s%c", i, Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 48:
					//CMPI.B  #k,a
					i = Next_Word() & 0xFF;
					sprintf(Dbg_Str, "CMPI.B  #$%.2X,%s%c", i & 0xFF, Make_Dbg_EA_Str(0, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 49:
					//CMPI.W  #k,a
					i = Next_Word() & 0xFFFF;
					sprintf(Dbg_Str, "CMPI.W  #$%.4X,%s%c", i, Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 50:
					//CMPI.L  #k,a
					i = Next_Long();
					sprintf(Dbg_Str, "CMPI.L  #$%.8X,%s%c", i, Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;
			}
		}
		break;

		case 1:
			//MOVE.b  as,ad
			sprintf(Tmp_Str, "%s%c", Make_Dbg_EA_Str(0, (OPC >> 3) & 0x7, OPC & 0x7), 0);
			sprintf(Dbg_Str, "MOVE.b  %s,%s%c", Tmp_Str, Make_Dbg_EA_Str(0, (OPC >> 6) & 0x7, (OPC >> 9) & 0x7), 0);
			break;

		case 2:
			//MOVE.l  as,ad
			sprintf(Tmp_Str, "%s%c", Make_Dbg_EA_Str(2, (OPC >> 3) & 0x7, OPC & 0x7), 0);
			sprintf(Dbg_Str, "MOVE.l  %s,%s%c", Tmp_Str, Make_Dbg_EA_Str(2, (OPC >> 6) & 0x7, (OPC >> 9) & 0x7), 0);
			break;

		case 3:
			//MOVE.w  as,ad
			sprintf(Tmp_Str, "%s%c", Make_Dbg_EA_Str(1, (OPC >> 3) & 0x7, OPC & 0x7), 0);
			sprintf(Dbg_Str, "MOVE.w  %s,%s%c", Tmp_Str, Make_Dbg_EA_Str(1, (OPC >> 6) & 0x7, (OPC >> 9) & 0x7), 0);
			break;

		case 4:
			//SPECIALS ...

			if (OPC & 0x100)
			{
				if (OPC & 0x40)
					//LEA  a,Ad
					sprintf(Dbg_Str, "LEA     %s,A%.1d%c", Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
				else
					//CHK.W  a,Dd
					sprintf(Dbg_Str, "CHK.W   %s,D%.1d%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
			}
			else
			{
				switch((OPC >> 6) & 0x3F)
				{
					case 0:	case 1: case 2:
						//NEGX.z  a
						sprintf(Dbg_Str, "NEGX%-4s%s%c", Make_Dbg_Size_Str((OPC >> 6) & 3), Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 3:
						//MOVE  SR,a
						sprintf(Dbg_Str, "MOVE    SR,%s%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 8: case 9: case 10:
						//CLR.z  a
						sprintf(Dbg_Str, "CLR%-5s%s%c", Make_Dbg_Size_Str((OPC >> 6) & 3), Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 16: case 17: case 18:
						//NEG.z  a
						sprintf(Dbg_Str, "NEG%-5s%s%c", Make_Dbg_Size_Str((OPC >> 6) & 3), Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 19:
						//MOVE  a,CCR
						sprintf(Dbg_Str, "MOVE    %s,CCR%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 24: case 25: case 26:
						//NOT.z  a
						sprintf(Dbg_Str, "NOT%-4s%s%c", Make_Dbg_Size_Str((OPC >> 6) & 3), Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 27:
						//MOVE  a,SR
						sprintf(Dbg_Str, "MOVE    %s,SR%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 32:
						//NBCD  a
						sprintf(Dbg_Str, "NBCD    %s%c", Make_Dbg_EA_Str(0, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 33:

						if (OPC & 0x38)
							//PEA  a
							sprintf(Dbg_Str, "PEA     %s%c", Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						else
							//SWAP.w  Dd
							sprintf(Dbg_Str, "SWAP.w  D%d%c", OPC & 0x7, 0);

						break;

					case 34: case 35:

						if (OPC & 0x38)
						{
							//MOVEM.z Reg-List,a
							sprintf(Dbg_Str, "MOVEM%-3sReg-List,%s%c", Make_Dbg_Size_Str_2((OPC >> 6) & 1), Make_Dbg_EA_Str((OPC >> 6) & 1 + 1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
							Next_Word();
						}
						else
							//EXT.z  Dd
							sprintf(Dbg_Str, "EXT%-5s%s%c", Make_Dbg_Size_Str_2((OPC >> 6) & 1), Make_Dbg_EA_Str((OPC >> 6) & 1 + 1, (OPC & 0x38) >> 3, OPC & 0x7), 0);

						break;

					case 40: case 41: case 42:
						//TST.z a
						sprintf(Dbg_Str, "TST%-5s%s%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), Make_Dbg_EA_Str((OPC >> 6) & 0x3, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 43:
						//TAS.b a
						sprintf(Dbg_Str, "TAS.B %s%c", Make_Dbg_EA_Str(0, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 48: case 49:
						//Bad Opcode
						sprintf(Dbg_Str, "Bad Opcode%c", 0);
						break;

					case 50: case 51:
						//MOVEM.z a,Reg-List
						sprintf(Dbg_Str, "MOVEM%-3s%s,Reg-List%c", Make_Dbg_Size_Str_2((OPC >> 6) & 1), Make_Dbg_EA_Str((OPC >> 6) & 1 + 1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						Next_Word();
						break;

					case 57:

						switch((OPC >> 3) & 0x7)
						{
							case 0: case 1:
								//TRAP  #vector
								sprintf(Dbg_Str, "TRAP    #$%.1X%c", OPC & 0xF, 0);
								break;

							case 2:
								//LINK As,#k16
								sprintf(Dbg_Str, "LINK    A%.1d,#$%.4X%c", OPC & 0x7, Next_Word(), 0);
								break;

							case 3:
								//ULNK Ad
								sprintf(Dbg_Str, "ULNK    A%.1d%c", OPC & 0x7, 0);
								break;

							case 4:
								//MOVE As,USP
								sprintf(Dbg_Str, "MOVE    A%.1d,USP%c",OPC & 0x7, 0);
								break;

							case 5:
								//MOVE USP,Ad
								sprintf(Dbg_Str, "MOVE    USP,A%.1d%c",OPC & 0x7, 0);
								break;

							case 6:

								switch(OPC & 0x7)
								{
									case 0:
										//RESET
										sprintf(Dbg_Str, "RESET%c", 0);
										break;

									case 1:
										//NOP
										sprintf(Dbg_Str, "NOP%c", 0);
										break;

									case 2:
										//STOP #k16
										sprintf(Dbg_Str, "STOP    #$%.4X%c", Next_Word(), 0);
										break;

									case 3:
										//RTE
										sprintf(Dbg_Str, "RTE%c", 0);
										break;

									case 4:
										//Bad Opcode
										sprintf(Dbg_Str, "Bad Opcode%c", 0);
										break;

									case 5:
										//RTS
										sprintf(Dbg_Str, "RTS%c", 0);
										break;

									case 6:
										//TRAPV
										sprintf(Dbg_Str, "TRAPV%c", 0);
										break;

									case 7:
										//RTR
										sprintf(Dbg_Str, "RTR%c", 0);
										break;
								}
								break;
						}
						break;

					case 58:
						//JSR  a
						sprintf(Dbg_Str, "JSR     %s%c", Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 59:
						//JMP  a
						sprintf(Dbg_Str, "JMP     %s%c", Make_Dbg_EA_Str(2, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;
				}
			}
			break;

		case 5:

			if ((OPC & 0xC0) == 0xC0)
			{
				if ((OPC & 0x38) == 0x08)
					//DBCC  Ds,label
					sprintf(Dbg_Str, "DB%-6sD%.1d,#$%.4X%c", Make_Dbg_Cond_Str((OPC >> 8) & 0xF), OPC & 0x7, Next_Word(), 0);
				else
					//STCC.b  a
					sprintf(Dbg_Str, "ST%-6s%s%c", Make_Dbg_Cond_Str((OPC >> 8) & 0xF), Make_Dbg_EA_Str(0, (OPC & 0x38) >> 3, OPC & 0x7), 0);
				break;
			}
			else
			{
				if (OPC & 0x100)
					//SUBQ.z  #k3,a
					sprintf(Dbg_Str, "SUBQ%-4s#%.1d,%s%c", Make_Dbg_Size_Str((OPC >> 6) & 3), (OPC >> 9) & 0x7, Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), 0);
				else
					//ADDQ.z  #k3,a
					sprintf(Dbg_Str, "ADDQ%-4s#%.1d,%s%c", Make_Dbg_Size_Str((OPC >> 6) & 3), (OPC >> 9) & 0x7, Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), 0);
				break;
			}
			break;

		case 6:

			if (OPC & 0xFF)
			{
				if ((OPC & 0xF00) == 0x100)
				{
					//BSR  label
					sprintf(Dbg_Str, "BSR     #$%.2X%c", OPC & 0xFF, 0);
					break;
				}

				if (!(OPC & 0xF00))
				{
					//BRA  label
					sprintf(Dbg_Str, "BRA     #$%.2X%c", OPC & 0xFF, 0);
					break;
				}

				//BCC  label
				sprintf(Dbg_Str, "B%-7s#$%.2X%c", Make_Dbg_Cond_Str((OPC >> 8) & 0xF), OPC & 0xFF, 0);
			}
			else
			{
				if ((OPC & 0xF00) == 0x100)
				{
					//BSR  label
					sprintf(Dbg_Str, "BSR     #$%.4X%c", Next_Word(), 0);
					break;
				}

				if (!(OPC & 0xF00))
				{
					//BRA  label
					sprintf(Dbg_Str, "BRA     #$%.4X%c", Next_Word(), 0);
					break;
				}

				//BCC  label
				sprintf(Dbg_Str, "B%-7s#$%.4X%c", Make_Dbg_Cond_Str((OPC >> 8 ) & 0xF), Next_Word(), 0);
			}
			break;

		case 7:
			//MOVEQ  #k8,Dd
			sprintf(Dbg_Str, "MOVEQ   #$%.2X,D%.1d%c", OPC & 0xFF, (OPC >> 9) & 0x7, 0);
			break;

		case 8:

			if (OPC & 0x100)
  			{
				if (!(OPC & 0xF8))
				{
					//SBCD  Ds,Dd
					sprintf(Dbg_Str, "SBCD D%.1d,D%.1d%c", OPC & 0x7, (OPC >> 9) & 0x7, 0);
					break;
				}

				if ((OPC & 0xF8) == 0x8)
				{
					//SBCD  -(As),-(Ad)
					sprintf(Dbg_Str, "SBCD -(A%.1d),-(A%.1d)%c", OPC & 0x7, (OPC >> 9) & 0x7, 0);
					break;
				}

				if ((OPC & 0xC0) == 0xC0)
					//DIVS.w  a,Dd
					sprintf(Dbg_Str, "DIVS.W  %s,D%.1d%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
				else
					//OR.z  Ds,a
					sprintf(Dbg_Str, "OR%-6sD%.1d;%s%c", Make_Dbg_Size_Str((OPC >> 6) & 3), (OPC >> 9) & 0x7, Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), 0);
			}
			else
			{
				if ((OPC & 0xC0) == 0xC0)
					//DIVU.w  a,Dd
					sprintf(Dbg_Str, "DIVU.W  %s,D%.1d%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
				else
					//OR.z  a,Dd
					sprintf(Dbg_Str, "OR%-6s%s,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 3), Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
			}
			break;

		case 9:

			if ((OPC & 0xC0) == 0xC0)
				//SUBA.z  a,Ad
				sprintf(Dbg_Str, "SUBA%-4s%s,A%.1d%c", Make_Dbg_Size_Str_2((OPC >> 8) & 1), Make_Dbg_EA_Str((OPC >> 8) & 1 + 1, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
			else
			{
				if (OPC & 0x100)
				{
					if (!(OPC & 0x38))
					{
						//SUBX.z  Ds,Dd
						sprintf(Dbg_Str, "SUBX%-4sD%.1d,D%.1d%c",	Make_Dbg_Size_Str((OPC >> 6) & 0x3), OPC & 0x7, (OPC >> 9) & 0x7, 0);
						break;
					}

					if ((OPC & 0x38) == 0x8)
					{
						//SUBX.z  -(As),-(Ad)
						sprintf(Dbg_Str, "SUBX%-4s-(A%.1d),-(A%.1d)%c",	Make_Dbg_Size_Str((OPC >> 6) & 0x3), OPC & 0x7, (OPC >> 9) & 0x7, 0);
						break;
					}

					//SUB.z  Ds,a
					sprintf(Dbg_Str, "SUB%-5sD%.1d,%s%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), 0);
				}
				else
					//SUB.z  a,Dd
					sprintf(Dbg_Str, "SUB%-5s%s,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
			}
			break;

		case 10:
			//Bad Opcode
			sprintf(Dbg_Str, "Bad Opcode%c", 0);
			break;

		case 11:

			if ((OPC & 0xC0) == 0xC0)
				//CMPA.z  a,Ad
				sprintf(Dbg_Str, "CMPA%-4s%s,A%.1d%c", Make_Dbg_Size_Str_2((OPC >> 8) & 1), Make_Dbg_EA_Str((OPC >> 7) & 1 + 1, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
			else
			{
				if (OPC & 0x100)
				{
					if ((OPC & 0x38) == 0x8)
					{
						//CMPM.z  (As)+,(Ad)+
						sprintf(Dbg_Str, "CMPM%-4s(A%.1d)+,(A%.1d)+%c",	Make_Dbg_Size_Str((OPC >> 6) & 0x3), OPC & 0x7, (OPC >> 9) & 0x7, 0);
						break;
					}

					//EOR.z  Ds,a
					sprintf(Dbg_Str, "EOR%-5sD%.1d,%s%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), 0);
				}
				else
					//CMP.z  a,Dd
					sprintf(Dbg_Str, "CMP%-5s%s,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
			}
			break;

		case 12:

			if ((OPC & 0X1F8) == 0x100)
			{
				//ABCD Ds,Dd
				sprintf(Dbg_Str, "ABCD    D%.1d,D%.1d%c", OPC & 0x7, (OPC >> 9) & 0x7, 0);
				break;
			}

			if ((OPC & 0X1F8) == 0x140)
			{
				//EXG.l Ds,Dd
				sprintf(Dbg_Str, "EXG.L   D%.1d,D%.1d%c", OPC & 0x7, (OPC >> 9) & 0x7, 0);
				break;
			}

			if ((OPC & 0X1F8) == 0x108)
			{
				//ABCD -(As),-(Ad)
				sprintf(Dbg_Str, "ABCD    -(A%.1d),-(A%.1d)%c", OPC & 0x7, (OPC >> 9) & 0x7, 0);
				break;
			}

			if ((OPC & 0X1F8) == 0x148)
			{
				//EXG.l As,Ad
				sprintf(Dbg_Str, "EXG.L   A%.1d,A%.1d%c", OPC & 0x7, (OPC >> 9) & 0x7, 0);
				break;
			}

			if ((OPC & 0X1F8) == 0x188)
			{
				//EXG.l As,Dd
				sprintf(Dbg_Str, "EXG.L   A%.1d,D%.1d%c", OPC & 0x7, (OPC >> 9) & 0x7, 0);
				break;
			}

			switch((OPC	>> 6) & 0x7)
			{
				case 0: case 1: case 2:
					//AND.z  a,Dd
					sprintf(Dbg_Str, "AND%-5s%s,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
					break;

				case 3:
					//MULU.w  a,Dd
					sprintf(Dbg_Str, "MULU.W  %s,D%.1d%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
					break;

				case 4: case 5: case 6:
					//AND.z  Ds,a
					sprintf(Dbg_Str, "AND%-5sD%.1d,%s%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), 0);
					break;

				case 7:
					//MULS.w  a,Dd
					sprintf(Dbg_Str, "MULS.W  %s,D%.1d%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
					break;
			}
			break;

		case 13:

			if ((OPC & 0xC0) == 0xC0)
				//ADDA.z  a,Ad
				sprintf(Dbg_Str, "ADDA%-4s%s,A%.1d%c", Make_Dbg_Size_Str_2((OPC >> 8) & 1), Make_Dbg_EA_Str((OPC >> 8) & 1 + 1, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
			else
			{
				if (OPC & 0x100)
				{
					if (!(OPC & 0x38))
					{
						//ADDX.z  Ds,Dd
						sprintf(Dbg_Str, "ADDX%-4sD%.1d,D%.1d%c",	Make_Dbg_Size_Str((OPC >> 6) & 0x3), OPC & 0x7, (OPC >> 9) & 0x7, 0);
						break;
					}

					if ((OPC & 0x38) == 0x8)
					{
						//ADDX.z  -(As),-(Ad)
						sprintf(Dbg_Str, "ADDX%-4s-(A%.1d),-(A%.1d)%c",	Make_Dbg_Size_Str((OPC >> 6) & 0x3), OPC & 0x7, (OPC >> 9) & 0x7, 0);
						break;
					}

					//ADD.z  Ds,a
					sprintf(Dbg_Str, "ADD%-5sD%.1d,%s%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), 0);
				}
				else
					//ADD.z  a,Dd
					sprintf(Dbg_Str, "ADD%-5s%s,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), Make_Dbg_EA_Str((OPC >> 6) & 3, (OPC & 0x38) >> 3, OPC & 0x7), (OPC >> 9) & 0x7, 0);
			}
			break;

		case 14:

			if ((OPC & 0xC0) == 0xC0)
			{
				switch ((OPC >> 8) & 0x7)
				{
					case 0:
						//ASR.w  #1,a
						sprintf(Dbg_Str, "ASR.W   #1,%s%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;
	
					case 1:
						//ASL.w  #1,a
						sprintf(Dbg_Str, "ASL.W   #1,%s%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 2:
						//LSR.w  #1,a
						sprintf(Dbg_Str, "LSR.W   #1,%s%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 3:
						//LSL.w  #1,a
						sprintf(Dbg_Str, "LSL.W   #1,%s%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 4:
						//ROXR.w  #1,a
						sprintf(Dbg_Str, "ROXR.W  #1,%s%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 5:
						//ROXL.w  #1,a
						sprintf(Dbg_Str, "ROXL.W  #1,%s%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 6:
						//ROR.w  #1,a
						sprintf(Dbg_Str, "ROR.W   #1,%s%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;

					case 7:
						//ROL.w  #1,a
						sprintf(Dbg_Str, "ROL.W   #1,%s%c", Make_Dbg_EA_Str(1, (OPC & 0x38) >> 3, OPC & 0x7), 0);
						break;
 
				}
			}
			else
			{
				switch ((OPC >> 3) & 0x3F)
				{
					case 0: case 8: case 16:
						//ASR.z  #k,Dd
						sprintf(Dbg_Str, "ASR%-5s#%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 1: case 9: case 17:
						//LSR.z  #k,Dd
						sprintf(Dbg_Str, "LSR%-5s#%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 2: case 10: case 18:
						//ROXR.z  #k,Dd
						sprintf(Dbg_Str, "ROXR%-4s#%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 3: case 11: case 19:
						//ROR.z  #k,Dd
						sprintf(Dbg_Str, "ROR%-5s#%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 4: case 12: case 20:
						//ASR.z  Ds,Dd
						sprintf(Dbg_Str, "ASR%-5sD%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 5: case 13: case 21:
						//LSR.z  Ds,Dd
						sprintf(Dbg_Str, "LSR%-5sD%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 6: case 14: case 22:
						//ROXR.z  Ds,Dd
						sprintf(Dbg_Str, "ROXR%-4sD%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 7: case 15: case 23:
						//ROR.z  Ds,Dd
						sprintf(Dbg_Str, "ROR%-5sD%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 32: case 40: case 48:
						//ASL.z  #k,Dd
						sprintf(Dbg_Str, "ASL%-5s#%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 33: case 41: case 49:
						//LSL.z  #k,Dd
						sprintf(Dbg_Str, "LSL%-5s#%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 34: case 42: case 50:
						//ROXL.z  #k,Dd
						sprintf(Dbg_Str, "ROXL%-4s#%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 35: case 43: case 51:
						//ROL.z  #k,Dd
						sprintf(Dbg_Str, "ROL%-5s#%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 36: case 44: case 52:
						//ASL.z  Ds,Dd
						sprintf(Dbg_Str, "ASL%-5sD%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 37: case 45: case 53:
						//LSL.z  Ds,Dd
						sprintf(Dbg_Str, "LSL%-5sD%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 38: case 46: case 54:
						//ROXL.z  Ds,Dd
						sprintf(Dbg_Str, "ROXL%-4sD%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

					case 39: case 47: case 55:
						//ROL.z  Ds,Dd
						sprintf(Dbg_Str, "ROL%-5sD%.1d,D%.1d%c", Make_Dbg_Size_Str((OPC >> 6) & 0x3), (OPC >> 9) & 0x7, OPC & 0x7, 0);
						break;

				}
			}
			break;

		case 15:
			//Bad Opcode
			sprintf(Dbg_Str, "Bad Opcode%c", 0);
			break;
	}
	
	return(Dbg_Str);
}


