#include "emu.h"
#include "debugger.h"
#include "hd61700.h"

#define EXT_ROM		(pc > 0x0c00)
#define INC_POS		pos += (type+1)
#define POS			(pos + type)

static const char *const reg_5b[4] =  {"sx", "sy", "sz", "sz"};
static const char *const reg_8b[8] =  {"pe", "pd", "ib", "ua", "ia", "ie", "tm", "tm"};
static const char *const reg_16b[8] = {"ix", "iy", "iz", "us", "ss", "ky", "ky", "ky"};
static const char *const jp_cond[8] = {"z", "nc", "lz", "uz", "nz", "c", "nlz"};

enum
{
	OP_NULL=0,
	OP_IM16,
	OP_IM16A,
	OP_IM3,
	OP_IM5,
	OP_IM7,
	OP_IM8,
	OP_IM8I,
	OP_IM8_,
	OP_IR_IM3,
	OP_IR_IM8,
	OP_IR_IM8_,
	OP_JX_COND,
	OP_MREG,
	OP_MREG2,
	OP_MR_SIR,
	OP_MR_SIRI,
	OP_REG16,
	OP_REG16_,
	OP_REG8,
	OP_REG8_,
	OP_REGIM8,
	OP_RMSIM3,
	OP_RSIR,
};

typedef struct
{
	const char *str;
	UINT8		arg1;
	UINT8		arg2;
	bool		optjr;
} hd61700_dasm;

static const hd61700_dasm hd61700_ops[256] =
{
	// 0x00
	{ "adc",  OP_MREG,    OP_MR_SIR, 1 }, { "sbc",  OP_MREG,    OP_MR_SIR, 1 },
	{ "ld",   OP_MREG,    OP_MR_SIR, 1 }, { "illegal", OP_NULL, OP_NULL,   0 },
	{ "anc",  OP_MREG,    OP_MR_SIR, 1 }, { "nac",  OP_MREG,    OP_MR_SIR, 1 },
	{ "orc",  OP_MREG,    OP_MR_SIR, 1 }, { "xrc",  OP_MREG,    OP_MR_SIR, 1 },
	{ "ad",   OP_MREG,    OP_MR_SIR, 1 }, { "sb",   OP_MREG,    OP_MR_SIR, 1 },
	{ "adb",  OP_MREG,    OP_MR_SIR, 1 }, { "sbb",  OP_MREG,    OP_MR_SIR, 1 },
	{ "an",   OP_MREG,    OP_MR_SIR, 1 }, { "na",   OP_MREG,    OP_MR_SIR, 1 },
	{ "or",   OP_MREG,    OP_MR_SIR, 1 }, { "xr",   OP_MREG,    OP_MR_SIR, 1 },

	// 0x10
	{ "st",   OP_MREG,    OP_MR_SIRI,  1 }, { "ld",   OP_MREG,  OP_MR_SIRI,1 },
	{ "stl",  OP_MREG2,   OP_NULL,     1 }, { "ldl",  OP_MREG2, OP_NULL,   1 },
	{ "???",  OP_MREG2,   OP_NULL,     1 }, { "psr",  OP_RSIR,  OP_MREG2,  1 },
	{ "pst",  OP_REG8,   OP_MREG2,    1 }, { "pst",  OP_REG8, OP_MREG2,  1 },
	{ "???",  OP_MREG2,   OP_NULL,     1 }, { "illegal", OP_NULL, OP_NULL, 0 },
	{ "???",  OP_MREG2,   OP_NULL,     1 }, { "???",  OP_MREG2, OP_NULL,   1 },
	{ "???",  OP_MREG2,   OP_NULL,     1 }, { "gsr",  OP_RSIR,  OP_MREG2,  1 },
	{ "gst",  OP_REG8,   OP_MREG2,    1 }, { "gst",  OP_REG8, OP_MREG2,  1 },

	// 0x20
	{ "st",   OP_MREG,    OP_IR_IM8_,  0 }, { "st",   OP_MREG,  OP_IR_IM8_,0 },
	{ "sti",  OP_MREG,    OP_IR_IM8_,  0 }, { "sti",  OP_MREG,  OP_IR_IM8_,0 },
	{ "std",  OP_MREG,    OP_IR_IM8_,  0 }, { "std",  OP_MREG,  OP_IR_IM8_,0 },
	{ "phs",  OP_MREG2,   OP_NULL,     0 }, { "phu",  OP_MREG2, OP_NULL,   0 },
	{ "ld",   OP_MREG,    OP_IR_IM8_,  0 }, { "ld",   OP_MREG,  OP_IR_IM8_,0 },
	{ "ldi",  OP_MREG,    OP_IR_IM8_,  0 }, { "ldi",  OP_MREG,  OP_IR_IM8_,0 },
	{ "ldd",  OP_MREG,    OP_IR_IM8_,  0 }, { "ldd",  OP_MREG,  OP_IR_IM8_,0 },
	{ "pps",  OP_MREG2,   OP_NULL,     0 }, { "ppu",  OP_MREG2, OP_NULL,   0 },

	// 0x30
	{ "jp",   OP_JX_COND, OP_IM16A,   0 }, { "jp",   OP_JX_COND, OP_IM16A, 0 },
	{ "jp",   OP_JX_COND, OP_IM16A,   0 }, { "jp",   OP_JX_COND, OP_IM16A, 0 },
	{ "jp",   OP_JX_COND, OP_IM16A,   0 }, { "jp",   OP_JX_COND, OP_IM16A, 0 },
	{ "jp",   OP_JX_COND, OP_IM16A,   0 }, { "jp",   OP_IM16A,   OP_NULL,  0 },
	{ "adc",  OP_IR_IM8, OP_MREG2,   0 }, { "adc",  OP_IR_IM8, OP_MREG2, 0 },
	{ "sbc",  OP_IR_IM8, OP_MREG2,   0 }, { "sbc",  OP_IR_IM8, OP_MREG2, 0 },
	{ "ad",   OP_IR_IM8, OP_MREG2,   0 }, { "ad",   OP_IR_IM8, OP_MREG2, 0 },
	{ "sb",   OP_IR_IM8, OP_MREG2,   0 }, { "sb",   OP_IR_IM8, OP_MREG2, 0 },

	// 0x40
	{ "adc",  OP_MREG2,    OP_IM8,     1 }, { "sbc",  OP_MREG2,    OP_IM8, 1 },
	{ "ld",   OP_MREG2,    OP_IM8,     1 }, { "illegal", OP_NULL, OP_NULL, 0 },
	{ "anc",  OP_MREG2,    OP_IM8,     1 }, { "nac",  OP_MREG2,    OP_IM8, 1 },
	{ "orc",  OP_MREG2,    OP_IM8,     1 }, { "xrc",  OP_MREG2,    OP_IM8, 1 },
	{ "ad",   OP_MREG2,    OP_IM8,     1 }, { "sb",   OP_MREG2,    OP_IM8, 1 },
	{ "adb",  OP_MREG2,    OP_IM8,     1 }, { "sbb",  OP_MREG2,    OP_IM8, 1 },
	{ "an",   OP_MREG2,    OP_IM8,     1 }, { "na",   OP_MREG2,    OP_IM8, 1 },
	{ "or",   OP_MREG2,    OP_IM8,     1 }, { "xr",   OP_MREG2,    OP_IM8, 1 },

	// 0x50
	{ "st",   OP_IM8I,    OP_MREG2,  0 }, { "st",    OP_IM8,      OP_MREG2,0 },
	{ "stl",  OP_IM8_,    OP_NULL,   0 }, { "illegal", OP_NULL,   OP_NULL, 0 },
	{ "???",  OP_IM8_,    OP_NULL,   0 }, { "psr",   OP_RSIR,     OP_IM5,  0 },
	{ "pst",  OP_REG8_,   OP_IM8,    0 }, { "pst",   OP_REG8_,    OP_IM8,  0 },
	{ "bups", OP_IM8_,    OP_NULL,   0 }, { "bdns",  OP_IM8_,     OP_NULL, 0 },
	{ "illegal", OP_NULL, OP_NULL,   0 }, { "illegal", OP_NULL,   OP_NULL, 0 },
	{ "sup",  OP_IM8_,    OP_NULL,   0 }, { "sdn",   OP_IM8_,     OP_NULL, 0 },
	{ "illegal", OP_NULL, OP_NULL,   0 }, { "illegal", OP_NULL,   OP_NULL, 0 },

	// 0x60
	{ "st",   OP_MREG2,    OP_REGIM8, 0 }, { "st",   OP_MREG2,   OP_REGIM8, 0 },
	{ "sti",  OP_MREG2,    OP_REGIM8, 0 }, { "sti",  OP_MREG2,   OP_REGIM8, 0 },
	{ "std",  OP_MREG2,    OP_REGIM8, 0 }, { "std",  OP_MREG2,   OP_REGIM8, 0 },
	{ "illegal", OP_NULL,  OP_NULL,   0 }, { "illegal", OP_NULL, OP_NULL,   0 },
	{ "ld",   OP_MREG2,    OP_REGIM8, 0 }, { "ld",   OP_MREG2,   OP_REGIM8, 0 },
	{ "ldi",  OP_MREG2,    OP_REGIM8, 0 }, { "ldi",  OP_MREG2,   OP_REGIM8, 0 },
	{ "ldd",  OP_MREG2,    OP_REGIM8, 0 }, { "ldd",  OP_MREG2,   OP_REGIM8, 0 },
	{ "illegal", OP_NULL,  OP_NULL,   0 }, { "illegal", OP_NULL, OP_NULL,   0 },

	// 0x70
	{ "cal",  OP_JX_COND,  OP_IM16A,  0 }, { "cal",  OP_JX_COND, OP_IM16A,  0 },
	{ "cal",  OP_JX_COND,  OP_IM16A,  0 }, { "cal",  OP_JX_COND, OP_IM16A,  0 },
	{ "cal",  OP_JX_COND,  OP_IM16A,  0 }, { "cal",  OP_JX_COND, OP_IM16A,  0 },
	{ "cal",  OP_JX_COND,  OP_IM16A,  0 }, { "cal",  OP_IM16A,   OP_NULL,   0 },
	{ "adc",  OP_REGIM8,   OP_MREG2,  0 }, { "adc",  OP_REGIM8,  OP_MREG2,  0 },
	{ "sbc",  OP_REGIM8,   OP_MREG2,  0 }, { "sbc",  OP_REGIM8,  OP_MREG2,  0 },
	{ "ad",   OP_REGIM8,   OP_MREG2,  0 }, { "ad ",  OP_REGIM8,  OP_MREG2,  0 },
	{ "sb",   OP_REGIM8,   OP_MREG2,  0 }, { "sb",   OP_REGIM8,  OP_MREG2,  0 },

	// 0x80
	{ "adcw", OP_MREG,    OP_MR_SIR, 1 }, { "sbcw", OP_MREG,    OP_MR_SIR, 1 },
	{ "ldw",  OP_MREG,    OP_MR_SIR, 1 }, { "illegal", OP_NULL, OP_NULL,   0 },
	{ "ancw", OP_MREG,    OP_MR_SIR, 1 }, { "nacw", OP_MREG,    OP_MR_SIR, 1 },
	{ "orcw", OP_MREG,    OP_MR_SIR, 1 }, { "xrcw", OP_MREG,    OP_MR_SIR, 1 },
	{ "adw",  OP_MREG,    OP_MR_SIR, 1 }, { "sbw",  OP_MREG,    OP_MR_SIR, 1 },
	{ "adbw", OP_MREG,    OP_MR_SIR, 1 }, { "sbbw", OP_MREG,    OP_MR_SIR, 1 },
	{ "anw",  OP_MREG,    OP_MR_SIR, 1 }, { "naw",  OP_MREG,    OP_MR_SIR, 1 },
	{ "orw",  OP_MREG,    OP_MR_SIR, 1 }, { "xrw",  OP_MREG,    OP_MR_SIR, 1 },

	// 0x90
	{ "stw",  OP_MREG,    OP_MR_SIRI,1 }, { "ldw",  OP_MREG,    OP_MR_SIRI,1 },
	{ "stlw", OP_MREG2,   OP_NULL,   1 }, { "ldlw", OP_MREG2,   OP_NULL,   1 },
	{ "illegal", OP_NULL, OP_NULL,   0 }, { "illegal", OP_NULL, OP_NULL,   0 },
	{ "pre",  OP_REG16,   OP_MREG2,  1 }, { "pre",  OP_REG16,   OP_MREG2,  1 },
	{ "???",  OP_MREG2,   OP_NULL,   1 }, { "illegal", OP_NULL, OP_NULL,   0 },
	{ "???",  OP_MREG2,   OP_NULL,   1 }, { "???",  OP_MREG2,   OP_NULL,   1 },
	{ "???",  OP_MREG2,   OP_NULL,   1 }, { "illegal", OP_NULL, OP_NULL,   0 },
	{ "gre",  OP_REG16,   OP_MREG2,  1 }, { "gre",  OP_REG16,   OP_MREG2,  1 },

	// 0xa0
	{ "stw",  OP_MREG,   OP_IR_IM8_, 0 }, { "stw",  OP_MREG,   OP_IR_IM8_, 0 },
	{ "stiw", OP_MREG,   OP_IR_IM8_, 0 }, { "stiw", OP_MREG,   OP_IR_IM8_, 0 },
	{ "stdw", OP_MREG,   OP_IR_IM8_, 0 }, { "stdw", OP_MREG,   OP_IR_IM8_, 0 },
	{ "phsw", OP_MREG2,  OP_NULL,    0 }, { "phuw", OP_MREG2,  OP_NULL,    0 },
	{ "ldw",  OP_MREG,   OP_IR_IM8_, 0 }, { "ldw",  OP_MREG,   OP_IR_IM8_, 0 },
	{ "ldiw", OP_MREG,   OP_IR_IM8_, 0 }, { "ldiw", OP_MREG,   OP_IR_IM8_, 0 },
	{ "lddw", OP_MREG,   OP_IR_IM8_, 0 }, { "lddw", OP_MREG,   OP_IR_IM8_, 0 },
	{ "ppsw", OP_MREG2,  OP_NULL,    0 }, { "ppuw", OP_MREG2,  OP_NULL,    0 },

	// 0xb0
	{ "jr",   OP_JX_COND, OP_IM7,    0 }, { "jr",   OP_JX_COND, OP_IM7,    0 },
	{ "jr",   OP_JX_COND, OP_IM7,    0 }, { "jr",   OP_JX_COND, OP_IM7,    0 },
	{ "jr",   OP_JX_COND, OP_IM7,    0 }, { "jr",   OP_JX_COND, OP_IM7,    0 },
	{ "jr",   OP_JX_COND, OP_IM7,    0 }, { "jr",   OP_IM7,     OP_NULL,   0 },
	{ "adcw", OP_IR_IM8, OP_MREG,   0 }, { "adcw", OP_IR_IM8, OP_MREG,   0 },
	{ "sbcw", OP_IR_IM8, OP_MREG,   0 }, { "sbcw", OP_IR_IM8, OP_MREG,   0 },
	{ "adw",  OP_IR_IM8, OP_MREG,   0 }, { "adw",  OP_IR_IM8, OP_MREG,   0 },
	{ "sbw",  OP_IR_IM8, OP_MREG,   0 }, { "sbw",  OP_IR_IM8, OP_MREG,   0 },

	// 0xc0
	{ "adbcm",OP_MREG,    OP_RMSIM3, 1 }, { "sdbcm",OP_MREG,    OP_RMSIM3, 1 },
	{ "ldm",  OP_MREG,    OP_RMSIM3, 1 }, { "illegal", OP_NULL, OP_NULL,   0 },
	{ "ancm", OP_MREG,    OP_RMSIM3, 1 }, { "nacm", OP_MREG,    OP_RMSIM3, 1 },
	{ "orcm", OP_MREG,    OP_RMSIM3, 1 }, { "xrcm", OP_MREG,    OP_RMSIM3, 1 },
	{ "adbm", OP_MREG,    OP_RMSIM3, 1 }, { "sbbm", OP_MREG,    OP_RMSIM3, 1 },
	{ "adbm", OP_MREG,    OP_RMSIM3, 1 }, { "sbbm", OP_MREG,    OP_RMSIM3, 1 },
	{ "anm",  OP_MREG,    OP_RMSIM3, 1 }, { "nam",  OP_MREG,    OP_RMSIM3, 1 },
	{ "orm",  OP_MREG,    OP_RMSIM3, 1 }, { "xrm",  OP_MREG,    OP_RMSIM3, 1 },

	// 0xd0
	{ "stw",  OP_IM16,    OP_MR_SIR, 0 }, { "ldw",  OP_MREG2,   OP_IM16,   0 },
	{ "stlm", OP_MREG2,   OP_IM3,    0 }, { "ldlm", OP_MREG2,   OP_IM3,    0 },
	{ "illegal", OP_NULL, OP_NULL,   0 }, { "illegal", OP_NULL, OP_NULL,   0 },
	{ "pre",  OP_REG16_,  OP_IM16,   0 }, { "pre",  OP_REG16_,  OP_IM16,   0 },
	{ "bup",  OP_NULL,    OP_NULL,   0 }, { "bnd",  OP_NULL,    OP_NULL,   0 },
	{ "???",  OP_MREG2,   OP_IM3,    0 }, { "???",  OP_MREG2,   OP_IM3,    0 },
	{ "sup",  OP_MREG,    OP_NULL,   0 }, { "sdn",  OP_MREG,    OP_NULL,   0 },
	{ "jp",   OP_MREG,    OP_NULL,   0 }, { "jp",   OP_MREG,    OP_NULL,   0 },

	// 0xe0
	{ "stm",  OP_MREG,  OP_IR_IM3,   0 }, { "stm",  OP_MREG,    OP_IR_IM3, 0 },
	{ "stim", OP_MREG,  OP_IR_IM3,   0 }, { "stim", OP_MREG,    OP_IR_IM3, 0 },
	{ "stdm", OP_MREG,  OP_IR_IM3,   0 }, { "stdm", OP_MREG,    OP_IR_IM3, 0 },
	{ "phsm", OP_MREG2, OP_IM3,      0 }, { "phum", OP_MREG2,   OP_IM3,    0 },
	{ "ldm",  OP_MREG,  OP_IR_IM3,   0 }, { "ldm",  OP_MREG,    OP_IR_IM3, 0 },
	{ "ldim", OP_MREG,  OP_IR_IM3,   0 }, { "ldim", OP_MREG,    OP_IR_IM3, 0 },
	{ "lddm", OP_MREG,  OP_IR_IM3,   0 }, { "lddm", OP_MREG,    OP_IR_IM3, 0 },
	{ "ppsm", OP_MREG2, OP_IM3,      0 }, { "ppum", OP_MREG2,   OP_IM3,    0 },

	// 0xf0
	{ "rtn",  OP_JX_COND, OP_NULL,   0 }, { "rtn",  OP_JX_COND, OP_NULL,   0 },
	{ "rtn",  OP_JX_COND, OP_NULL,   0 }, { "rtn",  OP_JX_COND, OP_NULL,   0 },
	{ "rtn",  OP_JX_COND, OP_NULL,   0 }, { "rtn",  OP_JX_COND, OP_NULL,   0 },
	{ "rtn",  OP_JX_COND, OP_NULL,   0 }, { "rtn",  OP_NULL,    OP_NULL,   0 },
	{ "nop",  OP_JX_COND, OP_NULL,   0 }, { "clt",  OP_NULL,    OP_NULL,   0 },
	{ "fst",  OP_NULL,    OP_NULL,   0 }, { "slw",  OP_NULL,    OP_NULL,   0 },
	{ "can",  OP_NULL,    OP_NULL,   0 }, { "rtni", OP_NULL,    OP_NULL,   0 },
	{ "off",  OP_NULL,    OP_NULL,   0 }, { "trp",  OP_NULL,    OP_NULL,   0 },
};


inline int dasm_im8(char *buffer, UINT16 pc, int arg, const UINT8 *oprom, int &pos, int type)
{
	if (((arg>>5) & 0x03) == 0x03)
	{
		INC_POS;
		UINT8 ret = sprintf( buffer, "0x%02x", oprom[POS] & 0x1f );
		return ret;
	}
	else
	{
		return sprintf( buffer, "%s", reg_5b[(arg>>5) & 0x03] );
	}
}


inline int dasm_im8(char *buffer, UINT16 pc, int arg, int arg1, const UINT8 *oprom, int &pos)
{
	if (((arg>>5) & 0x03) == 0x03)
	{
		return sprintf( buffer, "0x%02x", arg1 & 0x1f );
	}
	else
	{
		return sprintf( buffer, "%s", reg_5b[(arg>>5) & 0x03] );
	}
}


int dasm_arg(char *buffer, UINT8 op, UINT16 pc, int arg, const UINT8 *oprom, int &pos)
{
	char* buffer_start = buffer;
	int type = EXT_ROM;

	switch( arg )
	{
		case OP_MREG:
		case OP_MREG2:
			buffer += sprintf( buffer, "$%02u", oprom[POS] & 0x1f );
			if (arg == OP_MREG2) INC_POS;
			break;

		case OP_RSIR:
			buffer += sprintf( buffer, "%s", reg_5b[(oprom[POS]>>5) & 0x03] );
			break;

		case OP_REG8:
		case OP_REG8_:
			buffer += sprintf( buffer, "%s", reg_8b[(BIT(op,0)<<2) + ((oprom[POS]>>5&3))]);
			if (arg == OP_REG8_) INC_POS;
			break;

		case OP_MR_SIR:
			buffer += dasm_im8(buffer, pc, oprom[POS], oprom, pos, type);
			INC_POS;
			break;

		case OP_IR_IM8:
		case OP_IR_IM8_:
			buffer += sprintf( buffer, "(%s%s", (op&1) ? "iz": "ix", (oprom[POS]&0x80) ? "-": "+");
			buffer += dasm_im8(buffer, pc, oprom[POS], oprom, pos, type);
			buffer += sprintf( buffer, ")");
			if (arg == OP_IR_IM8_) INC_POS;
			break;

		case OP_IM8_:
			INC_POS;
		case OP_IM8:
			buffer += sprintf( buffer, "0x%02x", oprom[POS] );
			INC_POS;
			break;

		case OP_IM8I:
			buffer += sprintf( buffer, "(0x%02x)", oprom[POS] );
			INC_POS;
			break;

		case OP_REGIM8:
			buffer += sprintf( buffer, "(%s%s", (op&1) ? "iz": "ix", (oprom[POS]&0x80) ? "-": "+");
			buffer += sprintf( buffer, "%x)", oprom[POS] & 0x1f);
			INC_POS;
			break;

		case OP_JX_COND:
			buffer += sprintf( buffer, "%s", jp_cond[op & 0x07] );
			break;


		case OP_RMSIM3:
			{
				UINT8 tmp = oprom[POS];
				INC_POS;
				buffer += dasm_im8(buffer, pc, tmp, oprom[POS], oprom, pos);
				buffer += sprintf( buffer, ", 0x%02x", ((tmp>>5)&7)+1);
				INC_POS;
			}
			break;

		case OP_IR_IM3:
			{
				UINT8 tmp = oprom[POS];
				INC_POS;
				buffer += sprintf( buffer, "(%s%s", (op&1) ? "iz": "ix", (tmp&0x80) ? "-": "+");
				buffer += dasm_im8(buffer, pc, tmp, oprom[POS], oprom, pos);
				buffer += sprintf( buffer, "), 0x%02x", ((oprom[POS]>>5)&7)+1 );
				INC_POS;
			}
			break;

		case OP_IM3:
			buffer += sprintf( buffer, "0x%02x", ((oprom[POS]>>5)&7)+1 );
			INC_POS;
			break;

		case OP_MR_SIRI:
			buffer += sprintf( buffer, "(");
			buffer += dasm_im8(buffer, pc, oprom[POS], oprom, pos, type);
			buffer += sprintf( buffer, ")");
			INC_POS;
			break;

		case OP_IM7:
			{
				int tmp = oprom[POS];
				if (tmp&0x80)		tmp = 0x80 - tmp;

				buffer += sprintf( buffer, "0x%04x", (pc + tmp + EXT_ROM) & 0xffff );
				INC_POS;
			}
			break;

		case OP_IM5:
			buffer += sprintf( buffer, "0x%02x", oprom[POS]&0x1f );
			INC_POS;
			break;

		case OP_REG16:
		case OP_REG16_:
			buffer += sprintf( buffer, "%s", reg_16b[(BIT(op,0)<<2) + ((oprom[POS]>>5&3))]);
			if (arg == OP_REG16_) INC_POS;
			break;

		case OP_IM16:
		case OP_IM16A:
			{
				UINT8 tmp1 = oprom[POS];
				INC_POS;
				if (!EXT_ROM && arg == OP_IM16A)	INC_POS;
				UINT8 tmp2 = oprom[POS];
				buffer += sprintf( buffer, "0x%04x", ((tmp2<<8) | tmp1));
				INC_POS;
			}
			break;

		case OP_NULL:
			break;
	}

	return buffer - buffer_start;
}

UINT32 get_dasmflags(UINT8 op)
{
	switch (op)
	{
		case 0x30: case 0x31: case 0x32: case 0x33:	//jp
		case 0x34: case 0x35: case 0x36: case 0x37:	//jp
		case 0x70: case 0x71: case 0x72: case 0x73:	//cal
		case 0x74: case 0x75: case 0x76: case 0x77:	//cal
		case 0xb0: case 0xb1: case 0xb2: case 0xb3:	//jr
		case 0xb4: case 0xb5: case 0xb6: case 0xb7:	//jr
		case 0xde:									//jp
		case 0xdf:									//jp
			return DASMFLAG_STEP_OVER;
		case 0xf0: case 0xf1: case 0xf2: case 0xf3:	//rtn
		case 0xf4: case 0xf5: case 0xf6: case 0xf7:	//rtn
		case 0xfd:									//rtni
			return DASMFLAG_STEP_OUT;
	}

	return 0;
}


CPU_DISASSEMBLE( hd61700 )
{
	const hd61700_dasm *inst;
	UINT32 dasmflags = 0;
	UINT8 op, op1;
	int pos = 0, type = EXT_ROM;

	op = oprom[POS];
	INC_POS;

	dasmflags = get_dasmflags(op);

	op1 = oprom[POS];

	inst = &hd61700_ops[op];

	buffer += sprintf(buffer,"%-8s", inst->str);

	//dasm first arg
	buffer += dasm_arg(buffer, op, pc, inst->arg1, oprom, pos);

	//if present dasm second arg
	if (inst->arg2 != OP_NULL)
	{
		buffer += sprintf(buffer,", ");
		buffer += dasm_arg(buffer, op, pc, inst->arg2, oprom, pos);
	}

	//if required add the optional jr
	if (inst->optjr == true && BIT(op1, 7))
	{
		buffer += sprintf( buffer, ", jr ");
		buffer += dasm_arg(buffer, op, pc+1, OP_IM7, oprom, pos);

		dasmflags = DASMFLAG_STEP_OVER;
	}

	if (pos&1) INC_POS;

	return (pos>>1) | dasmflags | DASMFLAG_SUPPORTED;
}
