diff options
Diffstat (limited to 'src/devices/cpu/upd177x/upd177x.cpp')
-rw-r--r-- | src/devices/cpu/upd177x/upd177x.cpp | 794 |
1 files changed, 794 insertions, 0 deletions
diff --git a/src/devices/cpu/upd177x/upd177x.cpp b/src/devices/cpu/upd177x/upd177x.cpp new file mode 100644 index 00000000000..b5cd302312f --- /dev/null +++ b/src/devices/cpu/upd177x/upd177x.cpp @@ -0,0 +1,794 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/* + +TODO: +- Only upd1771c supported +- Noise, time, and external interrupts not implemented +- CH1/CH2 not implemented +- Not all instructions implemented + +*/ + +#include "emu.h" +#include "upd177x.h" +#include "upd177xd.h" + +#define VERBOSE 0 +#include "logmacro.h" + + +DEFINE_DEVICE_TYPE(UPD1771C, upd1771c_cpu_device, "upd1771c", "NEC uPD1771C") + + +enum +{ + UPD177X_PC, UPD177X_SP, + UPD177X_A, UPD177X_A_SAVE, UPD177X_H, UPD177X_N, UPD177X_X, UPD177X_Y, + UPD177X_TIMER, UPD177X_PNC1, UPD177X_PNC2, + UPD177X_PA, UPD177X_PB, UPD177X_MD0, UPD177X_MD1, UPD177X_SKIP, UPD177X_SKIP_SAVE +}; + + +static constexpr u8 INT_TONE1 = 1 << 0; +static constexpr u8 INT_TONE2 = 1 << 1; +static constexpr u8 INT_TONE3 = 1 << 2; +static constexpr u8 INT_TONE4 = 1 << 3; +static constexpr u8 INT_NOISE = 1 << 4; +static constexpr u8 INT_EXT = 1 << 5; +static constexpr u8 INT_TIME = 1 << 6; + +static constexpr u8 MD0_3264_BIT = 0; +static constexpr u8 MD0_TN_BIT = 1; +static constexpr u8 MD0_NS_BIT = 2; +static constexpr u8 MD0_NSF1_BIT = 3; +static constexpr u8 MD0_NSF2_BIT = 4; +static constexpr u8 MD0_OUT_BIT = 5; +static constexpr u8 MD0_IF_BIT = 6; +static constexpr u8 MD1_NSF3_BIT = 0; +static constexpr u8 MD1_TIME_BIT = 1; +static constexpr u8 MD1_EXT_BIT = 2; + +static constexpr u16 VECTOR_TONE1 = 0x20; +static constexpr u16 VECTOR_TONE2 = 0x24; +static constexpr u16 VECTOR_TONE3 = 0x28; +static constexpr u16 VECTOR_TONE4 = 0x2c; +static constexpr u16 VECTOR_NOISE = 0x48; +static constexpr u16 VECTOR_EXT = 0x60; +static constexpr u16 VECTOR_TIME = 0x80; + +static constexpr u8 STACK_START = 0x20; + + +upd177x_cpu_device::upd177x_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : cpu_device(mconfig, type, tag, owner, clock) + , device_sound_interface(mconfig, *this) + , m_program_config("program", ENDIANNESS_LITTLE, 16, 16, -1, address_map_constructor(FUNC(upd177x_cpu_device::program_map), this)) + , m_pb_out_cb(*this) +{ } + + +upd1771c_cpu_device::upd1771c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : upd177x_cpu_device(mconfig, UPD1771C, tag, owner, clock) +{ } + + +device_memory_interface::space_config_vector upd177x_cpu_device::memory_space_config() const +{ + return space_config_vector + { + std::make_pair(AS_PROGRAM, &m_program_config) + }; +} + + +void upd177x_cpu_device::program_map(address_map &map) +{ + map(0, 0x1ff).rom(); +} + + +void upd177x_cpu_device::device_start() +{ + space(AS_PROGRAM).specific(m_program); + + state_add(UPD177X_PC, "PC", m_pc); + state_add(STATE_GENPC, "GENPC", m_pc).noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow(); + state_add(UPD177X_SP, "SP", m_sp); + state_add(UPD177X_A, "A", m_a); + state_add(UPD177X_A_SAVE, "A'", m_a_save); + state_add(UPD177X_H, "H", m_h); + state_add(UPD177X_N, "N", m_n); + state_add(UPD177X_TIMER, "Timer", m_timer); + state_add(UPD177X_X, "X", m_x); + state_add(UPD177X_Y, "Y", m_y); + state_add(UPD177X_PA, "PA", m_pa); + state_add(UPD177X_PB, "PB", m_pb); + state_add(UPD177X_MD0, "MD0", m_md0); + state_add(UPD177X_MD1, "MD1", m_md1); + state_add(UPD177X_PNC1, "PNC1", m_pnc1); + state_add(UPD177X_PNC2, "PNC2", m_pnc2); + state_add(UPD177X_SKIP, "SKIP", m_skip); + state_add(UPD177X_SKIP_SAVE, "SKIP'", m_skip_save); + + save_item(NAME(m_pc)); + save_item(NAME(m_sp)); + save_item(NAME(m_a)); + save_item(NAME(m_a_save)); + save_item(NAME(m_h)); + save_item(NAME(m_n)); + save_item(NAME(m_timer)); + save_item(NAME(m_x)); + save_item(NAME(m_y)); + save_item(NAME(m_pa)); + save_item(NAME(m_pb)); + save_item(NAME(m_ram)); + save_item(NAME(m_md0)); + save_item(NAME(m_md1)); + save_item(NAME(m_pnc1)); + save_item(NAME(m_pnc2)); + save_item(NAME(m_skip)); + save_item(NAME(m_skip_save)); + save_item(NAME(m_ts)); + save_item(NAME(m_ns)); + save_item(NAME(m_ss)); + save_item(NAME(m_dac)); + save_item(NAME(m_dac_sign)); + save_item(NAME(m_tn_int)); + save_item(NAME(m_counter)); + + set_icountptr(m_icount); + + m_channel = stream_alloc(0, 1, clock() / 4); +} + + +void upd177x_cpu_device::device_reset() +{ + m_pc = 0; + m_sp = 0; + m_a = 0; + m_a_save = 0; + m_h = 0; + m_n = 0; + m_x = 0; + m_y = 0; + m_pa = 0; + m_pb = 0; + m_md0 = 0; + m_md1 = 0; + m_skip = false; + m_skip_save = false; + m_ts = false; + m_ns = false; + m_ss = false; + m_dac = 0; + m_dac_sign = true; + m_tn_int = false; + m_counter = 0; + m_timer = 0; + set_noise_counter_bit(); +} + + +std::unique_ptr<util::disasm_interface> upd177x_cpu_device::create_disassembler() +{ + return std::make_unique<upd177x_disassembler>(); +} + + +void upd177x_cpu_device::op0xxx(u16 opcode) +{ + switch (opcode) + { + case 0x0000: // NOP + break; + case 0x0002: // OUT PA + m_pa = m_a; + break; + case 0x0004: // OUT PB + m_pb = m_a; + m_pb_out_cb(m_pb); + break; + case 0x0008: // MOV X,RG + m_x = m_pnc1 & 0x7f; + break; + case 0x0201: // MOV N,A + m_n = m_a; + break; + case 0x0208: // MOV X,A + m_x = m_a & 0x7f; + break; + case 0x0401: // IN PA + m_a = m_pa; + break; + case 0x0402: // IN PB + m_a = m_pb; + break; + case 0x0404: // RAR + m_a = ((m_a & 0x01) << 7) | (m_a >> 1); + break; + case 0x0408: // RAL + m_a = ((m_a & 0x80) >> 7) | (m_a << 1); + break; + case 0x0502: // OUT DA + m_channel->update(); + m_dac = (m_ss ^ m_ts) ? ~m_a : m_a; + m_dac_sign = m_ss; + break; + case 0x0504: // MUL1 + if (!BIT(m_y, 0)) + { + m_a = m_a >> 1; + } + m_y = m_y >> 1; + break; + case 0x050c: // MUL2, usually gets executed 5 times to calculate X * (Y / 32) + if (BIT(m_y, 0)) + { + m_a = (m_a + m_x) >> 1; + } + else + { + m_a = m_a >> 1; + } + m_y = m_y >> 1; + break; + case 0x0800: // RET + m_sp = (m_sp - 1) & 0x07; + m_pc = (m_ram[STACK_START + (m_sp * 2) + 1] << 8) | m_ram[STACK_START + (m_sp * 2)]; + break; + case 0x090f: // RETI + m_sp = (m_sp - 1) & 0x07; + m_pc = (m_ram[STACK_START + (m_sp * 2) + 1] << 8) | m_ram[STACK_START + (m_sp * 2)]; + m_a = m_a_save; + m_skip = m_skip_save; + m_tn_int = false; + break; + + case 0x0005: // STF + case 0x0101: // MON + case 0x0501: // JMPA + case 0x0602: // OFF + case 0x0801: // RETS + default: + fatalerror("%s, %04x: Unsupported instruction %04x\n", tag(), m_pc - 1, opcode); + } +} + + +void upd177x_cpu_device::op1xxx(u16 opcode) +{ + switch (opcode & 0x0e0f) + { + case 0x0000: // MOV Y,Rr + m_y = m_ram[(opcode >> 4) & 0x1f] & 0x1f; + break; + case 0x0005: // MOV A,Rr + m_a = m_ram[(opcode >> 4) & 0x1f]; + break; + case 0x0201: // MOV Rr,A + m_ram[(opcode >> 4) & 0x1f] = m_a; + break; + case 0x0409: // MIX Rr + case 0x0509: // MIX Rr + m_ns = BIT(m_md0, MD0_NSF1_BIT) ? BIT(m_pnc2 , 2) : false; + if (m_ts ^ m_ns) + { + m_ss = m_ts ^ ((m_ram[(opcode >> 4) & 0x1f] < m_a) ? true : false); + m_a = m_ram[(opcode >> 4) & 0x1f] - m_a; + } + else + { + m_ss = m_ts ^ ((m_ram[(opcode >> 4) & 0x1f] + m_a > 255) ? true : false); + m_a = m_ram[(opcode >> 4) & 0x1f] + m_a; + } + break; + case 0x0601: // MOV (H),A + m_ram[m_h] = m_a; + break; + case 0x0801: // TBL0 A,(Rr) + case 0x0901: // TBL0 A,(Rr) + { + const u8 reg = (opcode >> 4) & 0x1e; + const u16 addr = (m_ram[reg + 1] << 8) | m_ram[reg]; + const u16 data = m_program.read_word(addr >> 1); + m_a = BIT(addr, 0) ? data >> 8 : data & 0xff; + } + m_cycle(); + break; + case 0x0802: // TBL0 X,(Rr) + case 0x0902: // TBL0 X,(Rr) + { + const u8 reg = (opcode >> 4) & 0x1e; + const u16 addr = (m_ram[reg + 1] << 8) | m_ram[reg]; + const u16 data = m_program.read_word(addr >> 1); + m_x = BIT(addr, 0) ? (data >> 8) : data; + m_ts = BIT(m_x, 7); + m_x &= 0x7f; + } + m_cycle(); + break; + + case 0x000a: // MOV H,Rr + case 0x0202: // MOV Rr,H + case 0x0205: // XCHG Rr,A + case 0x020a: // XCHG Rr,H + case 0x0405: // MOV A,(H) + case 0x0605: // XCHG (H),A + case 0x0804: // TBL0 Y,(Rr) + case 0x0904: // TBL0 Y,(Rr) + case 0x0808: // CALL0 (Rr) + case 0x0908: // CALL0 (Rr) + case 0x0a01: // TBL1 A,(Rr) + case 0x0b01: // TBL1 A,(Rr) + case 0x0a02: // TBL1 X,(Rr) + case 0x0b02: // TBL1 X,(Rr) + case 0x0a04: // TBL1 Y,(Rr) + case 0x0b04: // TBL1 Y,(Rr) + case 0x0a08: // CALL1 (Rr) + case 0x0b08: // CALL1 (Rr) + default: + fatalerror("%s, %04x: Unsupported instruction %04x\n", tag(), m_pc - 1, opcode); + } +} + + +void upd177x_cpu_device::op2xxx(u16 opcode) +{ + switch (opcode & 0x0f00) + { + case 0x0100: // MVI MD0,A + m_md0 = opcode & 0x7f; + set_noise_counter_bit(); + break; + case 0x0000: // JPP n + case 0x8000: // JMPFZ n + default: + fatalerror("%s, %04x: Unsupported instruction %04x\n", tag(), m_pc - 1, opcode); + } +} + + +void upd177x_cpu_device::op3xxx(u16 opcode) +{ + switch (opcode & 0x0f00) + { + case 0x0400: // MVI A,n + m_a = opcode & 0xff; + break; + case 0x0800: + if (!(opcode & 0x00c0)) + { + m_h = opcode & 0x3f; + } + break; + case 0x0100: // MVI MD1,n + case 0x0200: // MVI (H),n + default: + fatalerror("%s, %04x: Unsupported instruction %04x\n", tag(), m_pc - 1, opcode); + } +} + + +void upd177x_cpu_device::op7xxx(u16 opcode) +{ + // CALL + m_ram[STACK_START + (m_sp * 2) + 1] = m_pc >> 8; + m_ram[STACK_START + (m_sp * 2)] = m_pc & 0xff; + m_sp = (m_sp + 1) & 0x07; + m_pc = (m_pc & 0xf000) | (opcode & 0x0fff); +} + + +void upd177x_cpu_device::op89xxx(u16 opcode) +{ + switch (opcode & 0x1f00) + { + case 0x0000: // ADI A,n + m_a = m_a + (opcode & 0xff); + break; + case 0x0200: // ANDI A,n + m_a = m_a & (opcode & 0xff); + break; + case 0x0600: // ORI A,n + m_a = m_a | (opcode & 0xff); + break; + case 0x0800: // ADIS A,n + m_a = m_a + (opcode & 0xff); + m_skip = (m_a < (opcode & 0xff)); + break; + case 0x0c00: // SBIS A,n + m_skip = m_a < (opcode & 0xff); + m_a = m_a - (opcode & 0xff); + break; + case 0x0e00: // XORI A,n + m_a = m_a ^ (opcode & 0xff); + break; + case 0x1000: // TADI NC A,n + m_skip = (m_a + (opcode & 0xff) < 0x100); + break; + case 0x1400: // TSBI NC A,n + m_skip = (m_a >= (opcode & 0xff)); + break; + case 0x1600: // TSBI NZ A,n + m_skip = (m_a != (opcode & 0xff)); + break; + case 0x1a00: // TANDI Z A,n + m_skip = (m_a & (opcode & 0xff)) == 0; + break; + case 0x1c00: // TSBI C A,n + m_skip = (m_a < (opcode & 0xff)); + break; + + case 0x0100: // ADI MD1,n + case 0x1100: // ADI MD0,n + case 0x0300: // ANDI MD1,n + case 0x1300: // ANDI MD0,n + case 0x0400: // SBI A,n + case 0x0500: // SBI MD1,n + case 0x1500: // SBI MD0,n + case 0x0700: // ORI MD1,n + case 0x1700: // ORI MD0,n + case 0x0900: // ADIS MD1,n + case 0x1900: // ADIS MD0,n + case 0x0a00: // ANDIS A,n + case 0x0b00: // ANDIS MD1,n + case 0x1b00: // ANDIS MD0,n + case 0x0d00: // SBIS MD1,n + case 0x1d00: // SBIS MD0,n + case 0x0f00: // XORI MD1,n + case 0x1f00: // XORI MD0,n + case 0x1200: // TANDI NZ A,n + case 0x1800: // TADI C A,n + case 0x1e00: // TSBI Z A,n + default: + fatalerror("%s, %04x: Unsupported instruction %04x\n", tag(), m_pc - 1, opcode); + } +} + + +void upd177x_cpu_device::opabxxx(u16 opcode) +{ + switch (opcode & 0x1f00) + { + case 0x0d00: // SBS H,n + { + u8 old_h = m_h; + m_h = (m_h - (opcode & 0x3f)) & 0x3f; + if (old_h < m_h) + { + m_skip = true; + } + } + break; + case 0x1200: // TANDI NZ (H),n + m_skip = (m_ram[m_h] & (opcode & 0xff)); + break; + case 0x1a00: // TANDI Z (H),n + m_skip = (m_ram[m_h] & (opcode & 0xff)) == 0; + break; + case 0x1f00: // TSB Z H,n + m_skip = (m_h == (opcode & 0xff)); + break; + + case 0x0000: // AD (H),n + case 0x0100: // AD H,n + case 0x0200: // AND (H),n + case 0x0300: // AND H,n + case 0x0400: // SB (H),n + case 0x0500: // SB H,n + case 0x0600: // OR (H),n + case 0x0700: // OR H,n + case 0x0800: // ADS (H),n + case 0x0900: // ADS H,n + case 0x0a00: // ANDS (H),n + case 0x0b00: // ANDS H,n + case 0x0c00: // SBS (H),n + case 0x0e00: // XOR (H),n + case 0x0f00: // XOR H,n + case 0x1000: // TAD NC (H),n + case 0x1100: // TAD NC H,n + case 0x1300: // TAND NZ H,n + case 0x1400: // TSB NC (H),n + case 0x1500: // TSB NC H,n + case 0x1600: // TSB NZ (H),n + case 0x1700: // TSB NZ H,n + case 0x1800: // TAD C (H),n + case 0x1900: // TAD C H,n + case 0x1b00: // TAND Z H,n + case 0x1c00: // TSB C (H),n + case 0x1d00: // TSB C H,n + case 0x1e00: // TSB Z (H),n + default: + fatalerror("%s, %04x: Unsupported instruction %04x\n", tag(), m_pc - 1, opcode); + } +} + + +void upd177x_cpu_device::opcdxxx(u16 opcode) +{ + switch (opcode & 0x1e0f) + { + case 0x0008: // AD Rr,A + m_ram[(opcode >> 4) & 0x1f] += m_a; + break; + case 0x1e00: // TSB Z A,Rr + m_skip = (m_a == m_ram[(opcode >> 4) & 0x1f]); + break; + case 0x0000: // AD A,Rr + m_a += m_ram[(opcode >> 4) & 0x1f]; + break; + + case 0x0001: // AD A,(H) + case 0x0009: // AD (H),A + case 0x0200: // AND A,Rr + case 0x0201: // AND A,(H) + case 0x0208: // AND Rr,A + case 0x0209: // AND (H),A + case 0x0400: // SB A,Rr + case 0x0401: // SB A,(H) + case 0x0408: // SB Rr,A + case 0x0409: // SB (H),A + case 0x0600: // OR A,Rr + case 0x0601: // OR A,(H) + case 0x0608: // OR Rr,A + case 0x0609: // OR (H),A + case 0x0800: // ADS A,Rr + case 0x0801: // ADS A,(H) + case 0x0808: // ADS Rr,A + case 0x0809: // ADS (H),A + case 0x0a00: // ANDS A,Rr + case 0x0a01: // ANDS A,(H) + case 0x0a08: // ANDS Rr,A + case 0x0a09: // ANDS (H),A + case 0x0c00: // SBS A,Rr + case 0x0c01: // SBS A,(H) + case 0x0c08: // SBS Rr,A + case 0x0c09: // SBS (H),A + case 0x0e00: // XOR A,Rr + case 0x0e01: // XOR A,(H) + case 0x0e08: // XOR Rr,A + case 0x0e09: // XOR (H),A + case 0x1000: // TAD NC A,Rr + case 0x1001: // TAD NC A,(H) + case 0x1008: // TAD NC Rr,A + case 0x1009: // TAD NC (H),A + case 0x1200: // TAND NZ A,Rr + case 0x1201: // TAND NZ A,(H) + case 0x1208: // TAND NZ Rr,A + case 0x1209: // TAND NZ (H),A + case 0x1400: // TSB NC A,Rr + case 0x1401: // TSB NC A,(H) + case 0x1408: // TSB NC Rr,A + case 0x1409: // TSB NC (H),A + case 0x1600: // TSB NZ A,Rr + case 0x1601: // TSB NZ A,(H) + case 0x1608: // TSB NZ Rr,A + case 0x1609: // TSB NZ (H),A + case 0x1800: // TAD C A,Rr + case 0x1801: // TAD C A,(H) + case 0x1808: // TAD C Rr,A + case 0x1809: // TAD C (H),A + case 0x1a00: // TAND Z A,Rr + case 0x1a01: // TAND Z A,(H) + case 0x1a08: // TAND Z Rr,A + case 0x1a09: // TAND Z (H),A + case 0x1c00: // TSB C A,Rr + case 0x1c01: // TSB C A,(H) + case 0x1c08: // TSB C Rr,A + case 0x1c09: // TSB C (H),A + case 0x1e01: // TSB Z A,(H) + case 0x1e08: // TSB Z Rr,A + case 0x1e09: // TSB Z (H),A + default: + fatalerror("%s, %04x: Unsupported instruction %04x\n", tag(), m_pc - 1, opcode); + } +} + + +void upd177x_cpu_device::opefxxx(u16 opcode) +{ + switch (opcode & 0x1e00) + { + case 0x0000: // ADI Rr,n + m_ram[(opcode >> 4) & 0x1f] += (opcode & 0x0f); + break; + case 0x0200: // ADIS Rr,n + m_ram[(opcode >> 4) & 0x1f] += (opcode & 0x0f); + m_skip = (m_ram[(opcode >> 4) & 0x1f] < (opcode & 0x0f)); + break; + case 0x0400: // SBI Rr,n + m_ram[(opcode >> 4) & 0x1f] -= (opcode & 0x0f); + break; + case 0x0600: // SBIS Rr,n + m_skip = (m_ram[(opcode >> 4) & 0x1f] < (opcode & 0x0f)); + m_ram[(opcode >> 4) & 0x1f] -= (opcode & 0x0f); + break; + case 0x0800: // TADI NC Rr,n + m_skip = (m_ram[(opcode >> 4) & 0x1f] + (opcode & 0x0f) < 0x100); + break; + case 0x0c00: // TSBI NC Rr,n + m_skip = (m_ram[(opcode >> 4) & 0x1f] >= (opcode & 0x0f)); + break; + case 0x0e00: // TSBI C Rr,n + m_skip = (m_ram[(opcode >> 4) & 0x1f] < (opcode & 0x0f)); + break; + case 0x1200: // ADIMS Rr,n + { + const u8 reg = (opcode >> 4) & 0x1f; + if (BIT(m_md0, 0)) + { + m_skip = ((m_ram[reg] & 0x3f) + (opcode & 0x0f)) > 0x3f; + m_ram[reg] = (m_ram[reg] & 0xc0) | ((m_ram[reg] + (opcode & 0x0f)) & 0x3f); + } + else + { + m_skip = ((m_ram[reg] & 0x1f) + (opcode & 0x0f)) > 0x1f; + m_ram[reg] = (m_ram[reg] & 0xe0) | ((m_ram[reg] + (opcode & 0x0f)) & 0x1f); + } + } + break; + + case 0x0a00: // TADI C Rr,n + case 0x1000: // ADI5 Rr,n + case 0x1800: // TADI5 Rr,n + default: + if (opcode != 0xffff) + { + fatalerror("%s, %04x: Unsupported instruction %04x\n", tag(), m_pc - 1, opcode); + } + } +} + + +void upd177x_cpu_device::handle_timer() +{ + if (m_n >= 8) + { + if (m_timer == 0 || !--m_timer) + { + if (BIT(m_md0, MD0_TN_BIT) && !m_tn_int) + { + // Trigger TN IRQ + m_ram[STACK_START + (m_sp * 2) + 1] = m_pc >> 8; + m_ram[STACK_START + (m_sp * 2)] = m_pc & 0xff; + m_sp = (m_sp + 1) & 0x07; + m_skip_save = m_skip; + m_skip = false; + m_a_save = m_a; + if (m_n >= 0x40) + { + m_pc = VECTOR_TONE4; + } + else if (m_n >= 0x20) + { + m_pc = VECTOR_TONE3; + } + else if (m_n >= 0x10) + { + m_pc = VECTOR_TONE2; + } + else + { + m_pc = VECTOR_TONE1; + } + m_tn_int = true; + } + if (m_n >= 0x40) + { + m_timer = m_n; + } + else if (m_n >= 0x20) + { + m_timer = m_n * 2; + } + else if (m_n >= 0x10) + { + m_timer = m_n * 4; + } + else + { + m_timer = m_n * 8; + } + } + } +} + + +void upd177x_cpu_device::set_noise_counter_bit() +{ + if (BIT(m_md0, MD0_NSF2_BIT)) + { + m_noise_counter_bit = (BIT(m_md1, MD1_NSF3_BIT)) ? 5 : 8; + } + else + { + m_noise_counter_bit = (BIT(m_md1, MD1_NSF3_BIT)) ? 6 : 9; + } +} + + +void upd177x_cpu_device::m_cycle() +{ + m_icount -= 8; + const u16 old_counter = m_counter; + m_counter++; + const u16 counter_diff = old_counter ^ m_counter; + if (BIT(counter_diff, 9)) + { + if (BIT(m_md1, MD1_TIME_BIT)) + { + fatalerror("%s: TM int not supported\n", tag()); + } + } + if (BIT(counter_diff, m_noise_counter_bit)) + { + m_pnc1 = ((m_pnc1 << 1) | ((BIT(m_pnc1, 6) ^ BIT(m_pnc1, 5)) ? 1 : 0)) & 0x7f; + if (BIT(m_md0, MD0_NSF1_BIT)) + { + m_pnc2 = (m_pnc2 << 1) | (BIT(m_pnc2, 0) ? 0 : 1); + } + else + { + m_pnc2 = (m_pnc2 << 1) | ((BIT(m_pnc2, 2) ^ BIT(m_pnc2, 1)) ? 0 : 1); + } + + if (BIT(m_md0, MD0_NS_BIT)) + { + fatalerror("%s: NS int not supported\n", tag()); + } + } +} + + +void upd177x_cpu_device::execute_run() +{ + do + { + handle_timer(); + debugger_instruction_hook(m_pc); + if (!m_skip) + { + u16 opcode = m_program.read_word(m_pc++); + switch (opcode & 0xf000) + { + case 0x0000: op0xxx(opcode); break; + case 0x1000: op1xxx(opcode); break; + case 0x2000: op2xxx(opcode); break; + case 0x3000: op3xxx(opcode); break; + case 0x4000: m_ram[(opcode >> 8) & 0x1f] = opcode & 0xff; break; // MVI Rr,n + case 0x5000: m_ram[(opcode >> 8) & 0x1f] = opcode & 0xff; break; // MVI Rr,n + case 0x6000: m_pc = (m_pc & 0xf000) | (opcode & 0x0fff); break; // JMP n + case 0x7000: op7xxx(opcode); break; + case 0x8000: op89xxx(opcode); break; + case 0x9000: op89xxx(opcode); break; + case 0xa000: opabxxx(opcode); break; + case 0xb000: opabxxx(opcode); break; + case 0xc000: opcdxxx(opcode); break; + case 0xd000: opcdxxx(opcode); break; + case 0xe000: opefxxx(opcode); break; + case 0xf000: opefxxx(opcode); break; + } + } + else + { + m_pc++; + m_skip = false; + } + m_cycle(); + } while (m_icount > 0); +} + + +void upd177x_cpu_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) +{ + auto &buffer = outputs[0]; + + const int smpl = m_dac_sign ? -m_dac : m_dac; + for (int sampindex = 0; sampindex < buffer.samples(); sampindex++) + { + buffer.put_int(sampindex, smpl, 256); + } +} |