// license:BSD-3-Clause // copyright-holders:Curt Coder /*************************************************************************** cop410ds.c National Semiconductor COP410 Emulator. ***************************************************************************/ #include "emu.h" #include "cop410ds.h" u32 cop410_disassembler::opcode_alignment() const { return 1; } offs_t cop410_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint8_t opcode = opcodes.r8(pc); uint8_t next_opcode = opcodes.r8(pc+1); uint16_t address; uint32_t flags = 0; int bytes = 1; if ((opcode >= 0x80 && opcode <= 0xBE) || (opcode >= 0xC0 && opcode <= 0xFE)) { int page = pc >> 6; if (page == 2 || page == 3) //JP pages 2,3 { address = (uint16_t)((pc & 0x180) | (opcode & 0x7F)); util::stream_format(stream, "JP %03X", address); } else { if ((opcode & 0xC0) == 0xC0) //JP other pages { address = (uint16_t)((pc & 0x1C0) | (opcode & 0x3F)); util::stream_format(stream, "JP %03X", address); } else //JSRP { address = (uint16_t)(0x80 | (opcode & 0x3F)); util::stream_format(stream, "JSRP %03X", address); flags = STEP_OVER; } } } else if (opcode >= 0x08 && opcode <= 0x0F) { util::stream_format(stream, "LBI 0,%u", ((opcode & 0xF) + 1) & 0xF); } else if (opcode >= 0x18 && opcode <= 0x1F) { util::stream_format(stream, "LBI 1,%u", ((opcode & 0xF) + 1) & 0xF); } else if (opcode >= 0x28 && opcode <= 0x2F) { util::stream_format(stream, "LBI 2,%u", ((opcode & 0xF) + 1) & 0xF); } else if (opcode >= 0x38 && opcode <= 0x3F) { util::stream_format(stream, "LBI 3,%u", ((opcode & 0xF) + 1) & 0xF); } else if (opcode >= 0x51 && opcode <= 0x5F) { util::stream_format(stream, "AISC %u", opcode & 0xF); } else if (opcode >= 0x60 && opcode <= 0x61) { address = ((opcode & 0x01) << 8) | next_opcode; util::stream_format(stream, "JMP %03X", address); bytes = 2; } else if (opcode >= 0x68 && opcode <= 0x69) { address = ((opcode & 0x01) << 8) | next_opcode; util::stream_format(stream, "JSR %03X", address); flags = STEP_OVER; bytes = 2; } else if (opcode >= 0x70 && opcode <= 0x7F) { util::stream_format(stream, "STII %u", opcode & 0xF); } else { switch (opcode) { case 0: util::stream_format(stream, "CLRA"); break; case 1: util::stream_format(stream, "SKMBZ 0"); break; case 2: util::stream_format(stream, "XOR"); break; case 3: util::stream_format(stream, "SKMBZ 2"); break; case 4: util::stream_format(stream, "XIS 0"); break; case 5: util::stream_format(stream, "LD 0"); break; case 6: util::stream_format(stream, "X 0"); break; case 7: util::stream_format(stream, "XDS 0"); break; case 0x11: util::stream_format(stream, "SKMBZ 1"); break; case 0x13: util::stream_format(stream, "SKMBZ 3"); break; case 0x14: util::stream_format(stream, "XIS 1"); break; case 0x15: util::stream_format(stream, "LD 1"); break; case 0x16: util::stream_format(stream, "X 1"); break; case 0x17: util::stream_format(stream, "XDS 1"); break; case 0x20: util::stream_format(stream, "SKC"); break; case 0x21: util::stream_format(stream, "SKE"); break; case 0x22: util::stream_format(stream, "SC"); break; case 0x23: bytes = 2; if (next_opcode >= 0x80 && next_opcode <= 0xbf) { address = (uint16_t)(next_opcode & 0x3F); util::stream_format(stream, "XAD %u,%u", ((address & 0x30) >> 4),address & 0x0F); } else { util::stream_format(stream, "Invalid"); } break; case 0x24: util::stream_format(stream, "XIS 2"); break; case 0x25: util::stream_format(stream, "LD 2"); break; case 0x26: util::stream_format(stream, "X 2"); break; case 0x27: util::stream_format(stream, "XDS 2"); break; case 0x30: util::stream_format(stream, "ASC"); break; case 0x31: util::stream_format(stream, "ADD"); break; case 0x32: util::stream_format(stream, "RC"); break; case 0x33: bytes = 2; if (next_opcode >= 0x60 && next_opcode <= 0x6F) { util::stream_format(stream, "LEI %x", next_opcode & 0xF); } else { switch (next_opcode) { case 0x01: util::stream_format(stream, "SKGBZ 0"); break; case 0x03: util::stream_format(stream, "SKGBZ 2"); break; case 0x11: util::stream_format(stream, "SKGBZ 1"); break; case 0x13: util::stream_format(stream, "SKGBZ 3"); break; case 0x21: util::stream_format(stream, "SKGZ"); break; case 0x2A: util::stream_format(stream, "ING"); break; case 0x2E: util::stream_format(stream, "INL"); break; case 0x38: util::stream_format(stream, "HALT"); break; case 0x3A: util::stream_format(stream, "OMG"); break; case 0x3C: util::stream_format(stream, "CAMQ"); break; case 0x3E: util::stream_format(stream, "OBD"); break; default: util::stream_format(stream, "Invalid"); break; } break; } break; case 0x34: util::stream_format(stream, "XIS 3"); break; case 0x35: util::stream_format(stream, "LD 3"); break; case 0x36: util::stream_format(stream, "X 3"); break; case 0x37: util::stream_format(stream, "XDS 3"); break; case 0x40: util::stream_format(stream, "COMP"); break; case 0x42: util::stream_format(stream, "RMB 2"); break; case 0x43: util::stream_format(stream, "RMB 3"); break; case 0x44: util::stream_format(stream, "NOP"); break; case 0x45: util::stream_format(stream, "RMB 1"); break; case 0x46: util::stream_format(stream, "SMB 2"); break; case 0x47: util::stream_format(stream, "SMB 1"); break; case 0x48: util::stream_format(stream, "RET"); flags = STEP_OUT; break; case 0x49: util::stream_format(stream, "RETSK"); flags = STEP_OUT; break; case 0x4B: util::stream_format(stream, "SMB 3"); break; case 0x4C: util::stream_format(stream, "RMB 0"); break; case 0x4D: util::stream_format(stream, "SMB 0"); break; case 0x4E: util::stream_format(stream, "CBA"); break; case 0x4F: util::stream_format(stream, "XAS"); break; case 0x50: util::stream_format(stream, "CAB"); break; case 0xBF: util::stream_format(stream, "LQID"); break; case 0xFF: util::stream_format(stream, "JID"); break; default: util::stream_format(stream, "Invalid"); break; } } return bytes | flags | SUPPORTED; }