diff options
Diffstat (limited to 'src/emu/cpu/pps4/pps4.c')
-rw-r--r-- | src/emu/cpu/pps4/pps4.c | 1776 |
1 files changed, 1469 insertions, 307 deletions
diff --git a/src/emu/cpu/pps4/pps4.c b/src/emu/cpu/pps4/pps4.c index 130b70d5b39..2611bbab53e 100644 --- a/src/emu/cpu/pps4/pps4.c +++ b/src/emu/cpu/pps4/pps4.c @@ -1,5 +1,6 @@ // license:BSD-3-Clause -// copyright-holders:Miodrag Milanovic +// copyright-holders:Juergen Buchmueller <pullmoll@t-online.de> + /***************************************************************************** * * pps4.c @@ -31,300 +32,1448 @@ #include "debugger.h" #include "pps4.h" -#define VERBOSE 0 -#define LOG(x) do { if (VERBOSE) logerror x; } while (0) +#define VERBOSE 0 //!< set to 1 to log certain instruction conditions +#if VERBOSE +#define LOG(x) logerror x +#else +#define LOG(x) +#endif const device_type PPS4 = &device_creator<pps4_device>; - pps4_device::pps4_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : cpu_device(mconfig, PPS4, "PPS4", tag, owner, clock, "pps4", __FILE__ ) - , m_program_config("program", ENDIANNESS_LITTLE, 8, 12) - , m_data_config("data", ENDIANNESS_LITTLE, 8, 12) // 4bit RAM - , m_io_config("io", ENDIANNESS_LITTLE, 8, 8) // 4bit IO + : cpu_device(mconfig, PPS4, "PPS4", tag, owner, clock, "pps4", __FILE__ ) + , m_program_config("program", ENDIANNESS_LITTLE, 8, 12) + , m_data_config("data", ENDIANNESS_LITTLE, 8, 12) // 4bit RAM + , m_io_config("io", ENDIANNESS_LITTLE, 8, 8) // 4bit IO { } +/** + * @brief pps4_device::M Return the memory at address B + * @return ROM/RAM(B) + */ +UINT8 pps4_device::M() +{ + UINT8 ret = m_data->read_byte(m_B & ~m_SAG); + m_SAG = 0; + return ret; +} -offs_t pps4_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) + +/** + * @brief pps4_device::W Write to the memory address at B + * @return ROM/RAM(B) + */ +void pps4_device::W(UINT8 data) { - extern CPU_DISASSEMBLE( pps4 ); - return CPU_DISASSEMBLE_NAME(pps4)(this, buffer, pc, oprom, opram, options); + m_data->write_byte(m_B & ~m_SAG, data); + m_SAG = 0; } +offs_t pps4_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) +{ + extern CPU_DISASSEMBLE( pps4 ); + return CPU_DISASSEMBLE_NAME(pps4)(this, buffer, pc, oprom, opram, options); +} +/** + * @brief pps4_device::ROP Read the next opcode (instruction) + * @return m_I + */ inline UINT8 pps4_device::ROP() { - UINT8 retVal = m_direct->read_decrypted_byte(m_P.w.l); - m_P.w.l = (m_P.w.l + 1) & 0x0fff; - return retVal; + m_Ip = m_I & 0xf0; // set previous opcode mask + m_I = m_direct->read_decrypted_byte(m_P & 0xFFF); + m_P = (m_P + 1) & 0xFFF; + m_icount -= 1; + return m_I; } +/** + * @brief pps4_device::ARG Read the next argument (instrunction 2) + * @return m_I2 + */ inline UINT8 pps4_device::ARG() { - UINT8 retVal = m_direct->read_raw_byte(m_P.w.l); - m_P.w.l = (m_P.w.l + 1) & 0x0fff; - return retVal; -} - -inline void pps4_device::DO_SKIP() -{ - m_P.w.l = (m_P.w.l + 1) & 0x0fff; -} - -void pps4_device::execute_one(int opcode) -{ - m_icount -= 1; - switch (opcode) - { - // Arithmetic instructions - case 0x0b: // AD - break; - case 0x0a: // ADC - break; - case 0x09: // ADSK - break; - case 0x08: // ADCSK - break; - case 0x60: case 0x61: case 0x62: case 0x63: - case 0x64: case 0x66: case 0x67: case 0x68: - case 0x69: case 0x6a: case 0x6b: case 0x6c: - case 0x6d: case 0x6e: - // ADI - break; - case 0x65: //DC - m_A = (m_A + 10) & 0x0f; - break; - // Logical instructions - case 0x0d: // AND - break; - case 0x0f: // OR - break; - case 0x0c: // EOR - break; - case 0x0e: // COMP - m_A ^= 0x0f; - break; - // Data transfer instructions - case 0x20: // SC - m_C = 1; - break; - case 0x24: //RC - m_C = 0; - break; - case 0x22: // SF1 - m_FF1 = 1; - break; - case 0x26: // RF1 - m_FF1 = 0; - break; - case 0x21: // SF2 - m_FF2 = 1; - break; - case 0x25: // RF2 - m_FF2 = 0; - break; - case 0x30: case 0x31: case 0x32: case 0x33: - case 0x34: case 0x35: case 0x36: case 0x37: - // LD - break; - case 0x38: case 0x39: case 0x3a: case 0x3b: - case 0x3c: case 0x3d: case 0x3e: case 0x3f: - // EX - break; - case 0x28: case 0x29: case 0x2a: case 0x2b: - case 0x2c: case 0x2d: case 0x2e: case 0x2f: - // EXD - break; - case 0x70: case 0x71: case 0x72: case 0x73: - case 0x74: case 0x75: case 0x76: case 0x77: - case 0x78: case 0x79: case 0x7a: case 0x7b: - case 0x7c: case 0x7d: case 0x7e: case 0x7f: - // LDI - m_A = opcode & 0x0f; - break; - case 0x12: // LAX - m_A = m_X; - break; - case 0x1b: // LXA - m_X = m_A; - break; - case 0x11: // LABL - m_A = m_B.w.l & 0x00f; - break; - case 0x10: // LBMX - m_B.w.l &= 0xf0f; - m_B.w.l |= (m_X << 4); - break; - case 0x04: // LBUA - break; - case 0x19: // XABL - { - UINT8 tmp = m_B.w.l & 0x00f; - m_B.w.l &= 0xff0; - m_B.w.l |= m_A; - m_A = tmp; - } - break; - case 0x18: // XBMX - { - UINT8 tmp = (m_B.w.l & 0x0f0) >> 4; - m_B.w.l &= 0xf0f; - m_B.w.l |= (m_X << 4); - m_X = tmp; - } - break; - case 0x1a: // XAX - { - UINT8 tmp = m_A; - m_A = m_X; - m_X = tmp; - } - break; - case 0x06: // XS - { - PAIR tmp = m_SA; - m_SA = m_SB; - m_SB = tmp; - } - break; - case 0x6f: // CYS - break; - case 0xc0: case 0xc1: case 0xc2: case 0xc3: - case 0xc4: case 0xc5: case 0xc6: case 0xc7: - case 0xc8: case 0xc9: case 0xca: case 0xcb: - case 0xcc: case 0xcd: case 0xce: case 0xcf: - // LB - { - //UINT8 tmp = ARG(); - m_icount -= 1; - } - break; - case 0x00: // LBL - { - UINT8 tmp = ARG(); - m_icount -= 1; - m_B.w.l = tmp; - } - break; - case 0x17: // INCB - if ((m_B.w.l & 0x0f) == 0x0f) { - m_B.w.l &= 0xff0; - DO_SKIP(); - } else { - m_B.w.l += 1; - } - break; - case 0x1f: // DECB - if ((m_B.w.l & 0x0f) == 0x00) { - m_B.w.l |= 0x00f; - DO_SKIP(); - } else { - m_B.w.l -= 1; - } - break; - // Control transfer instructions - case 0x80: case 0x81: case 0x82: case 0x83: - case 0x84: case 0x85: case 0x86: case 0x87: - case 0x88: case 0x89: case 0x8a: case 0x8b: - case 0x8c: case 0x8d: case 0x8e: case 0x8f: - case 0x90: case 0x91: case 0x92: case 0x93: - case 0x94: case 0x95: case 0x96: case 0x97: - case 0x98: case 0x99: case 0x9a: case 0x9b: - case 0x9c: case 0x9d: case 0x9e: case 0x9f: - case 0xa0: case 0xa1: case 0xa2: case 0xa3: - case 0xa4: case 0xa5: case 0xa6: case 0xa7: - case 0xa8: case 0xa9: case 0xaa: case 0xab: - case 0xac: case 0xad: case 0xae: case 0xaf: - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - case 0xb4: case 0xb5: case 0xb6: case 0xb7: - case 0xb8: case 0xb9: case 0xba: case 0xbb: - case 0xbc: case 0xbd: case 0xbe: case 0xbf: - // T - m_P.w.l = (m_P.w.l & 0xfc0) | (opcode & 0x3f); - break; - case 0xd0: case 0xd1: case 0xd2: case 0xd3: - case 0xd4: case 0xd5: case 0xd6: case 0xd7: - case 0xd8: case 0xd9: case 0xda: case 0xdb: - case 0xdc: case 0xdd: case 0xde: case 0xdf: - case 0xe0: case 0xe1: case 0xe2: case 0xe3: - case 0xe4: case 0xe5: case 0xe6: case 0xe7: - case 0xe8: case 0xe9: case 0xea: case 0xeb: - case 0xec: case 0xed: case 0xee: case 0xef: - case 0xf0: case 0xf1: case 0xf2: case 0xf3: - case 0xf4: case 0xf5: case 0xf6: case 0xf7: - case 0xf8: case 0xf9: case 0xfa: case 0xfb: - case 0xfc: case 0xfd: case 0xfe: case 0xff: - // TM - break; - case 0x50: case 0x51: case 0x52: case 0x53: - case 0x54: case 0x55: case 0x56: case 0x57: - case 0x58: case 0x59: case 0x5a: case 0x5b: - case 0x5c: case 0x5d: case 0x5e: case 0x5f: - // TL - { - //UINT8 tmp = ARG(); - m_icount -= 1; - } - break; - case 0x01: case 0x02: case 0x03: - // TML - { - //UINT8 tmp = ARG(); - m_icount -= 1; - } - break; - case 0x15: // SKC - break; - case 0x1e: // SKZ - break; - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - case 0x48: case 0x49: case 0x4a: case 0x4b: - case 0x4c: case 0x4d: case 0x4e: case 0x4f: - // SKBI - break; - case 0x16: // SKF1 - break; - case 0x14: // SKF2 - break; - case 0x05: // RTN - break; - case 0x07: // RTNSK - break; - // Input/Output instructions - case 0x1c: // IOL - { - //UINT8 tmp = ARG(); - m_icount -= 1; - } - break; - case 0x27: // DIA - break; - case 0x23: // DIB - break; - case 0x1d: // DOA - break; - // Special instructions - case 0x13: // SAG - break; - } + m_I2 = m_direct->read_raw_byte(m_P & 0xFFF); + m_P = (m_P + 1) & 0xFFF; + m_icount -= 1; + return m_I2; +} + +/** + * @brief Note3 + * + * Instructions ADI, LD, EX, EXD, LDI, LB and LBL have a numeric + * value coded as part of the instruction in the immediate field. + * This numeric value must be in complementary form on the bus. + * All of these immediate fields which are inverted are shown + * in brackets. + * For example: ADI 1, as written by the programmer who wishes + * to add one to the value in the accumulator, is converted to + * 0x6E = 01001 [1110]; the bracketed binary value is the value + * as seen on the data bus. + * If the programmer is using the Rockwell Assembler he does not + * have to manually determine the proper inverted value as the + * assembler does this for him. + * + * [And we do in MAME as well :-] + */ + +/** + * @brief pps4_device::iAD Add + * OPCODE cycles mnemonic + * ----------------------------- + * 0000 1011 1 cyc AD + * + * Symbolic equation + * ----------------------------- + * C, A <- A + M + * + * The result of the binary addition of contents of accumulator + * and 4-bit contents of RAM currently addressed by B register, + * replaces the contents of the accumulator. The resulting + * carry-out is loaded into C flip-flop. + */ +void pps4_device::iAD() +{ + m_A = m_A + M(); + m_C = m_A >> 4; + m_A = m_A & 15; +} + +/** + * @brief pps4_device::iADC Add with carry-in + * OPCODE cycles mnemonic + * ----------------------------- + * 0000 1010 1 cyc ADC + * + * Symbolic equation + * ----------------------------- + * C, A <- A + M + C + * + * Same as AD except the C flip-flop serves as a carry-in + * to the adder. + */ +void pps4_device::iADC() +{ + m_A = m_A + M() + m_C; + m_C = m_A >> 4; + m_A = m_A & 15; +} + +/** + * @brief pps4_device::iADSK Add and skip if carry-out + * OPCODE cycles mnemonic + * ----------------------------- + * 0000 1001 1 cyc ADSK + * + * Symbolic equation + * ----------------------------- + * C, A <- A + M + * Skip if C = 1 + * + * Same as AD except the next ROM word will be + * skipped (ignored) if a carry-out is generated. + */ +void pps4_device::iADSK() +{ + m_A = m_A + M(); + m_C = m_A >> 4; + m_A = m_A & 15; + m_P = (m_P + m_C) & 0xFFF; +} + +/** + * @brief pps4_device::iADCSK Add with carry-in and skip if carry-out + * OPCODE cycles mnemonic + * ----------------------------- + * 0000 1000 1 cyc ADCSK + * + * Symbolic equation + * ----------------------------- + * C, A <- A + M + C + * Skip if C = 1 + * + * Same as ADC except the next ROM word will be + * skipped (ignored) if a carry-out is generated. + */ +void pps4_device::iADCSK() +{ + m_A = m_A + M() + m_C; + m_C = m_A >> 4; + m_A = m_A & 15; + m_P = (m_P + m_C) & 0xFFF; +} + +/** + * @brief pps4_device::iAND Logical AND + * OPCODE cycles mnemonic + * ----------------------------- + * 0000 1101 1 cyc AND + * + * Symbolic equation + * ----------------------------- + * A <- A & M + * + * The result of logical AND of accumulator and + * 4-bit contents of RAM currently addressed by + * B register replaces contents of accumulator. + */ +void pps4_device::iAND() +{ + m_A = m_A & M(); +} + +/** + * @brief pps4_device::iADI Add immediate + * OPCODE cycles mnemonic + * ----------------------------- + * 0110 xxxx 1 cyc ADI #x + * + * Symbolic equation + * ----------------------------- + * A <- A + [I(4:1)] + * + * The result of the binary addition of contents of + * accumulator and 4-bit immediate field of instruction + * word replaces the contents of accumulator. + * The next ROM word will be skipped (ignored) if a + * carry-out is generated. + * __ The instruction does not use or change the C flip-flop. __ + * The immediate field I(4:1) of this instruction may not + * be equal to binary 0 (CYS) or 0101 (DC) + * + * See %Note3 + */ +void pps4_device::iADI() +{ + const UINT8 imm = ~m_I & 15; + m_A = m_A + imm; + m_P = m_P + (m_A > 15) ? 1 : 0; + m_A = m_A & 15; + m_P = m_P & 0xFFF; +} + +/** + * @brief pps4_device::iDC Decimal correction + * OPCODE cycles mnemonic + * ----------------------------- + * 0110 0110 1 cyc DC + * + * Symbolic equation + * ----------------------------- + * A <- A + 1010b + * + * Decimal correction of accumulator. + * Binary 1010 is added to the contents of the accumulator. + * Result is stored in accumulator. Instruction does not + * use or change carry flip-flop or skip. + */ +void pps4_device::iDC() +{ + m_A = m_A + 10; +} + +/** + * @brief pps4_device::iOR Logical OR + * OPCODE cycles mnemonic + * ----------------------------- + * 0000 1111 1 cyc OR + * + * Symbolic equation + * ----------------------------- + * A <- A | M + * + * The result of logical OIR of accumulator and + * 4-bit contents of RAM currently addressed by + * B register replaces contents of accumulator. + */ +void pps4_device::iOR() +{ + m_A = m_A | M(); +} + +/** + * @brief pps4_device::iEOR Logical exclusive-OR + * OPCODE cycles mnemonic + * ----------------------------- + * 0000 1100 1 cyc EOR + * + * Symbolic equation + * ----------------------------- + * A <- A ^ M + * + * The result of logical exclusive-OR of + * accumulator and 4-bit contents of RAM + * currently addressed by B register + * replaces contents of accumulator. + */ +void pps4_device::iEOR() +{ + m_A = m_A ^ M(); +} + +/** + * @brief pps4_device::iCOMP Complement + * OPCODE cycles mnemonic + * ----------------------------- + * 0000 1110 1 cyc COMP + * + * Symbolic equation + * ----------------------------- + * A <- ~A + * + * Each bit of the accumulator is logically + * complemented and placed in accumulator. + */ +void pps4_device::iCOMP() +{ + m_A = ~m_A & 15; +} + +/** + * @brief pps4_device::iSC Set carry flip-flop + * OPCODE cycles mnemonic + * ----------------------------- + * 0010 0000 1 cyc SC + * + * Symbolic equation + * ----------------------------- + * C <- 1 + * + * The C flip-flop is set to 1. + */ +void pps4_device::iSC() +{ + m_C = 1; +} + +/** + * @brief pps4_device::iRC Reset carry flip-flop + * OPCODE cycles mnemonic + * ----------------------------- + * 0010 0100 1 cyc RC + * + * Symbolic equation + * ----------------------------- + * C <- 0 + * + * The C flip-flop is set to 0. + */ +void pps4_device::iRC() +{ + m_C = 0; +} + +/** + * @brief pps4_device::iSF1 Set flip-flop FF1 + * OPCODE cycles mnemonic + * ----------------------------- + * 0010 0010 1 cyc SF1 + * + * Symbolic equation + * ----------------------------- + * FF1 <- 1 + * + * The Flip-flop FF1 is set to 1. + */ +void pps4_device::iSF1() +{ + m_FF1 = 1; +} + +/** + * @brief pps4_device::iRF1 Reset flip-flop FF1 + * OPCODE cycles mnemonic + * ----------------------------- + * 0010 0100 1 cyc RF1 + * + * Symbolic equation + * ----------------------------- + * FF1 <- 0 + * + * The Flip-flop FF1 is set to 0. + */ +void pps4_device::iRF1() +{ + m_FF1 = 0; +} + +/** + * @brief pps4_device::iSF2 Set flip-flop FF2 + * OPCODE cycles mnemonic + * ----------------------------- + * 0010 0001 1 cyc SF2 + * + * Symbolic equation + * ----------------------------- + * FF2 <- 1 + * + * The Flip-flop FF2 is set to 1. + */ +void pps4_device::iSF2() +{ + m_FF2 = 1; +} + +/** + * @brief pps4_device::iRF2 Reset flip-flop FF2 + * OPCODE cycles mnemonic + * ----------------------------- + * 0010 0101 1 cyc RF2 + * + * Symbolic equation + * ----------------------------- + * FF2 <- 0 + * + * The flip-flop FF2 is set to 0. + */ +void pps4_device::iRF2() +{ + m_FF2 = 0; +} + +/** + * @brief pps4_device::iLD Load accumulator from memory + * OPCODE cycles mnemonic + * ----------------------------- + * 0011 0xxx 1 cyc LDx + * + * Symbolic equation + * ----------------------------- + * A <- M + * B(7:5) <- B(7:5) ^ [I(3:1)] + * + * The 4-bit contents of RAM currently addressed + * by B register are placed in the accumulator. + * The RAM address in the B register is then + * modified by the result of an exclusive-OR of + * the 3-b it immediate field I(3:1) and B(7:5) + * + * See %Note3 + */ +void pps4_device::iLD() +{ + const UINT16 imm = ~m_I & 7; + m_A = M(); + m_B = m_B ^ (imm << 4); +} + +/** + * @brief pps4_device::iEX Exchange accumulator and memory + * OPCODE cycles mnemonic + * ----------------------------- + * 0011 1xxx 1 cyc EXx + * + * Symbolic equation + * ----------------------------- + * A <-> M + * B(7:5) <- B(7:5) ^ [I(3:1)] + * + * The same as LD except the contents of accumulator + * are also placed in currently addressed RAM location. + * + * See %Note3 + */ +void pps4_device::iEX() +{ + const UINT16 imm = ~m_I & 7; + const UINT8 mem = M(); + W(m_A); + m_A = mem; + m_B = m_B ^ (imm << 4); +} + +/** + * @brief pps4_device::iEXD Exchange accumulator and memory and decrement BL + * OPCODE cycles mnemonic + * ----------------------------- + * 0010 1xxx 1 cyc EXD x + * + * Symbolic equation + * ----------------------------- + * A <-> M + * B(7:5) <- B(7:5) ^ [I(3:1)] + * BL <- BL - 1 + * Skip on BL = 1111b + * + * The same as EX except RAM address in B register + * is further modified by decrementing BL by 1. + * If the new contents of BL is 1111, the next + * ROM word will be ignored. + * + * See %Note3 + */ +void pps4_device::iEXD() +{ + const UINT8 imm = ~m_I & 7; + const UINT8 mem = M(); + UINT8 bl = m_B & 15; + W(m_A); + m_A = mem; + m_B = m_B ^ (imm << 4); + if (0 == bl) { + // decrement BL wraps to 1111b + bl = 15; + m_P = (m_P + 1) & 0xFFF; + } else { + // decrement BL + bl = bl - 1; + } + m_B = (m_B & ~15) | bl; } +/** + * @brief pps4_device::iLDI Load accumualtor immediate + * OPCODE cycles mnemonic + * ----------------------------- + * 0111 xxxx 1 cyc LDI x + * + * Symbolic equation + * ----------------------------- + * A <- [I(4:1)] + * + * The 4-bit contents, immediate field I(4:1), + * of the instruction are placed in the accumulator. + * + * Note: Only the first occurence of an LDI in a consecutive + * string of LDIs will be executed. The program will ignore + * remaining LDIs and execute next valid instruction. + * + * See %Note3 + */ +void pps4_device::iLDI() +{ + // previous LDI instruction? + if (0x70 == m_Ip) { + LOG(("%s: skip prev:%02x\n", __FUNCTION__, m_Ip)); + return; + } + m_A = ~m_I & 15; +} + +/** + * @brief pps4_device::iLAX + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 0010 1 cyc LAX + * + * Symbolic equation + * ----------------------------- + * A <- X + * + * The 4-bit contents of the X register are + * placed in the accumulator. + */ +void pps4_device::iLAX() +{ + m_A = m_X; +} + +/** + * @brief pps4_device::iLXA + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 1011 1 cyc LAX + * + * Symbolic equation + * ----------------------------- + * X <- A + * + * The contents of the accumulator are + * tansferred to the X register. + */ +void pps4_device::iLXA() +{ + m_X = m_A; +} + +/** + * @brief pps4_device::iLABL + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 0001 1 cyc LABL + * + * Symbolic equation + * ----------------------------- + * A <- BL + * + * The contents of BL register are + * tansferred to the accumulator. + */ +void pps4_device::iLABL() +{ + m_A = m_B & 15; +} + +/** + * @brief pps4_device::iLBMX + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 0000 1 cyc LBMX + * + * Symbolic equation + * ----------------------------- + * BM <- X + * + * The contents of X register are + * tansferred to BM register. + */ +void pps4_device::iLBMX() +{ + m_B = (m_B & ~(15 << 4)) | (m_X << 4); +} + +/** + * @brief pps4_device::iLBUA + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 0000 1 cyc LBUA + * + * Symbolic equation + * ----------------------------- + * BU <- A + * A <- M + * + * The contents of accumulator are tansferred to + * BU register. Also, the contents of the currently + * addressed RAM are transferred to accumulator. + */ +void pps4_device::iLBUA() +{ + m_B = (m_B & ~(15 << 8)) | (m_A << 8); + m_A = M(); +} + +/** + * @brief pps4_device::iXABL + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 1001 1 cyc XABL + * + * Symbolic equation + * ----------------------------- + * A <-> BL + * + * The contents of accumulator and BL register + * are exchanged. + */ +void pps4_device::iXABL() +{ + // swap A and BL + UINT8 bl = m_B & 15; + m_B = (m_B & ~15) | m_A; + m_A = bl; +} + +/** + * @brief pps4_device::iXMBX + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 1000 1 cyc XMBX + * + * Symbolic equation + * ----------------------------- + * X <-> BM + * + * The contents of accumulator and BL register + * are exchanged. + */ +void pps4_device::iXBMX() +{ + // swap X and BM + UINT8 bm = (m_B >> 4) & 15; + m_B = (m_B & ~(15 << 4)) | (m_X << 4); + m_X = bm; +} + +/** + * @brief pps4_device::iXAX + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 1010 1 cyc XAX + * + * Symbolic equation + * ----------------------------- + * A <-> X + * + * The contents of accumulator and X register + * are exchanged. + */ +void pps4_device::iXAX() +{ + // swap A and X + m_A ^= m_X; + m_X ^= m_A; + m_A ^= m_X; +} + +/** + * @brief pps4_device::iXS + * OPCODE cycles mnemonic + * ----------------------------- + * 0000 0110 1 cyc XS + * + * Symbolic equation + * ----------------------------- + * SA <-> SB + * + * The 12-bit contents of SA and SB register + * are exchanged. + */ +void pps4_device::iXS() +{ + // swap SA and SB + m_SA ^= m_SB; + m_SB ^= m_SA; + m_SA ^= m_SB; +} + +/** + * @brief pps4_device::iCYS + * OPCODE cycles mnemonic + * ----------------------------- + * 0110 1111 1 cyc CYS + * + * Symbolic equation + * ----------------------------- + * A <- SA(4:1) + * SA(4:1) <- SA(8:5) + * SA(8:5) <- SA(12:9) + * SA(12:9) <- A + * + * A 4-bit right shift of the SA register takes place + * with the four bits which are shifted off the end + * of SA being transferred into the accumulator. + * The contents of the accumulator are placed in the + * left end of the SA register + * + */ +void pps4_device::iCYS() +{ + const UINT16 sa = (m_SA >> 4) | (m_A << 12); + m_A = m_SA & 15; + m_SA = sa; +} + +/** + * @brief pps4_device::iLB + * OPCODE cycles mnemonic + * ----------------------------- + * 1100 0000 2 cyc LB + * + * Symbolic equation + * ----------------------------- + * SB <- SA, SA <- P + * P(12:5) <- 0000 1100 + * P(4:1) <- I(4:1) + * + * BU <- 0000 + * B(8:1) <- [I2(8:1)] + * P <- SA, SA <-> SB + * + * Sixteen consecutive locations on ROM page 3 (I2) contain + * data which can be loaded into the eight least significant + * bits of the B register by use of any LB instruction. + * The four most significant bits of B register will be loaded + * with zeros. The contents of the SB register will be destroyed. + * This instruction takes two cycles to execute but occupies + * only one ROM word. (Automatic return) + * + * Only the first occurence of an LB or LBL instruction in a + * consecutive string of LB or LBL will be executed. The + * program will ignore the remaining LB or LBL and execute + * the next valid instruction. Within subroutines the LB + * instruction must be used with caution because the contents + * of SB have been modified. + * + * See %Note3 and %Note4 + */ +void pps4_device::iLB() +{ + // previous LB or LBL instruction? + if (0xc0 == m_Ip|| 0x00 == m_Ip) { + LOG(("%s: skip prev:%02X\n", __FUNCTION__, m_Ip)); + return; + } + m_SB = m_SA; + m_SA = (m_P + 1) & 0xFFF; + m_P = (3 << 8) | (m_I & 15); + m_B = ~ARG() & 255; + m_P = m_SA; + // swap SA and SB + m_SA ^= m_SB; + m_SB ^= m_SA; + m_SA ^= m_SB; +} + +/** + * @brief pps4_device::iLBL + * OPCODE cycles mnemonic + * ----------------------------- + * 0000 0000 2 cyc LBL + * + * Symbolic equation + * ----------------------------- + * BU <- 0000 + * B(8:1) <- [I2(8:1)] + * + * This instruction occupies two ROM words, the second of + * which will be loaded into the eight least significant + * bits of the B register. The four most significant bits + * of B (BU) will be loaded with zeroes. + * + * Only the first occurence of an LB or LBL instruction in a + * consecutive string of LB or LBL will be executed. The + * program will ignore the remaining LB or LBL and execute + * the next valid instruction. + * + * See %Note3 + */ +void pps4_device::iLBL() +{ + // previous LB or LBL instruction? + if (0xc0 == m_Ip || 0x00 == m_Ip) { + LOG(("%s: skip prev:%02X\n", __FUNCTION__, m_Ip)); + return; + } + m_B = ~ARG() & 255; +} + +/** + * @brief pps4_device::INCB + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 0111 1 cyc INCB + * + * Symbolic equation + * ----------------------------- + * BL <- BL + 1 + * Skip on BL = 0000 + * + * BL register (least significant four bits of B register) + * is incremented by 1. If the new contents of BL is 0000b, + * then the next ROM word will be ignored. + */ +void pps4_device::iINCB() +{ + UINT8 bl = m_B & 15; + bl = (bl + 1) & 15; + if (0 == bl) { + LOG(("%s: skip BL=%x\n", __FUNCTION__, bl)); + m_P = (m_P + 1) & 0xFFF; + } + m_B = (m_B & ~15) | bl; +} + +/** + * @brief pps4_device::iDECB + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 1111 1 cyc DECB + * + * Symbolic equation + * ----------------------------- + * BL <- BL - 1 + * Skip on BL = 1111 + * + * BL register is decremented by 1. If the new + * contents of BL is 1111b, then the next ROM + * word will be ignored. + */ +void pps4_device::iDECB() +{ + UINT8 bl = m_B & 15; + bl = (bl - 1) & 15; + if (15 == bl) { + LOG(("%s: skip BL=%x\n", __FUNCTION__, bl)); + m_P = (m_P + 1) & 0xFFF; + } + m_B = (m_B & ~15) | bl; +} + +/** + * @brief pps4_device::iT Transfer + * OPCODE cycles mnemonic + * ----------------------------- + * 10xx xxxx 1 cyc T * + * + * Symbolic equation + * ----------------------------- + * P(6:1) <- I(6:1) + * + * An unconditional transfer to a ROM word on the current + * page takes place. The least significant 6-bits of P + * register P(6:1) are replaced by six bit immediate + * field I(6:1) + */ +void pps4_device::iT() +{ + const UINT16 p = (m_P & ~63) | (m_I & 63); + LOG(("%s: P=%03x I=%02x -> P=%03x\n", __FUNCTION__, m_P, m_I, p)); + m_P = p; +} + +/** + * @brief pps4_device::iTM Transfer and mark indirect + * OPCODE cycles mnemonic + * ----------------------------- + * 11xx xxxx 2 cyc TM * + * yyyy yyyy from page 3 + * + * Symbolic equation + * ----------------------------- + * SB <- SA, SA <- P + * P(12:7) <- 000011 + * P(6:1) <- I1(6:1) + * + * P(12:9) <- 0001 + * P(8:1) <- I2(8:1) + * + * 48 consecutive locations on ROM page 3 contains pointer data + * which indentify subroutine entry addresses. These subroutine + * entry addresses are limited to pages 4 through 7. This TM + * instruction will save the address of the next ROM word in + * the SA register after loading the original contents of SA + * into SB. A transfer then occurs to one of the subroutine + * entry addresses. This instruction occupies one ROM word + * but takes two cycles for execution. + */ +void pps4_device::iTM() +{ + m_SB = m_SA; + m_SA = m_P; + m_P = 3 << 6; + m_P = m_P | (m_I & 63); + ARG(); + m_P = 1 << 8; + m_P |= m_I2; +} + +/** + * @brief pps4_device::iTL Transfer long + * OPCODE cycles mnemonic + * ----------------------------- + * 0101 xxxx 2 cyc TL * + * yyyy yyyy + * + * Symbolic equation + * ----------------------------- + * P(12:9) <- I1(4:1) + * P(8:1) <- I2(8:1) + * + * The instruction executes a transfer to any ROM word on any + * page. It occupies two ROM words an requires two cycles for + * execution. The first byte loads P(12:9) with field I1(4:1) + * and then the second byte I2(8:1) is placed in P(8:1). + */ +void pps4_device::iTL() +{ + ARG(); + m_P = (m_I & 15) << 8; + m_P = m_P | m_I2; +} + +/** + * @brief pps4_device::iTML Transfer and mark long + * OPCODE cycles mnemonic + * ----------------------------- + * 0101 xxxx 2 cyc TML * + * yyyy yyyy + * + * Symbolic equation + * ----------------------------- + * SB <- SA, SA <- P + * P(12:9) <- I1(4:1) + * P(8:1) <- I2(8:1) + * + * Note I1(2:1) != 00 + * + * This instruction executes a transfer and mark to any + * location on ROM pages 4 through 15. It occupies two + * ROM words and requires two cycle times for execution. + */ +void pps4_device::iTML() +{ + ARG(); + m_SB = m_SA; + m_SA = m_P; + m_P = (m_I & 15) << 8; + m_P = m_P | m_I2; +} + +/** + * @brief pps4_device::iSKC Skip on carry flip-flop + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 0101 1 cyc SKC + * + * Symbolic equation + * ----------------------------- + * Skip if C = 1 + * + * The next ROM word will be ignored if C flip-flop is 1. + */ +void pps4_device::iSKC() +{ + m_P = m_P + m_C; + m_P = m_P & 0xFFF; +} + +/** + * @brief pps4_device::iSKC Skip on carry flip-flop + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 1110 1 cyc SKZ + * + * Symbolic equation + * ----------------------------- + * Skip if A = 0 + * + * The next ROM word will be ignored if C flip-flop is 1. + */ +void pps4_device::iSKZ() +{ + m_P = m_P + (0 == m_A) ? 1 : 0; + m_P = m_P & 0xFFF; +} + +/** + * @brief pps4_device::iSKBI Skip if BL equal to immediate + * OPCODE cycles mnemonic + * ----------------------------- + * 0100 xxxx 1 cyc SKBI x + * + * Symbolic equation + * ----------------------------- + * Skip if BL = I(4:1) + * + * The next ROM word will be ignored if the least significant + * four bits of B register (BL) is equal to the 4-bit immediate + * field I(4:1) of instruction. + */ +void pps4_device::iSKBI() +{ + const unsigned imm = m_I & 15; + m_P = m_P + (imm == (m_B & 15)) ? 1 : 0; + m_P = m_P & 0xFFF; +} + +/** + * @brief pps4_device::iSKF1 Skip if FF1 equals 1 + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 0110 1 cyc SKF1 + * + * Symbolic equation + * ----------------------------- + * Skip if FF1 = 1 + */ +void pps4_device::iSKF1() +{ + m_P = m_P + m_FF1; + m_P = m_P & 0xFFF; +} + +/** + * @brief pps4_device::iSKF2 Skip if FF2 equals 1 + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 0100 1 cyc SKF2 + * + * Symbolic equation + * ----------------------------- + * Skip if FF2 = 1 + */ +void pps4_device::iSKF2() +{ + m_P = m_P + m_FF2; + m_P = m_P & 0xFFF; +} + +/** + * @brief pps4_device::iRTN Return + * OPCODE cycles mnemonic + * ----------------------------- + * 0000 0101 1 cyc RET + * + * Symbolic equation + * ----------------------------- + * P <- SA, SA <-> SB + * + * This instruction executes a return from subroutine + * by loading contents of SA register into P register + * and interchanges the SB and SA registers. + */ +void pps4_device::iRTN() +{ + m_P = m_SA; + // swap SA and SB + m_SA ^= m_SB; + m_SB ^= m_SA; + m_SA ^= m_SB; +} + +/** + * @brief pps4_device::iRTN Return + * OPCODE cycles mnemonic + * ----------------------------- + * 0000 0111 1 cyc RETSK + * + * Symbolic equation + * ----------------------------- + * P <- SA, SA <-> SB + * P <- P + 1 + * + * Same as RTN expect the first ROM word encountered + * after the return from subroutine is skipped. + */ +void pps4_device::iRTNSK() +{ + m_P = m_SA; + ROP(); // ignored + m_I = 0; // avoid LB/LBL or LDI skipping + // swap SA and SB + m_SA ^= m_SB; + m_SB ^= m_SA; + m_SA ^= m_SB; + m_P = m_P & 0xFFF; +} + +/** + * @brief pps4_device::IOL + * OPCODE cycles mnemonic + * ----------------------------- + * 0001 1100 2 cyc IOL + * yyyy yyyy + * + * Symbolic equation + * ----------------------------- + * ~A -> Data Bus + * A <- ~Data Bus + * I2 -> I/O device + * + * This instruction occupies two ROM words and requires two + * cycles for execution. The first ROM word is received by + * the CPU and sets up the I/O enable signal. The second + * ROM word is then received by the I/O devices and decoded + * for address and command. The contents of the accumulator + * inverted are placed on the data lines for acceptance by + * the I/O. At the same time, input data received by the I/O + * device is transferred to the accumulator inverted. + */ +void pps4_device::iIOL() +{ + const unsigned a = ~m_A & 15; + ARG(); + LOG(("%s: port:%X <- %02X\n", __FUNCTION__, m_I2, a)); + m_io->write_byte(m_I2, a); + m_A = ~m_io->read_byte(m_I2) & 15; + LOG(("%s: port:%X -> %02X\n", __FUNCTION__, m_I2, m_A)); +} + +/** + * @brief pps4_device::iDIA Discrete input group A + * OPCODE cycles mnemonic + * ----------------------------- + * 0010 0111 1 cyc DIA + * + * Symbolic equation + * ----------------------------- + * A <- DIA + * + * Data at the inputs to discrete group A is + * transferred to the accumulator. + */ +void pps4_device::iDIA() +{ + m_A = m_io->read_byte(PPS4_PORT_A); +} + +/** + * @brief pps4_device::iDIB Discrete input group B + * OPCODE cycles mnemonic + * ----------------------------- + * 0010 0011 1 cyc DIB + * + * Symbolic equation + * ----------------------------- + * A <- DIB + * + * Data at the inputs to discrete group B is + * transferred to the accumulator. + */ +void pps4_device::iDIB() +{ + m_A = m_io->read_byte(PPS4_PORT_B); +} + +/** + * @brief pps4_device::iDIA Discrete input group A + * OPCODE cycles mnemonic + * ----------------------------- + * 0010 1101 1 cyc DOA + * + * Symbolic equation + * ----------------------------- + * DOA <- A + * + * The contents of the accumulator are transferred + * to the discrete output register. + */ +void pps4_device::iDOA() +{ + m_io->write_byte(PPS4_PORT_A, m_A); +} + +/** + * @brief pps4_device::iSAG Special address generation + * OPCODE cycles mnemonic + * ----------------------------- + * 0010 1101 1 cyc SAG + * + * Symbolic equation + * ----------------------------- + * A/B Bus (12:5) <- 0000 0000 + * A/B Bus (4:1) <- BL(4:1) + * Contents of B remains unchanged + * + * The instruction causes the eight most significant bits + * of the RAM address output to be zeroed during the next + * cycle only. Note that this instruction does not alter + * the contents of the B register. + */ +void pps4_device::iSAG() +{ + // mask bits 12:5 + m_SAG = 0xff0; +} /*************************************************************************** COMMON EXECUTION ***************************************************************************/ +void pps4_device::execute_one() +{ + m_I = ROP(); + switch (m_I) { + case 0x00: + iLBL(); + break; + case 0x01: + iTML(); + break; + case 0x02: + iTML(); + break; + case 0x03: + iTML(); + break; + case 0x04: + iLBUA(); + break; + case 0x05: + iRTN(); + break; + case 0x06: + iXS(); + break; + case 0x07: + iRTNSK(); + break; + case 0x08: + iADCSK(); + break; + case 0x09: + iADSK(); + break; + case 0x0a: + iADC(); + break; + case 0x0b: + iAD(); + break; + case 0x0c: + iEOR(); + break; + case 0x0d: + iAND(); + break; + case 0x0e: + iCOMP(); + break; + case 0x0f: + iOR(); + break; + + case 0x10: + iLBMX(); + break; + case 0x11: + iLABL(); + break; + case 0x12: + iLAX(); + break; + case 0x13: + iSAG(); + break; + case 0x14: + iSKF2(); + break; + case 0x15: + iSKC(); + break; + case 0x16: + iSKF1(); + break; + case 0x17: + iINCB(); + break; + case 0x18: + iXBMX(); + break; + case 0x19: + iXABL(); + break; + case 0x1a: + iXAX(); + break; + case 0x1b: + iLXA(); + break; + case 0x1c: + iIOL(); + break; + case 0x1d: + iDOA(); + break; + case 0x1e: + iSKZ(); + break; + case 0x1f: + iDECB(); + break; + + case 0x20: + iSC(); + break; + case 0x21: + iSF2(); + break; + case 0x22: + iSF1(); + break; + case 0x23: + iDIB(); + break; + case 0x24: + iRC(); + break; + case 0x25: + iRF2(); + break; + case 0x26: + iRF1(); + break; + case 0x27: + iDIA(); + break; + + case 0x28: case 0x29: case 0x2a: case 0x2b: + case 0x2c: case 0x2d: case 0x2e: case 0x2f: + iEXD(); + break; + + case 0x30: case 0x31: case 0x32: case 0x33: + case 0x34: case 0x35: case 0x36: case 0x37: + iLD(); + break; + + case 0x38: case 0x39: case 0x3a: case 0x3b: + case 0x3c: case 0x3d: case 0x3e: case 0x3f: + iEX(); + break; + + case 0x40: case 0x41: case 0x42: case 0x43: + case 0x44: case 0x45: case 0x46: case 0x47: + case 0x48: case 0x49: case 0x4a: case 0x4b: + case 0x4c: case 0x4d: case 0x4e: case 0x4f: + iSKBI(); + break; + + case 0x50: case 0x51: case 0x52: case 0x53: + case 0x54: case 0x55: case 0x56: case 0x57: + case 0x58: case 0x59: case 0x5a: case 0x5b: + case 0x5c: case 0x5d: case 0x5e: case 0x5f: + iTL(); + break; + + case 0x65: + iDC(); + break; + + case 0x60: case 0x61: case 0x62: case 0x63: + case 0x64: case 0x66: case 0x67: + case 0x68: case 0x69: case 0x6a: case 0x6b: + case 0x6c: case 0x6d: case 0x6e: + iADI(); + break; + + case 0x6f: + iCYS(); + break; + + case 0x70: case 0x71: case 0x72: case 0x73: + case 0x74: case 0x75: case 0x76: case 0x77: + case 0x78: case 0x79: case 0x7a: case 0x7b: + case 0x7c: case 0x7d: case 0x7e: case 0x7f: + iLDI(); + break; + + case 0x80: case 0x81: case 0x82: case 0x83: + case 0x84: case 0x85: case 0x86: case 0x87: + case 0x88: case 0x89: case 0x8a: case 0x8b: + case 0x8c: case 0x8d: case 0x8e: case 0x8f: + case 0x90: case 0x91: case 0x92: case 0x93: + case 0x94: case 0x95: case 0x96: case 0x97: + case 0x98: case 0x99: case 0x9a: case 0x9b: + case 0x9c: case 0x9d: case 0x9e: case 0x9f: + case 0xa0: case 0xa1: case 0xa2: case 0xa3: + case 0xa4: case 0xa5: case 0xa6: case 0xa7: + case 0xa8: case 0xa9: case 0xaa: case 0xab: + case 0xac: case 0xad: case 0xae: case 0xaf: + case 0xb0: case 0xb1: case 0xb2: case 0xb3: + case 0xb4: case 0xb5: case 0xb6: case 0xb7: + case 0xb8: case 0xb9: case 0xba: case 0xbb: + case 0xbc: case 0xbd: case 0xbe: case 0xbf: + iT(); + break; + + + case 0xc0: case 0xc1: case 0xc2: case 0xc3: + case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: + case 0xcc: case 0xcd: case 0xce: case 0xcf: + iLB(); + break; + + default: + iTM(); + } +} + void pps4_device::execute_run() { - do - { - debugger_instruction_hook(this, m_P.d); - execute_one(ROP()); + do + { + debugger_instruction_hook(this, m_P); + execute_one(); - } while (m_icount > 0); + } while (m_icount > 0); } /*************************************************************************** @@ -333,44 +1482,51 @@ void pps4_device::execute_run() void pps4_device::device_start() { - m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); - m_data = &space(AS_DATA); - m_io = &space(AS_IO); - - save_item(NAME(m_A)); - save_item(NAME(m_X)); - save_item(NAME(m_P)); - save_item(NAME(m_SA)); - save_item(NAME(m_SB)); - save_item(NAME(m_B)); - save_item(NAME(m_C)); - save_item(NAME(m_FF1)); - save_item(NAME(m_FF2)); - - state_add( PPS4_PC, "PC", m_P.d ).mask(0xfff).formatstr("%03X"); - state_add( PPS4_A, "A", m_A ).formatstr("%02X"); // TODO: size? - state_add( PPS4_X, "X", m_X ).formatstr("%02X"); // TODO: size? - state_add( PPS4_SA, "SA", m_SA.d ).formatstr("%04X"); // TODO: size? - state_add( PPS4_SB, "SB", m_SB.d ).formatstr("%04X"); // TODO: size? - state_add( PPS4_B, "B", m_B.d ).formatstr("%04X"); // TODO: size? - state_add( STATE_GENPC, "GENPC", m_P.d ).noshow(); - state_add( STATE_GENFLAGS, "GENFLAGS", m_C ).formatstr("%3s").noshow(); - - m_icountptr = &m_icount; + m_program = &space(AS_PROGRAM); + m_direct = &m_program->direct(); + m_data = &space(AS_DATA); + m_io = &space(AS_IO); + + save_item(NAME(m_A)); + save_item(NAME(m_X)); + save_item(NAME(m_P)); + save_item(NAME(m_SA)); + save_item(NAME(m_SB)); + save_item(NAME(m_SAG)); + save_item(NAME(m_B)); + save_item(NAME(m_C)); + save_item(NAME(m_FF1)); + save_item(NAME(m_FF2)); + save_item(NAME(m_I)); + save_item(NAME(m_I2)); + save_item(NAME(m_Ip)); + + state_add( PPS4_PC, "PC", m_P ).mask(0xFFF).formatstr("%03X"); + state_add( PPS4_A, "A", m_A ).formatstr("%01X"); + state_add( PPS4_X, "X", m_X ).formatstr("%01X"); + state_add( PPS4_SA, "SA", m_SA ).formatstr("%03X"); + state_add( PPS4_SB, "SB", m_SB ).formatstr("%03X"); + state_add( PPS4_B, "B", m_B ).formatstr("%03X"); + state_add( PPS4_SAG, "SAG", m_SAG ).formatstr("%03X"); + state_add( PPS4_I2, "I2", m_I2 ).formatstr("%02X").noshow(); + state_add( PPS4_Ip, "Ip", m_Ip ).formatstr("%02X").noshow(); + state_add( STATE_GENPC, "GENPC", m_P ).noshow(); + state_add( STATE_GENFLAGS, "GENFLAGS", m_C).formatstr("%3s").noshow(); + + m_icountptr = &m_icount; } void pps4_device::state_string_export(const device_state_entry &entry, astring &string) { - switch (entry.index()) - { - case STATE_GENFLAGS: - string.printf("%c%c%c", - m_C ? 'C':'.', - m_FF1 ? '1':'.', - m_FF2 ? '2':'.'); - break; - } + switch (entry.index()) + { + case STATE_GENFLAGS: + string.printf("%c%c%c", + m_C ? 'C':'.', + m_FF1 ? '1':'.', + m_FF2 ? '2':'.'); + break; + } } /*************************************************************************** @@ -379,11 +1535,17 @@ void pps4_device::state_string_export(const device_state_entry &entry, astring & void pps4_device::device_reset() { - m_A = m_X = 0; - m_C = m_FF1 = m_FF2 = 0; - - m_P.d = 0; - m_SA.d = 0; - m_SB.d = 0; - m_B.d = 0; + m_A = 0; // Accumulator A(4:1) + m_X = 0; // X register X(4:1) + m_P = 0; // program counter P(12:1) + m_SA = 0; // Shift register SA(12:1) + m_SB = 0; // Shift register SB(12:1) + m_SAG = 0; // Special address generation mask + m_B = 0; // B address register B(12:1) (BL, BM and BU) + m_C = 0; // Carry flip-flop + m_FF1 = 0; // Flip-flop 1 + m_FF2 = 0; // Flip-flop 2 + m_I = 0; // Most recent instruction I(8:1) + m_I2 = 0; // Most recent parameter I2(8:1) + m_Ip = 0; // Previous instruction I(8:1) } |