void tlcs870_device::do_LD_inpp_indirectbit_CF(const uint8_t opbyte0, const uint8_t opbyte1) { /* OP (opbyte0) (immval0) (opbyte1) (immval1) (immval2) JF ZF CF HF cycles LD (DE).g, CF 1110 1ggg 1001 1010 1 - - - 5 LD (HL).g, CF 1110 1ggg 1001 1011 1 - - - 5 */ m_cycles = 5; const uint8_t bitpos = get_reg8(opbyte0 & 7) & 0x7; const uint8_t bitused = 1 << bitpos; const uint16_t addr = get_reg16((opbyte1 & 1) + 2); // DE or HL uint8_t val = RM8(addr); if (is_CF()) // if carry flag is set, set the bit in val { val |= bitused; } else // if carry flag isn't set, clear the bit in val { val &= ~bitused; } // for this optype of operation ( LD *.b, CF ) the Jump Flag always ends up being 1 set_JF(); WM8(addr, val); }
void tlcs870_device::do_CPL_inpp_indirectbit(const uint8_t opbyte0, const uint8_t opbyte1) { /* OP (opbyte0) (immval0) (opbyte1) (immval1) (immval2) JF ZF CF HF cycles CPL (DE).g 1110 1ggg 1001 0010 Z * - - 5 CPL (HL).g 1110 1ggg 1001 0011 Z * - - 5 */ m_cycles = 5; const uint8_t bitpos = get_reg8(opbyte0 & 7) & 0x7; const uint8_t bitused = 1 << bitpos; const uint16_t addr = get_reg16((opbyte1 & 1) + 2); // DE or HL m_read_input_port = 0; // reads output latch, not actual ports if accessing memory mapped ports uint8_t val = RM8(addr); uint8_t bit = val & bitused; if (bit) // if the bit is set, clear the zero/jump flags and unset the bit { clear_ZF(); clear_JF(); val &= ~bitused; } else // if the bit isn't set, set the zero/jump flags and set the bit { set_ZF(); set_JF(); val |= bitused; } WM8(addr, val); }
void tlcs870_device::do_CLR_inppbit(const uint8_t opbyte0, const uint8_t opbyte1) { /* OP (opbyte0) (immval0) (opbyte1) (immval1) (immval2) JF ZF CF HF cycles CLR (DE).g 1110 1ggg 1000 1010 Z * - - 5 CLR (HL).g 1110 1ggg 1000 1011 Z * - - 5 */ m_cycles = 5; const uint8_t bitpos = get_reg8(opbyte0 & 7) & 0x7; const uint8_t bitused = 1 << bitpos; const uint16_t addr = get_reg16((opbyte1 & 1) + 2); // DE or HL m_read_input_port = 0; // reads output latch, not actual ports if accessing memory mapped ports uint8_t val = RM8(addr); if (val & bitused) // Zero flag gets set based on original value of bit? { clear_ZF(); clear_JF(); // 'Z' (so copy Z flag?) } else { set_ZF(); set_JF(); // 'Z' } val &= ~bitused; WM8(addr, val); }
void tlcs870_device::do_SET_inppbit(const uint8_t opbyte0, const uint8_t opbyte1) { /* OP (opbyte0) (immval0) (opbyte1) (immval1) (immval2) JF ZF CF HF cycles SET (DE).g 1110 1ggg 1000 0010 Z * - - 5 SET (HL).g 1110 1ggg 1000 0011 Z * - - 5 */ m_cycles = 5; const uint8_t bitpos = get_reg8(opbyte0 & 7) & 0x7; const uint8_t bitused = 1 << bitpos; const uint16_t addr = get_reg16((opbyte1 & 1) + 2); // DE or HL uint8_t val = RM8(addr); if (val & bitused) // Zero flag gets set based on original value of bit? { clear_ZF(); clear_JF(); // 'Z' (so copy Z flag?) } else { set_ZF(); set_JF(); // 'Z' } val |= bitused; WM8(addr, val); }
void tlcs870_device::do_RETN(const uint8_t opbyte0, const uint8_t opbyte1) { // with E8 only if (opbyte0 == 0xe8) { /* Return from non-maskable interrupt service (how does this differ from RETI?) OP (opbyte0) (immval0) (opbyte1) (immval1) (immval2) JF ZF CF HF cycles RETN 1110 1000 0000 0100 * * * * 7 */ m_cycles = 7; m_sp.d += 3; m_addr = RM16(m_sp.d - 2); set_PSW(RM8(m_sp.d - 1)); } else { do_regprefixtype_oprand_illegal(opbyte0, opbyte1); } }
void tlcs870_device::do_LD_CF_inpp_indirectbit(const uint8_t opbyte0, const uint8_t opbyte1) { /* OP (opbyte0) (immval0) (opbyte1) (immval1) (immval2) JF ZF CF HF cycles LD CF, (DE).g 1110 1ggg 1001 1110 ~C - * - 4 LD CF, (HL).g 1110 1ggg 1001 1111 ~C - * - 4 aka aka TEST (pp).g */ m_cycles = 4; const uint8_t bitpos = get_reg8(opbyte0 & 7) & 0x7; const uint8_t bitused = 1 << bitpos; const uint16_t addr = get_reg16((opbyte1 & 1) + 2); // DE or HL const uint8_t val = RM8(addr); const uint8_t bit = val & bitused; bit ? set_CF() : clear_CF(); // for this optype of operation ( LD CF, *.b ) the Jump Flag always ends up the inverse of the Carry Flag bit ? clear_JF() : set_JF(); }
void code3(int mode, LPSYMBOL s1, LPSYMBOL s2, LPSYMBOL s3) { switch (mode) { case AM_RR8: RR8(s1->instr, s2->val8, s3->val8); break; case AM_RI8: RI8(s1->instr, s2->val8, s3->val8); break; case AM_RM8: RM8(s1->instr, s2->val8, s3->val8); break; case AM_RA8: RA8(s1->instr, s2->val8, s3->val16); break; case AM_RR16: RR16(s1->instr, s2->val8, s3->val8); break; case AM_RI16: RI16(s1->instr, s2->val8, s3->val16); break; case AM_RM16: RM16(s1->instr, s2->val8, s3->val8); break; case AM_RA16: RA16(s1->instr, s2->val8, s3->val16); break; case AM_MR8: MR8(s1->instr, s2->val8, s3->val8); break; case AM_MR16: MR16(s1->instr, s2->val8, s3->val8); break; case AM_M8I8: M8I8(s1->instr, s2->val8, s3->val8); break; case AM_M16I8: M16I8(s1->instr, s2->val8, s3->val8); break; case AM_MI16: MI16(s1->instr, s2->val8, s3->val16); break; case AM_AR8: AR8(s1->instr, s2->val16, s3->val8); break; case AM_AR16: AR16(s1->instr, s2->val16, s3->val8); break; case AM_A8I8: A8I8(s1->instr, s2->val16, s3->val8); break; case AM_A16I8: A16I8(s1->instr, s2->val16, s3->val8); break; case AM_AI16: AI16(s1->instr, s2->val16, s3->val16); break; default: break; } }