/**************************************************************************
 *               National Semiconductor COP420 Emulator                   *
 *                                                                        *
 *                   Copyright (C) 2006 MAME Team                         *
 **************************************************************************/

#include <stdio.h>
#include "cpuintrf.h"

int DasmCOP420(char *buffer, unsigned pc)
{
	int op;
	int cnt = 1;
	UINT16 addr;
	UINT8 op2;
//	UINT32 flags = 0;
	UINT8 oprom[2];

	op = cpu_readop(pc);
  oprom[0] = op;
  oprom[1] = cpu_readop_arg(pc+1);

	if ((op >= 0x80 && op <= 0xBE) || (op >= 0xC0 && op <= 0xFE))
	{
		int page = pc >> 6;

		if (page == 2 || page == 3) //JP pages 2,3
		{
			addr = (UINT16)((pc & 0x380) | (op & 0x7F));
			sprintf(buffer,"JP %03x",addr);
		}
		else
		{
			if ((op & 0xC0) == 0xC0) //JP other pages
			{
				addr = (UINT16)((pc & 0x3C0) | (op & 0x3F));
				sprintf(buffer,"JP %03x",addr);
			}
			else					//JSRP
			{
				addr = (UINT16)(0x80 | (op & 0x3F));
				sprintf(buffer,"JSRP %03x",addr);
//				flags = DASMFLAG_STEP_OVER;
			}
		}
	}
	else if (op >= 0x08 && op <= 0x0F)
	{
		sprintf(buffer,"LBI 0%x",((op & 0xF) + 1) & 0xF);
	}
	else if (op >= 0x18 && op <= 0x1F)
	{
		sprintf(buffer,"LBI 1%x",((op & 0xF) + 1) & 0xF);
	}
	else if (op >= 0x28 && op <= 0x2F)
	{
		sprintf(buffer,"LBI 2%x",((op & 0xF) + 1) & 0xF);
	}
	else if (op >= 0x38 && op <= 0x3F)
	{
		sprintf(buffer,"LBI 3%x",((op & 0xF) + 1) & 0xF);
	}
	else if (op >= 0x51 && op <= 0x5F)
	{
		sprintf(buffer,"AISC %x",op & 0xF);
	}
	else if (op >= 0x60 && op <= 0x63)
	{
		addr = ((op & 0x03) << 8) | oprom[1];
		sprintf(buffer,"JMP %03x",addr);
		cnt = 2;
	}
	else if (op >= 0x68 && op <= 0x6B)
	{
		addr = ((op & 0x03) << 8) | oprom[1];
		sprintf(buffer,"JSR %03x",addr);
//		flags = DASMFLAG_STEP_OVER;
		cnt = 2;
	}
	else if (op >= 0x70 && op <= 0x7F)
	{
		sprintf(buffer,"STII %x",op & 0xF);
	}
	else
	{
		switch (op)
		{
		case 0:
			sprintf(buffer,"CLRA");
			break;

		case 1:
			sprintf(buffer,"SKMBZ 0");
			break;

		case 2:
			sprintf(buffer,"XOR");
			break;

		case 3:
			sprintf(buffer,"SKMBZ 2");
			break;

		case 4:
			sprintf(buffer,"XIS 0");
			break;

		case 5:
			sprintf(buffer,"LD 0");
			break;

		case 6:
			sprintf(buffer,"X 0");
			break;

		case 7:
			sprintf(buffer,"XDS 0");
			break;

		case 0x10:
			sprintf(buffer,"CASC");
			break;

		case 0x11:
			sprintf(buffer,"SKMBZ 1");
			break;

		case 0x12:
			sprintf(buffer,"XABR");
			break;

		case 0x13:
			sprintf(buffer,"SKMBZ 3");
			break;

		case 0x14:
			sprintf(buffer,"XIS 1");
			break;

		case 0x15:
			sprintf(buffer,"LD 1");
			break;

		case 0x16:
			sprintf(buffer,"X 1");
			break;

		case 0x17:
			sprintf(buffer,"XDS 1");
			break;

		case 0x20:
			sprintf(buffer,"SKC");
			break;

		case 0x21:
			sprintf(buffer,"SKE");
			break;

		case 0x22:
			sprintf(buffer,"SC");
			break;

		case 0x23:
			addr = (UINT16)(oprom[1] & 0x3F);
			sprintf(buffer, ((oprom[1] & 0x80) ? "XAD %02x" : "LDD %02x"), addr);
			cnt = 2;
			break;

		case 0x24:
			sprintf(buffer,"XIS 2");
			break;

		case 0x25:
			sprintf(buffer,"LD 2");
			break;

		case 0x26:
			sprintf(buffer,"X 2");
			break;

		case 0x27:
			sprintf(buffer,"XDS 2");
			break;

		case 0x30:
			sprintf(buffer,"ASC");
			break;

		case 0x31:
			sprintf(buffer,"ADD");
			break;

		case 0x32:
			sprintf(buffer,"RC");
			break;

		case 0x33:
			op2 = oprom[1];
			cnt = 2;

			if (op2 >= 0x50 && op2 <= 0x5F)
			{
				sprintf(buffer,"OGI %x",op2 & 0xF);
			}
			else if (op2 >= 0x60 && op2 <= 0x6F)
			{
				sprintf(buffer,"LEI %x",op2 & 0xF);
			}
			else if (op2 >= 0x81 && op2 <= 0x88)
			{
				sprintf(buffer,"LBI 0%x",op2 & 0xF);
			}
			else if (op2 >= 0x91 && op2 <= 0x98)
			{
				sprintf(buffer,"LBI 1%x",op2 & 0xF);
			}
			else if (op2 >= 0xA1 && op2 <= 0xA8)
			{
				sprintf(buffer,"LBI 2,%x",op2 & 0xF);
			}
			else if (op2 >= 0xB1 && op2 <= 0xB8)
			{
				sprintf(buffer,"LBI 3%x",op2 & 0xF);
			}
			else
			{
				switch (op2)
				{
				case 0x00:
					sprintf(buffer,"INIL");
					break;

				case 0x01:
					sprintf(buffer,"SKGBZ 0");
					break;

				case 0x03:
					sprintf(buffer,"SKGBZ 2");
					break;

				case 0x11:
					sprintf(buffer,"SKGBZ 1");
					break;

				case 0x13:
					sprintf(buffer,"SKGBZ 3");
					break;

				case 0x21:
					sprintf(buffer,"SKGZ");
					break;

				case 0x28:
					sprintf(buffer,"ININ");
					break;

				case 0x2A:
					sprintf(buffer,"ING");
					break;

				case 0x2C:
					sprintf(buffer,"COMA");
					break;

				case 0x2E:
					sprintf(buffer,"INL");
					break;

				case 0x3A:
					sprintf(buffer,"OMG");
					break;

				case 0x3C:
					sprintf(buffer,"CAMQ");
					break;

				case 0x3E:
					sprintf(buffer,"OBD");
					break;

				default:
					sprintf(buffer,"Invalid");
					break;
				}
			}
			break;

		case 0x34:
			sprintf(buffer,"XIS 3");
			break;

		case 0x35:
			sprintf(buffer,"LD 3");
			break;

		case 0x36:
			sprintf(buffer,"X 3");
			break;

		case 0x37:
			sprintf(buffer,"XDS 3");
			break;

		case 0x40:
			sprintf(buffer,"COMP");
			break;

		case 0x41:
			sprintf(buffer,"SKT");
			break;

		case 0x42:
			sprintf(buffer,"RMB 2");
			break;

		case 0x43:
			sprintf(buffer,"RMB 3");
			break;

		case 0x44:
			sprintf(buffer,"NOP");
			break;

		case 0x45:
			sprintf(buffer,"RMB 1");
			break;

		case 0x46:
			sprintf(buffer,"SMB 2");
			break;

		case 0x47:
			sprintf(buffer,"SMB 1");
			break;

		case 0x48:
			sprintf(buffer,"RET");
//			flags = DASMFLAG_STEP_OUT;
			break;

		case 0x49:
			sprintf(buffer,"RETSK");
//			flags = DASMFLAG_STEP_OUT;
			break;

		case 0x4A:
			sprintf(buffer,"ADT");
			break;

		case 0x4B:
			sprintf(buffer,"SMB 3");
			break;

		case 0x4C:
			sprintf(buffer,"RMB 0");
			break;

		case 0x4D:
			sprintf(buffer,"SMB 0");
			break;

		case 0x4E:
			sprintf(buffer,"CBA");
			break;

		case 0x4F:
			sprintf(buffer,"XAS");
			break;

		case 0x50:
			sprintf(buffer,"CAB");
			break;

		case 0xBF:
			sprintf(buffer,"LQID");
			break;

		case 0xFF:
			sprintf(buffer,"JID");
			break;

		default:
			sprintf(buffer,"Invalid");
			break;
		}
	}

	return cnt /*| flags | DASMFLAG_SUPPORTED*/;
}
