#include "stdafx.h"
#include "Debugger.h"

#include "vm1.h"

CDebugger::CDebugger()
	: m_pCPUObj(nullptr)
	, m_bDisAsmLog(true)
	, m_nPrintPosition(0)
	, m_nStartDisasm(0)
{
	m_DisLog = fopen("_Disasm_log.txt", "wt");
}

//!!!TODO: необходимо сделать карту памяти для БК11М
#define GET_WORD(a) (*(uint16_t *)&aMemory[a])
#define GET_BYTE(a) aMemory[a]

#define SET_WORD(a, v) (*(uint16_t *)&aMemory[a] = (v))
#define SET_BYTE(a, v) (aMemory[a] = (v))


CDebugger::~CDebugger()
{
	fclose(m_DisLog);
}

bool CDebugger::SnapRON()
{
	//кажись подобрал вариант, когда получается правильное дизассемблирование
	if (m_pCPUObj->reg.tplmz & (1 << 1 | 1 << 3))
	{
		if (++m_nStartDisasm == 1) //делать только один раз
		{
			for (int i = 0; i < 8; ++i)
			{
				m_Reg[i] = LOWORD(m_pCPUObj->reg.gpr[i]);
			}

			m_PSW = LOWORD(m_pCPUObj->reg.gpr[14]);
			return true;
		}
	}
	else
	{
		m_nStartDisasm = 0;
	}

	return false;
}

uint16_t CDebugger::GetRegister(VM1REGS nRegNum)
{
	ASSERT(m_pCPUObj);

	if (nRegNum < PSW)
	{
		return m_pCPUObj->reg.gpr[nRegNum];
	}
	else
	{
		switch (nRegNum)
		{
			case PSW:
				return m_pCPUObj->reg.gpr[14];

			case Q:
				return m_pCPUObj->reg.gpr[15];

			case A:
				return m_pCPUObj->reg.areg;

			case IR:
				return m_pCPUObj->reg.ir;

			case X:
				return m_pCPUObj->wire.x;

			case Y:
				return m_pCPUObj->wire.y;
		}
	}

	return 0;
}


VM1_QBUS_WIRES *CDebugger::GetWires()
{
	return &m_pCPUObj->wire;
}
VM1_QBUS_REGS *CDebugger::GetRegs()
{
	return &m_pCPUObj->reg;
}

uint16_t CDebugger::GetDebugMemDumpWord(uint16_t addr)
{
	return GET_WORD(addr);
}
uint8_t CDebugger::GetDebugMemDumpByte(uint16_t addr)
{
	return GET_BYTE(addr);
}

BOOL CDebugger::OnDebugModify_Memory(int nAddress, uint16_t nValue)
{
	SET_WORD(nAddress, nValue);
	return TRUE;
}

BOOL CDebugger::OnDebugModify_Memory(int nAddress, uint8_t nValue)
{
	SET_BYTE(nAddress, nValue);
	return TRUE;
}


//
//	Потоковый дизассемблер для эмулятора CPU типа 1801ВМ1
//
//	Использует глобальные переменные:
//
//          m_Reg[7]     - счётчик команд
//          m_PSW        - слово состояния CPU
//          aMemory      - массив 64К байтов памяти
//          abReadAccess - массив 64К признаков возможности чтения для байтов памяти ( true - есть память, false - нет памяти )
//          m_Reg        - массив регистров процессора
//
//	Вызов:          DisAsm( PC );  // Дизассемблирует текущую инструкцию.
//
#pragma warning(disable:4996)

////////////////////////////////////


void CDebugger::DisAsmPrint(char *str)
{
	m_nPrintPosition += strlen(str);
#ifdef EM_LOG

	if (m_bDisAsmLog)
	{
		EM_LOG(str);
	}
	else
#endif
	{
		//DisasmOut(str);
	}
}

void CDebugger::SkipPrintToOperandPosition()
{
	if (m_bDisAsmLog)
	{
		while (m_nPrintPosition < 6)
		{
			DisAsmPrint(" ");
		}
	}
	else
	{
		DisAsmPrint(" ");
	}

	memset(m_nR_Operand, -1, sizeof(m_nR_Operand));
}

void CDebugger::SkipPrintToCommentsPosition()
{
	if (m_bDisAsmLog)
	{
		while (m_nPrintPosition < 28)
		{
			DisAsmPrint(" ");
		}
	}
	else
	{
		while (m_nPrintPosition < 31)
		{
			DisAsmPrint(" ");
		}
	}
}

void CDebugger::PrintPSW(char *str)
{
	char str1[8];

	if (m_PSW & 0340)
	{
		str1[0] = 'P';
	}
	else
	{
		str1[0] = '.';
	}

	if (m_PSW & 16)
	{
		str1[1] = 'T';
	}
	else
	{
		str1[1] = '-';
	}

	if (m_PSW & 8)
	{
		str1[2] = 'N';
	}
	else
	{
		str1[2] = '-';
	}

	if (m_PSW & 4)
	{
		str1[3] = 'Z';
	}
	else
	{
		str1[3] = '-';
	}

	if (m_PSW & 2)
	{
		str1[4] = 'V';
	}
	else
	{
		str1[4] = '-';
	}

	if (m_PSW & 1)
	{
		str1[5] = 'C';
	}
	else
	{
		str1[5] = '-';
	}

	str1[6] = 0;
	sprintf(str, ";   PSW : %s", str1);
}

int CDebugger::PrintOperand(uint8_t nOpMode, int nOpSize)
{
	int nReg = nOpMode & 07;
	int nMode = (nOpMode & 070) >> 3;
	uint16_t nOffset;
	uint16_t wAddr;
	int nOppAddr = 0;
	bool bByteMode = (nOpSize - 1) ? false : true;
	char str[128];
	static char acReg[16];

	if (nReg <= 5)
	{
		sprintf(acReg, "R%u", nReg);
	}
	else
	{
		switch (nReg)
		{
			case 6:
				sprintf(acReg, "SP");
				nOpSize = 2;
				break;

			case 7:
				sprintf(acReg, "PC");
				nOpSize = 2;
				break;
		}
	}

	switch (nMode)
	{
		case 00:
		{
			sprintf(str, "%s", acReg);
			nOppAddr = -1 * (nReg + 1);
		}
		break;

		case 01:
		{
			sprintf(str, "(%s)", acReg);
			nOppAddr = m_Reg[nReg];
		}
		break;

		case 02:
		{
			if (nReg != 7)
			{
				sprintf(str, "(%s)+", acReg);
				nOppAddr = m_Reg[nReg];
				m_nR_Operand[nReg] = (uint16_t)(m_Reg[nReg] + nOpSize);
			}
			else
			{
				wAddr = m_Reg[7] & (~1);
				uint16_t nData = (signed short)(GET_WORD(wAddr));
				m_Reg[7] += 2;
				/*
				if (nData > 7 || nData < -7)
				{
				    sprintf(str, "#%i.", nData);
				}
				else
				{
				    sprintf(str, "#%i", nData);
				}
				*/
				sprintf(str, "#%06o", nData);
				nOppAddr = wAddr;
			}
		}
		break;

		case 03:
		{
			if (nReg != 7)
			{
				sprintf(str, "@(%s)+", acReg);
				nOppAddr = GET_WORD(m_Reg[nReg] & (~1));
				m_nR_Operand[nReg] = (uint16_t)(m_Reg[nReg] + 2);
			}
			else
			{
				wAddr = GET_WORD(m_Reg[7] & (~1));
				m_Reg[7] += 2;
				sprintf(str, "@#%06o", wAddr);
				nOppAddr = wAddr;
			}
		}
		break;

		case 04:
		{
			sprintf(str, "-(%s)", acReg);
			nOppAddr = m_Reg[nReg] - 2;
			m_nR_Operand[nReg] = (uint16_t)(m_Reg[nReg] - nOpSize);
		}
		break;

		case 05:
		{
			sprintf(str, "@-(%s)", acReg);
			nOppAddr = GET_WORD((m_Reg[nReg] - 2) & (~1));
			m_nR_Operand[nReg] = (uint16_t)(m_Reg[nReg] - 2);
		}
		break;

		case 06:
		{
			nOffset = (signed short)(GET_WORD(m_Reg[7] & (~1)));
			m_Reg[7] += 2;

			if (nReg != 7)
			{
				/*
				if (nOffset > 7 || nOffset < -7)
				{
				    sprintf(str, "%i.(%s)", nOffset, acReg);
				}
				else
				{
				    sprintf(str, "%i(%s)", nOffset, acReg);
				}
				*/
				sprintf(str, "%06o(%s)", nOffset, acReg);
			}
			else
			{
				wAddr = m_Reg[7] + nOffset;

				if (!bByteMode)
				{
					wAddr &= (~1);
				}

				sprintf(str, "%06o", wAddr);
			}

			uint16_t wOppAddr = (uint16_t)nOffset + m_Reg[nReg];
			nOppAddr = wOppAddr;
		}
		break;

		case 07:
		{
			nOffset = (signed short)(GET_WORD(m_Reg[7] & (~1)));
			m_Reg[7] += 2;

			if (nOffset)
			{
				/*
				if (nOffset > 7 || nOffset < -7)
				{
				    sprintf(str, "@%i.(%s)", nOffset, acReg);
				}
				else
				{
				    sprintf(str, "@%i(%s)", nOffset, acReg);
				}
				*/
				sprintf(str, "@%06o(%s)", nOffset, acReg);
			}
			else
			{
				sprintf(str, "@(%s)", acReg);
			}

			nOppAddr = GET_WORD((uint16_t)((m_Reg[nReg] + (uint16_t)nOffset) & (~1)));
		}
		break;
	}

	DisAsmPrint(str);

	if (!bByteMode && nOppAddr >= 0)
	{
		nOppAddr &= (~1);
	}

	return nOppAddr;
}

int CDebugger::PrintOperand2(uint8_t nOpMode, int nOpSize)
{
	int nReg = nOpMode & 07;
	int nMode = (nOpMode & 070) >> 3;
	uint16_t nOffset;
	uint16_t wAddr;
	int nOppAddr = 0;
	bool bByteMode = (nOpSize - 1) ? false : true;
	char str[128];
	static char acReg[16];

	if (nReg <= 5)
	{
		sprintf(acReg, "R%u", nReg);
	}
	else
	{
		switch (nReg)
		{
			case 6:
				sprintf(acReg, "SP");
				break;

			case 7:
				sprintf(acReg, "PC");
				break;
		}
	}

	switch (nMode)
	{
		case 00:
		{
			sprintf(str, "%s", acReg);
			nOppAddr = -1 * (nReg + 1);
		}
		break;

		case 01:
		{
			sprintf(str, "(%s)", acReg);

			if (m_nR_Operand[nReg] < 0)
			{
				nOppAddr = m_Reg[nReg];
			}
			else
			{
				nOppAddr = m_nR_Operand[nReg];
			}
		}
		break;

		case 02:
		{
			if (nReg != 7)
			{
				sprintf(str, "(%s)+", acReg);

				if (m_nR_Operand[nReg] < 0)
				{
					nOppAddr = m_Reg[nReg];
				}
				else
				{
					nOppAddr = m_nR_Operand[nReg];
				}
			}
			else
			{
				wAddr = m_Reg[7] & (~1);
				uint16_t nData = (signed short)(GET_WORD(wAddr));
				m_Reg[7] += 2;
				/*
				if (nData > 7 || nData < -7)
				{
				    sprintf(str, "#%i.", nData);
				}
				else
				{
				    sprintf(str, "#%i", nData);
				}
				*/
				sprintf(str, "#%06o", nData);
				nOppAddr = wAddr;
			}
		}
		break;

		case 03:
		{
			if (nReg != 7)
			{
				sprintf(str, "@(%s)+", acReg);

				if (m_nR_Operand[nReg] < 0)
				{
					nOppAddr = GET_WORD(m_Reg[nReg] & (~1));
				}
				else
				{
					nOppAddr = GET_WORD(m_nR_Operand[nReg] & (~1));
				}
			}
			else
			{
				wAddr = GET_WORD(m_Reg[7] & (~1));
				m_Reg[7] += 2;
				sprintf(str, "@#%06o", wAddr);
				nOppAddr = wAddr;
			}
		}
		break;

		case 04:
		{
			sprintf(str, "-(%s)", acReg);

			if (m_nR_Operand[nReg] < 0)
			{
				nOppAddr = m_Reg[nReg] - 2;
			}
			else
			{
				nOppAddr = m_nR_Operand[nReg] - 2;
			}
		}
		break;

		case 05:
		{
			sprintf(str, "@-(%s)", acReg);

			if (m_nR_Operand[nReg] < 0)
			{
				nOppAddr = GET_WORD((m_Reg[nReg] - 2) & (~1));
			}
			else
			{
				nOppAddr = GET_WORD((m_nR_Operand[nReg] - 2) & (~1));
			}
		}
		break;

		case 06:
		{
			nOffset = (signed short)(GET_WORD(m_Reg[7] & (~1)));
			m_Reg[7] += 2;

			if (nReg != 7)
			{
				/*
				if (nOffset > 7 || nOffset < -7)
				{
				    sprintf(str, "%i.(%s)", nOffset, acReg);
				}
				else
				{
				    sprintf(str, "%i(%s)", nOffset, acReg);
				}
				*/
				sprintf(str, "%06o(%s)", nOffset, acReg);
			}
			else
			{
				wAddr = m_Reg[7] + nOffset;

				if (!bByteMode)
				{
					wAddr &= (~1);
				}

				sprintf(str, "%06o", wAddr);
			}

			if (m_nR_Operand[nReg] < 0)
			{
				uint16_t wOppAddr = (uint16_t)nOffset + m_Reg[nReg];
				nOppAddr = wOppAddr;
			}
			else
			{
				uint16_t wOppAddr = (uint16_t)nOffset + m_nR_Operand[nReg];
				nOppAddr = wOppAddr;
			}
		}
		break;

		case 07:
		{
			nOffset = (signed short)(GET_WORD(m_Reg[7] & (~1)));
			m_Reg[7] += 2;

			if (nOffset)
			{
				/*
				if (nOffset > 7 || nOffset < -7)
				{
				    sprintf(str, "%i.(%s)", nOffset, acReg);
				}
				else
				{
				    sprintf(str, "%i(%s)", nOffset, acReg);
				}
				*/
				sprintf(str, "%06o(%s)", nOffset, acReg);
			}
			else
			{
				sprintf(str, "@(%s)", acReg);
			}

			if (m_nR_Operand[nReg] < 0)
			{
				nOppAddr = GET_WORD((uint16_t)((m_Reg[nReg] + (uint16_t)nOffset) & (~1)));
			}
			else
			{
				nOppAddr = GET_WORD((uint16_t)((m_nR_Operand[nReg] + (uint16_t)nOffset) & (~1)));
			}
		}
		break;
	}

	DisAsmPrint(str);

	if (!bByteMode && nOppAddr >= 0)
	{
		nOppAddr &= (~1);
	}

	return nOppAddr;
}

void CDebugger::DisAsm(int nClk)
{
	static uint16_t LastPC[7] = {0, 0, 0, 0, 0, 0, 0};
	static long LastPC_count[7] = {0, 0, 0, 0, 0, 0, 0};
	char str[128];
	uint16_t nWord;

	if (!SnapRON()) //делаем снапшот регистров общего назначения
	{
		return;
	}

	LastPC[0] = m_Reg[7];
	uint16_t PC_res = m_Reg[7];
	bool bRepeat = false;

	//*
	if (LastPC[2] == LastPC[0])
	{
		if (++LastPC_count[2] > 2)
		{
			bRepeat = true;
		}
	}
	else
	{
		if (LastPC_count[2] > 3)
		{
			sprintf(str, LNG("\n^^^ Last [2] lines [%i] repeat ^^^\n\n"), LastPC_count[2] / 2 - 1);
			DisAsmPrint(str);
			bRepeat = false;
		}

		LastPC_count[2] = 0;
	}

	if (LastPC[3] == LastPC[0])
	{
		if (++LastPC_count[3] > 6)
		{
			bRepeat = true;
		}
	}
	else
	{
		if (LastPC_count[3] > 6)
		{
			sprintf(str, LNG("\n^^^ Last [3] lines [%i] repeat ^^^\n\n"), LastPC_count[3] / 3 - 1);
			DisAsmPrint(str);
			bRepeat = false;
		}

		LastPC_count[3] = 0;
	}

	if (!LastPC_count[2])
	{
		if (LastPC[4] == LastPC[0])
		{
			if (++LastPC_count[4] > 8)
			{
				bRepeat = true;
			}
		}
		else
		{
			if (LastPC_count[4] > 8)
			{
				sprintf(str, LNG("\n^^^ Last [4] lines [%i] repeat ^^^\n\n"), LastPC_count[4] / 4 - 1);
				DisAsmPrint(str);
				bRepeat = false;
			}

			LastPC_count[4] = 0;
		}
	}

	if (LastPC[5] == LastPC[0])
	{
		if (++LastPC_count[5] > 10)
		{
			bRepeat = true;
		}
	}
	else
	{
		if (LastPC_count[5] > 10)
		{
			sprintf(str, LNG("\n^^^ Last [5] lines [%i] repeat ^^^\n\n"), LastPC_count[5] / 5 - 1);
			DisAsmPrint(str);
			bRepeat = false;
		}

		LastPC_count[5] = 0;
	}

	if (!LastPC_count[2] && !LastPC_count[3])
	{
		if (LastPC[6] == LastPC[0])
		{
			if (++LastPC_count[6] > 12)
			{
				bRepeat = true;
			}
		}
		else
		{
			if (LastPC_count[6] > 12)
			{
				sprintf(str, LNG("\n^^^ Last [6] lines [%i] repeat ^^^\n\n"), LastPC_count[6] / 6 - 1);
				DisAsmPrint(str);
				bRepeat = false;
			}

			LastPC_count[6] = 0;
		}
	}

	LastPC[6] = LastPC[5];
	LastPC[5] = LastPC[4];
	LastPC[4] = LastPC[3];
	LastPC[3] = LastPC[2];
	LastPC[2] = LastPC[1];
	LastPC[1] = LastPC[0];

	if (bRepeat)
	{
		m_Reg[7] = PC_res;
		return;
	}

	if (m_bDisAsmLog)
	{
		sprintf(str, "%08d> %06o [%06o]:      ", nClk, m_Reg[7], m_PSW);
		//sprintf(str,"PC[%06o] PSW[%03o]:  ", r[7], PSW );
		//sprintf(str,"%012llu:      ", Get_qwRunTimeNS() );
		//sprintf(str,"PC[%06o] PSW[%03o] SP[%06o] 772[%06o] 774[%06o] : ", r[7], PSW, r[6], GET_WORD(0772), GET_WORD(0774) );
		//sprintf(str, "PC[%06o] PSW[%03o] R0[%06o] R1[%06o] R2[%06o] R3[%06o] R4[%06o] R5[%06o] R6[%06o]  :  ", m_Reg[7], m_PSW, m_Reg[0], m_Reg[1], m_Reg[2], m_Reg[3], m_Reg[4], m_Reg[5], m_Reg[6]);
	}
	else
	{
		sprintf(str, "%08d> %06o: ", nClk, m_Reg[7]);
	}

	DisAsmPrint(str);
	m_nPrintPosition = 0;
	nWord = GET_WORD(m_Reg[7] & (~1));
	m_Reg[7] += 2;

	if (nWord <= 6)
	{
		static char *acInstr[] = { "HALT", "WAIT", "RTI", "BPT", "IOT", "RESET", "RTT" };
		sprintf(str, "%s\n", acInstr[nWord]);
		DisAsmPrint(str);

		if (nWord >= 2 && nWord != 5)
		{
			DisAsmPrint("\n");
		}

		goto DONE;
	}

	if (nWord == 012)
	{
		DisAsmPrint("START\n\n");
		goto DONE;
	}

	if (nWord == 016)
	{
		DisAsmPrint("STEP\n\n");
		goto DONE;
	}

	if (nWord <= 0177)
	{
		if (nWord & 0100)
		{
			DisAsmPrint("JMP ");
			SkipPrintToOperandPosition();
			PrintOperand(nWord & 077);
			DisAsmPrint("\n\n");
			goto DONE;
		}

		sprintf(str, LNG("%06o - Strange Opcode\n"), nWord);
		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord <= 0207)
	{
		int nReg = nWord & 07;

		if (nReg != 7)
		{
			DisAsmPrint("RTS ");
			SkipPrintToOperandPosition();
			sprintf(str, "R%u", nReg);
			DisAsmPrint(str);
		}
		else
		{
			DisAsmPrint("RETURN");
		}

		SkipPrintToCommentsPosition();
		sprintf(str, LNG("; %06o:%06o ->   R%i  "), m_Reg[6], GET_WORD(m_Reg[6] & (~1)), nReg);
		DisAsmPrint(str);
		DisAsmPrint("\n\n");
		goto DONE;
	}

	if (nWord < 0230)
	{
		sprintf(str, LNG("%06o - Strange Opcode\n"), nWord);
		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord <= 0237)
	{
		//    int nPriority = nWord & 07;
		//    sprintf(str,"SPL %u\n", nPriority );
		sprintf(str, LNG("%06o - SPL - Opcode not supported\n"), nWord);
		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord <= 0277)
	{
		uint16_t nMask, mask;

		switch (nWord)
		{
			case 0240:
				DisAsmPrint("NOP\n");
				break;

			case 0241:
				DisAsmPrint("CLC\n");
				break;

			case 0242:
				DisAsmPrint("CLV\n");
				break;

			case 0244:
				DisAsmPrint("CLZ\n");
				break;

			case 0250:
				DisAsmPrint("CLN\n");
				break;

			case 0257:
				DisAsmPrint("CCC\n");
				break;

			case 0261:
				DisAsmPrint("SEC\n");
				break;

			case 0262:
				DisAsmPrint("SEV\n");
				break;

			case 0264:
				DisAsmPrint("SEZ\n");
				break;

			case 0270:
				DisAsmPrint("SEN\n");
				break;

			case 0277:
				DisAsmPrint("SCC\n");
				break;

			default:
				if (nWord <= 0257)
				{
					// NOP .. CCC
					nMask = nWord & 017;
					DisAsmPrint("BIC_PSW ^b");

					for (mask = 010; mask; mask >>= 1)
					{
						sprintf(str, "%u", ((nMask & mask) != 0));
						DisAsmPrint(str);
					}

					DisAsmPrint("\n");
					break;
				}

				if (nWord <= 0277)
				{
					// NOP2 .. SCC
					nMask = nWord & 017;
					DisAsmPrint("BIS_PSW ^b");

					for (mask = 010; mask; mask >>= 1)
					{
						sprintf(str, "%u", ((nMask & mask) != 0));
						DisAsmPrint(str);
					}

					DisAsmPrint("\n");
					break;
				}

				sprintf(str, LNG("%06o - Strange Opcode\n"), nWord);
				DisAsmPrint(str);
				break;
		}

		goto DONE;
	}

	if (nWord <= 0377)
	{
		DisAsmPrint("SWAB ");
		SkipPrintToOperandPosition();
		int nOppAddr = PrintOperand(nWord & 077);
		SkipPrintToCommentsPosition();

		if (nOppAddr >= 0)
		{
			uint16_t wOppAddr = nOppAddr;
			uint16_t wOperand = GET_WORD(wOppAddr);

			if (abReadAccess[wOppAddr])
			{
				sprintf(str, LNG("; %06o:%06o"), wOppAddr, wOperand);
			}
			else
			{
				sprintf(str, LNG("; %06o:      "), wOppAddr);
			}

			DisAsmPrint(str);
		}
		else
		{
			int nR = (-1 * nOppAddr) - 1;
			sprintf(str, LNG(";   R%i  :%06o"), nR, m_Reg[nR]);
			DisAsmPrint(str);
		}

		DisAsmPrint("\n");
		goto DONE;
	}

	if (nWord <= 03777)
	{
		switch (nWord & 03400)
		{
			case 0400:
				DisAsmPrint("BR ");
				break;

			case 01000:
				DisAsmPrint("BNE ");
				break;

			case 01400:
				DisAsmPrint("BEQ ");
				break;

			case 02000:
				DisAsmPrint("BGE ");
				break;

			case 02400:
				DisAsmPrint("BLT ");
				break;

			case 03000:
				DisAsmPrint("BGT ");
				break;

			case 03400:
				DisAsmPrint("BLE ");
				break;

			default:
				sprintf(str, LNG("%06o - Strange Opcode\n"), nWord);
				DisAsmPrint(str);
				goto DONE;
		}

		int nOffset = (signed char)(nWord & 0377);
		nOffset *= 2;
		SkipPrintToOperandPosition();
		sprintf(str, "%06o", m_Reg[7] + nOffset);
		DisAsmPrint(str);
		SkipPrintToCommentsPosition();

		if ((nWord & 03400) != 0400)
		{
			PrintPSW(str);
			DisAsmPrint(str);
		}

		DisAsmPrint("\n");
		goto DONE;
	}

	if (nWord <= 04777)
	{
		int nReg = (nWord & 0700) >> 6;

		if (nReg != 7)
		{
			DisAsmPrint("JSR ");
			SkipPrintToOperandPosition();
			sprintf(str, "R%u, ", nReg);
			DisAsmPrint(str);
		}
		else
		{
			DisAsmPrint("CALL ");
			SkipPrintToOperandPosition();
		}

		PrintOperand(nWord & 077);
		SkipPrintToCommentsPosition();
		sprintf(str, LNG(";   R%i  :%06o -> %06o"), nReg, m_Reg[nReg], m_Reg[6] - 2);
		DisAsmPrint(str);
		DisAsmPrint("\n\n");
		goto DONE;
	}

	if (nWord <= 06377)
	{
		switch (nWord & 07700)
		{
			case 05000:
				DisAsmPrint("CLR ");
				break;

			case 05100:
				DisAsmPrint("COM ");
				break;

			case 05200:
				DisAsmPrint("INC ");
				break;

			case 05300:
				DisAsmPrint("DEC ");
				break;

			case 05400:
				DisAsmPrint("NEG ");
				break;

			case 05500:
				DisAsmPrint("ADC ");
				break;

			case 05600:
				DisAsmPrint("SBC ");
				break;

			case 05700:
				DisAsmPrint("TST ");
				break;

			case 06000:
				DisAsmPrint("ROR ");
				break;

			case 06100:
				DisAsmPrint("ROL ");
				break;

			case 06200:
				DisAsmPrint("ASR ");
				break;

			case 06300:
				DisAsmPrint("ASL ");
				break;
		}

		SkipPrintToOperandPosition();
		int nOppAddr = PrintOperand(nWord & 077);
		SkipPrintToCommentsPosition();

		if (nOppAddr >= 0)
		{
			uint16_t wOppAddr = nOppAddr;
			uint16_t wOperand = GET_WORD(wOppAddr);

			if (abReadAccess[wOppAddr])
			{
				sprintf(str, LNG("; %06o:%06o"), wOppAddr, wOperand);
			}
			else
			{
				sprintf(str, LNG("; %06o:      "), wOppAddr);
			}

			DisAsmPrint(str);
		}
		else
		{
			int nR = (-1 * nOppAddr) - 1;
			sprintf(str, LNG(";   R%i  :%06o"), nR, m_Reg[nR]);
			DisAsmPrint(str);
		}

		DisAsmPrint("\n");
		goto DONE;
	}

	if (nWord <= 06477)
	{
		DisAsmPrint("MARK ");
		SkipPrintToOperandPosition();
		sprintf(str, "%i\n", (nWord & 077));
		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord < 06700)
	{
		sprintf(str, LNG("%06o - Strange Opcode\n"), nWord);
		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord <= 06777)
	{
		DisAsmPrint("SXT ");
		SkipPrintToOperandPosition();
		PrintOperand(nWord & 077);
		DisAsmPrint("\n");
		goto DONE;
	}

	if (nWord <= 07777)
	{
		sprintf(str, LNG("%06o - Strange Opcode\n"), nWord);
		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord <= 017777)
	{
		DisAsmPrint("MOV ");
		SkipPrintToOperandPosition();
		int nOpp1Addr = PrintOperand((nWord & 07700) >> 6);
		DisAsmPrint(", ");
		int nOpp2Addr = PrintOperand2(nWord & 077);
		SkipPrintToCommentsPosition();

		if (nOpp1Addr >= 0 && nOpp2Addr >= 0)
		{
			uint16_t wOpp1Addr = nOpp1Addr;
			uint16_t wOperand = GET_WORD(wOpp1Addr & (~1));
			uint16_t wOpp2Addr = nOpp2Addr;

			if (abReadAccess[wOpp1Addr])
			{
				sprintf(str, LNG("; %06o:%06o -> %06o"), wOpp1Addr, wOperand, wOpp2Addr);
			}
			else
			{
				sprintf(str, LNG("; %06o:       -> %06o"), wOpp1Addr, wOpp2Addr);
			}

			DisAsmPrint(str);
		}
		else if (nOpp1Addr < 0 && nOpp2Addr >= 0)
		{
			int nR = (-1 * nOpp1Addr) - 1;
			sprintf(str, LNG(";   R%i  :%06o -> %06o"), nR, m_Reg[nR], nOpp2Addr);
			DisAsmPrint(str);
		}
		else if (nOpp1Addr >= 0 && nOpp2Addr < 0)
		{
			uint16_t wOpp1Addr = nOpp1Addr;
			uint16_t wOperand = GET_WORD(wOpp1Addr & (~1));
			int nR = (-1 * nOpp2Addr) - 1;

			if (abReadAccess[wOpp1Addr])
			{
				sprintf(str, LNG("; %06o:%06o ->   R%i"), wOpp1Addr, wOperand, nR);
			}
			else
			{
				sprintf(str, LNG("; %06o:       ->   R%i"), wOpp1Addr, nR);
			}

			DisAsmPrint(str);
		}
		else
			// if( nOpp1Addr < 0 && nOpp2Addr < 0 )
		{
			int nRa = (-1 * nOpp1Addr) - 1;
			int nRb = (-1 * nOpp2Addr) - 1;
			sprintf(str, LNG(";   R%i  :%06o ->   R%i"), nRa, m_Reg[nRa], nRb);
			DisAsmPrint(str);
		}

		DisAsmPrint("\n");
		goto DONE;
	}

	if (nWord <= 067777)
	{
		switch (nWord & 070000)
		{
			case 020000:
				DisAsmPrint("CMP ");
				break;

			case 030000:
				DisAsmPrint("BIT ");
				break;

			case 040000:
				DisAsmPrint("BIC ");
				break;

			case 050000:
				DisAsmPrint("BIS ");
				break;

			case 060000:
				DisAsmPrint("ADD ");
				break;
		}

		SkipPrintToOperandPosition();
		int nOpp1Addr = PrintOperand((nWord & 07700) >> 6);
		DisAsmPrint(", ");
		int nOpp2Addr = PrintOperand2(nWord & 077);
		SkipPrintToCommentsPosition();

		if (nOpp1Addr >= 0 && nOpp2Addr >= 0)
		{
			uint16_t wOpp1Addr = nOpp1Addr;
			uint16_t wOperand1 = GET_WORD(wOpp1Addr & (~1));
			uint16_t wOpp2Addr = nOpp2Addr;
			uint16_t wOperand2 = GET_WORD(wOpp2Addr & (~1));

			if (abReadAccess[wOpp1Addr] && abReadAccess[wOpp2Addr])
			{
				sprintf(str, LNG("; %06o:%06o -> %06o:%06o"), wOpp1Addr, wOperand1, wOpp2Addr, wOperand2);
			}
			else if (!abReadAccess[wOpp1Addr])
			{
				sprintf(str, LNG("; %06o:       -> %06o:%06o"), wOpp1Addr, wOpp2Addr, wOperand2);
			}
			else if (!abReadAccess[wOpp2Addr])
			{
				sprintf(str, LNG("; %06o:%06o -> %06o:"), wOpp1Addr, wOperand1, wOpp2Addr);
			}
			else
			{
				sprintf(str, LNG("; %06o:       -> %06o:"), wOpp1Addr, wOpp2Addr);
			}

			DisAsmPrint(str);
		}
		else if (nOpp1Addr < 0 && nOpp2Addr >= 0)
		{
			int nR = (-1 * nOpp1Addr) - 1;
			uint16_t wOpp2Addr = nOpp2Addr;
			uint16_t wOperand2 = GET_WORD(wOpp2Addr & (~1));

			if (abReadAccess[wOpp2Addr])
			{
				sprintf(str, LNG(";   R%i  :%06o -> %06o:%06o"), nR, m_Reg[nR], wOpp2Addr, wOperand2);
			}
			else
			{
				sprintf(str, LNG(";   R%i  :%06o -> %06o:"), nR, m_Reg[nR], wOpp2Addr);
			}

			DisAsmPrint(str);
		}
		else if (nOpp1Addr >= 0 && nOpp2Addr < 0)
		{
			uint16_t wOpp1Addr = nOpp1Addr;
			uint16_t wOperand = GET_WORD(wOpp1Addr & (~1));
			int nR = (-1 * nOpp2Addr) - 1;

			if (abReadAccess[wOpp1Addr])
			{
				sprintf(str, LNG("; %06o:%06o ->   R%i  :%06o"), wOpp1Addr, wOperand, nR, m_Reg[nR]);
			}
			else
			{
				sprintf(str, LNG("; %06o:       ->   R%i  :%06o"), wOpp1Addr, nR, m_Reg[nR]);
			}

			DisAsmPrint(str);
		}
		else
			// if( nOpp1Addr < 0 && nOpp2Addr < 0 )
		{
			int nRa = (-1 * nOpp1Addr) - 1;
			int nRb = (-1 * nOpp2Addr) - 1;
			sprintf(str, LNG(";   R%i  :%06o ->   R%i  :%06o"), nRa, m_Reg[nRa], nRb, m_Reg[nRb]);
			DisAsmPrint(str);
		}

		DisAsmPrint("\n");
		goto DONE;
	}

	if (nWord < 074000)
	{
		sprintf(str, LNG("%06o - Strange Opcode\n"), nWord);
		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord <= 074777)
	{
		DisAsmPrint("XOR ");
		SkipPrintToOperandPosition();
		int nR = (nWord & 0700) >> 6;
		sprintf(str, "R%i, ", nR);
		DisAsmPrint(str);
		int nOppAddr = PrintOperand(nWord & 077);
		SkipPrintToCommentsPosition();

		if (nOppAddr >= 0)
		{
			uint16_t wOppAddr = (uint16_t)nOppAddr;
			uint16_t wOperand = GET_WORD(wOppAddr & (~1));

			if (abReadAccess[wOppAddr])
			{
				sprintf(str, LNG(";   R%i  :%06o -> %06o:%06o\n"), nR, m_Reg[nR], wOppAddr, wOperand);
			}
			else
			{
				sprintf(str, LNG(";   R%i  :%06o -> %06o:\n"), nR, m_Reg[nR], wOppAddr);
			}
		}
		else
		{
			int nRb = (-1 * nOppAddr) - 1;
			sprintf(str, LNG(";   R%i  :%06o ->   R%i  :%06o\n"), nR, m_Reg[nR], nRb, m_Reg[nRb]);
		}

		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord < 077000)
	{
		sprintf(str, LNG("%06o - Strange Opcode\n"), nWord);
		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord <= 077777)
	{
		DisAsmPrint("SOB ");
		SkipPrintToOperandPosition();
		int nR = (nWord & 0700) >> 6;
		sprintf(str, "R%i, %06o", nR, (m_Reg[7] - (nWord & 077) * 2));
		DisAsmPrint(str);
		SkipPrintToCommentsPosition();
		sprintf(str, LNG(";   R%i  :%06o\n"), nR, m_Reg[nR]);
		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord <= 0103777)
	{
		switch (nWord & 03400)
		{
			case 00:
				DisAsmPrint("BPL ");
				break;

			case 0400:
				DisAsmPrint("BMI ");
				break;

			case 01000:
				DisAsmPrint("BHI ");
				break;

			case 01400:
				DisAsmPrint("BLOS ");
				break;

			case 02000:
				DisAsmPrint("BVC ");
				break;

			case 02400:
				DisAsmPrint("BVS ");
				break;

			case 03000:
				DisAsmPrint("BCC ");
				break;

			case 03400:
				DisAsmPrint("BCS ");
				break;

			default:
				sprintf(str, LNG("%06o - Strange Opcode\n"), nWord);
				DisAsmPrint(str);
				goto DONE;
		}

		uint16_t nOffset = (signed char)(nWord & 0377);
		nOffset *= 2;
		SkipPrintToOperandPosition();
		sprintf(str, "%06o", m_Reg[7] + nOffset);
		DisAsmPrint(str);
		SkipPrintToCommentsPosition();
		//sprintf(str,";   PSW :%06o", m_PSW );
		PrintPSW(str);
		DisAsmPrint(str);
		DisAsmPrint("\n");
		goto DONE;
	}

	if (nWord <= 0104377)
	{
		DisAsmPrint("EMT ");
		SkipPrintToOperandPosition();
		sprintf(str, "%o\n\n", nWord & 0377);
		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord <= 0104777)
	{
		DisAsmPrint("TRAP ");
		SkipPrintToOperandPosition();
		sprintf(str, "%u.\n\n", nWord & 0377);
		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord <= 0106377)
	{
		switch (nWord & 07700)
		{
			case 05000:
				DisAsmPrint("CLRB ");
				break;

			case 05100:
				DisAsmPrint("COMB ");
				break;

			case 05200:
				DisAsmPrint("INCB ");
				break;

			case 05300:
				DisAsmPrint("DECB ");
				break;

			case 05400:
				DisAsmPrint("NEGB ");
				break;

			case 05500:
				DisAsmPrint("ADCB ");
				break;

			case 05600:
				DisAsmPrint("SBCB ");
				break;

			case 05700:
				DisAsmPrint("TSTB ");
				break;

			case 06000:
				DisAsmPrint("RORB ");
				break;

			case 06100:
				DisAsmPrint("ROLB ");
				break;

			case 06200:
				DisAsmPrint("ASRB ");
				break;

			case 06300:
				DisAsmPrint("ASLB ");
				break;
		}

		SkipPrintToOperandPosition();
		int nOppAddr = PrintOperand(nWord & 077, 1);
		SkipPrintToCommentsPosition();

		if (nOppAddr >= 0)
		{
			uint16_t wOppAddr = nOppAddr;
			uint8_t cOperand = GET_BYTE(wOppAddr);

			if (abReadAccess[wOppAddr])
			{
				sprintf(str, LNG("; %06o:   %03o"), wOppAddr, cOperand);
			}
			else
			{
				sprintf(str, LNG("; %06o:      "), wOppAddr);
			}

			DisAsmPrint(str);
		}
		else
		{
			int nR = (-1 * nOppAddr) - 1;
			uint8_t cOperand = (uint8_t)m_Reg[nR];
			sprintf(str, LNG(";   R%i  :   %03o"), nR, cOperand);
			DisAsmPrint(str);
		}

		DisAsmPrint("\n");
		goto DONE;
	}

	if (nWord <= 0106477)
	{
		DisAsmPrint("MTPS ");
		SkipPrintToOperandPosition();
		int nOppAddr = PrintOperand(nWord & 077, 1);
		SkipPrintToCommentsPosition();

		if (nOppAddr >= 0)
		{
			uint16_t wOppAddr = nOppAddr;
			uint8_t cOperand = GET_BYTE(wOppAddr);

			if (abReadAccess[wOppAddr])
			{
				sprintf(str, LNG("; %06o:   %03o ->   PSW :%06o"), wOppAddr, cOperand, m_PSW);
			}
			else
			{
				sprintf(str, LNG("; %06o:       ->   PSW :%06o"), wOppAddr, m_PSW);
			}

			DisAsmPrint(str);
		}
		else
		{
			int nR = (-1 * nOppAddr) - 1;
			uint8_t cOperand = (uint8_t)m_Reg[nR];
			sprintf(str, LNG(";   R%i  :   %03o ->   PSW :%06o"), nR, cOperand, m_PSW);
			DisAsmPrint(str);
		}

		DisAsmPrint("\n");
		goto DONE;
	}

	if (nWord < 0106700)
	{
		sprintf(str, LNG("%06o - Strange Opcode\n"), nWord);
		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord <= 0106777)
	{
		DisAsmPrint("MFPS ");
		SkipPrintToOperandPosition();
		int nOppAddr = PrintOperand(nWord & 077, 1);
		SkipPrintToCommentsPosition();

		if (nOppAddr >= 0)
		{
			uint16_t wOppAddr = nOppAddr;
			sprintf(str, LNG(";   PSW :   %03o -> %06o"), (uint8_t)m_PSW, wOppAddr);
			DisAsmPrint(str);
		}
		else
		{
			int nR = (-1 * nOppAddr) - 1;
			sprintf(str, LNG(";   PSW :   %03o ->   R%i"), (uint8_t)m_PSW, nR);
			DisAsmPrint(str);
		}

		DisAsmPrint("\n");
		goto DONE;
	}

	if (nWord < 0110000)
	{
		sprintf(str, LNG("%06o - Strange Opcode\n"), nWord);
		DisAsmPrint(str);
		goto DONE;
	}

	if (nWord <= 0117777)
	{
		DisAsmPrint("MOVB ");
		SkipPrintToOperandPosition();
		int nOpp1Addr = PrintOperand((nWord & 07700) >> 6, 1);
		DisAsmPrint(", ");
		int nOpp2Addr = PrintOperand2(nWord & 077, 1);
		SkipPrintToCommentsPosition();

		if (nOpp1Addr >= 0 && nOpp2Addr >= 0)
		{
			uint16_t wOpp1Addr = nOpp1Addr;
			uint8_t cOperand = GET_BYTE(wOpp1Addr);
			uint16_t wOpp2Addr = nOpp2Addr;

			if (abReadAccess[wOpp1Addr])
			{
				sprintf(str, LNG("; %06o:   %03o -> %06o"), wOpp1Addr, cOperand, wOpp2Addr);

				if ((wOpp2Addr == 0177566 || wOpp1Addr == 0177562) && cOperand > ' ')
				{
					char str1[64];
					sprintf(str1, "   '%c'", cOperand);
					strcat(str, str1);
				}
			}
			else
			{
				sprintf(str, LNG("; %06o:       -> %06o"), wOpp1Addr, wOpp2Addr);
			}

			DisAsmPrint(str);
		}
		else if (nOpp1Addr < 0 && nOpp2Addr > 0)
		{
			int nR = (-1 * nOpp1Addr) - 1;
			uint8_t cOperand = (uint8_t)m_Reg[nR];
			sprintf(str, LNG(";   R%i  :   %03o -> %06o"), nR, cOperand, nOpp2Addr);

			if (nOpp2Addr == 0177566 && cOperand > ' ')
			{
				char str1[64];
				sprintf(str1, "   '%c'", cOperand);
				strcat(str, str1);
			}

			DisAsmPrint(str);
		}
		else if (nOpp1Addr > 0 && nOpp2Addr < 0)
		{
			uint16_t wOpp1Addr = nOpp1Addr;
			uint8_t cOperand = GET_BYTE(wOpp1Addr);
			int nR = (-1 * nOpp2Addr) - 1;

			if (abReadAccess[wOpp1Addr])
			{
				sprintf(str, LNG("; %06o:   %03o ->   R%i  "), wOpp1Addr, cOperand, nR);

				if (wOpp1Addr == 0177562 && cOperand > ' ')
				{
					char str1[64];
					sprintf(str1, "   '%c'", cOperand);
					strcat(str, str1);
				}
			}
			else
			{
				sprintf(str, LNG("; %06o:       ->   R%i"), wOpp1Addr, nR);
			}

			DisAsmPrint(str);
		}
		else
			// if( nOpp1Addr < 0 && nOpp2Addr < 0 )
		{
			int nRa = (-1 * nOpp1Addr) - 1;
			uint8_t cOperand = (uint8_t)m_Reg[nRa];
			int nRb = (-1 * nOpp2Addr) - 1;
			sprintf(str, LNG(";   R%i  :   %03o ->   R%i"), nRa, cOperand, nRb);
			DisAsmPrint(str);
		}

		DisAsmPrint("\n");
		goto DONE;
	}

	if (nWord <= 0157777)
	{
		switch (nWord & 070000)
		{
			case 020000:
				DisAsmPrint("CMPB ");
				break;

			case 030000:
				DisAsmPrint("BITB ");
				break;

			case 040000:
				DisAsmPrint("BICB ");
				break;

			case 050000:
				DisAsmPrint("BISB ");
				break;
		}

		SkipPrintToOperandPosition();
		int nOpp1Addr = PrintOperand((nWord & 07700) >> 6, 1);
		DisAsmPrint(", ");
		int nOpp2Addr = PrintOperand2(nWord & 077, 1);
		SkipPrintToCommentsPosition();

		if (nOpp1Addr >= 0 && nOpp2Addr >= 0)
		{
			uint16_t wOpp1Addr = nOpp1Addr;
			uint8_t cOperand1 = GET_BYTE(wOpp1Addr);
			uint16_t wOpp2Addr = nOpp2Addr;
			uint8_t cOperand2 = GET_BYTE(wOpp2Addr);

			if (abReadAccess[wOpp1Addr] && abReadAccess[wOpp2Addr])
			{
				sprintf(str, LNG("; %06o:   %03o -> %06o:   %03o"), wOpp1Addr, cOperand1, wOpp2Addr, cOperand2);
			}
			else if (!abReadAccess[wOpp1Addr])
			{
				sprintf(str, LNG("; %06o:       -> %06o:   %03o"), wOpp1Addr, wOpp2Addr, cOperand2);
			}
			else if (!abReadAccess[wOpp2Addr])
			{
				sprintf(str, LNG("; %06o:   %03o -> %06o:"), wOpp1Addr, cOperand1, wOpp2Addr);
			}
			else
			{
				sprintf(str, LNG("; %06o:       -> %06o:"), wOpp1Addr, wOpp2Addr);
			}

			DisAsmPrint(str);
		}
		else if (nOpp1Addr < 0 && nOpp2Addr > 0)
		{
			int nR = (-1 * nOpp1Addr) - 1;
			uint8_t cOperand = (uint8_t)m_Reg[nR];
			uint16_t wOpp2Addr = nOpp2Addr;
			uint8_t cOperand2 = GET_BYTE(wOpp2Addr);

			if (abReadAccess[wOpp2Addr])
			{
				sprintf(str, LNG(";   R%i  :   %03o -> %06o:   %03o"), nR, cOperand, wOpp2Addr, cOperand2);
			}
			else
			{
				sprintf(str, LNG(";   R%i  :   %03o -> %06o:"), nR, cOperand, wOpp2Addr);
			}

			DisAsmPrint(str);
		}
		else if (nOpp1Addr > 0 && nOpp2Addr < 0)
		{
			uint16_t wOpp1Addr = nOpp1Addr;
			uint8_t cOperand = GET_BYTE(wOpp1Addr);
			int nR = (-1 * nOpp2Addr) - 1;

			if (abReadAccess[wOpp1Addr])
			{
				sprintf(str, LNG("; %06o:   %03o ->   R%i  :   %03o"), wOpp1Addr, cOperand, nR, (uint8_t)m_Reg[nR]);
			}
			else
			{
				sprintf(str, LNG("; %06o:       ->   R%i  :   %03o"), wOpp1Addr, nR, (uint8_t)m_Reg[nR]);
			}

			DisAsmPrint(str);
		}
		else
			// if( nOpp1Addr < 0 && nOpp2Addr < 0 )
		{
			int nRa = (-1 * nOpp1Addr) - 1;
			auto cOperand = (uint8_t)m_Reg[nRa];
			int nRb = (-1 * nOpp2Addr) - 1;
			sprintf(str, LNG(";   R%i  :   %03o ->   R%i  :   %03o"), nRa, cOperand, nRb, (uint8_t)m_Reg[nRb]);
			DisAsmPrint(str);
		}

		DisAsmPrint("\n");
		goto DONE;
	}

	if (nWord <= 0167777)
	{
		DisAsmPrint("SUB ");
		SkipPrintToOperandPosition();
		int nOpp1Addr = PrintOperand((nWord & 07700) >> 6);
		DisAsmPrint(", ");
		int nOpp2Addr = PrintOperand2(nWord & 077);
		SkipPrintToCommentsPosition();

		if (nOpp1Addr >= 0 && nOpp2Addr >= 0)
		{
			uint16_t wOpp1Addr = nOpp1Addr;
			uint16_t wOperand1 = GET_WORD(wOpp1Addr & (~1));
			uint16_t wOpp2Addr = nOpp2Addr;
			uint16_t wOperand2 = GET_WORD(wOpp2Addr & (~1));

			if (abReadAccess[wOpp1Addr] && abReadAccess[wOpp2Addr])
			{
				sprintf(str, LNG("; %06o:%06o -> %06o:%06o"), wOpp1Addr, wOperand1, wOpp2Addr, wOperand2);
			}
			else if (!abReadAccess[wOpp1Addr])
			{
				sprintf(str, LNG("; %06o:       -> %06o:%06o"), wOpp1Addr, wOpp2Addr, wOperand2);
			}
			else if (!abReadAccess[wOpp2Addr])
			{
				sprintf(str, LNG("; %06o:%06o -> %06o:"), wOpp1Addr, wOperand1, wOpp2Addr);
			}
			else
			{
				sprintf(str, LNG("; %06o:       -> %06o:"), wOpp1Addr, wOpp2Addr);
			}

			DisAsmPrint(str);
		}
		else if (nOpp1Addr < 0 && nOpp2Addr >= 0)
		{
			int nR = (-1 * nOpp1Addr) - 1;
			uint16_t wOpp2Addr = nOpp2Addr;
			uint16_t wOperand2 = GET_WORD(wOpp2Addr & (~1));

			if (abReadAccess[wOpp2Addr])
			{
				sprintf(str, LNG(";   R%i  :%06o -> %06o:%06o"), nR, m_Reg[nR], wOpp2Addr, wOperand2);
			}
			else
			{
				sprintf(str, LNG(";   R%i  :%06o -> %06o:"), nR, m_Reg[nR], wOpp2Addr);
			}

			DisAsmPrint(str);
		}
		else if (nOpp1Addr >= 0 && nOpp2Addr < 0)
		{
			uint16_t wOpp1Addr = nOpp1Addr;
			uint16_t wOperand = GET_WORD(wOpp1Addr & (~1));
			int nR = (-1 * nOpp2Addr) - 1;

			if (abReadAccess[wOpp1Addr])
			{
				sprintf(str, LNG("; %06o:%06o ->   R%i  :%06o"), wOpp1Addr, wOperand, nR, m_Reg[nR]);
			}
			else
			{
				sprintf(str, LNG("; %06o:       ->   R%i  :%06o"), wOpp1Addr, nR, m_Reg[nR]);
			}

			DisAsmPrint(str);
		}
		else
			// if( nOpp1Addr < 0 && nOpp2Addr < 0 )
		{
			int nRa = (-1 * nOpp1Addr) - 1;
			int nRb = (-1 * nOpp2Addr) - 1;
			sprintf(str, LNG(";   R%i  :%06o ->   R%i  :%06o"), nRa, m_Reg[nRa], nRb, m_Reg[nRb]);
			DisAsmPrint(str);
		}

		DisAsmPrint("\n");
		goto DONE;
	}

	sprintf(str, LNG("%06o - Strange Opcode\n"), nWord);
	DisAsmPrint(str);
DONE:
	m_Reg[7] = PC_res;
}


