diff options
Diffstat (limited to 'src/devices')
-rw-r--r-- | src/devices/cpu/amis2000/amis2000.h | 3 | ||||
-rw-r--r-- | src/devices/cpu/amis2000/amis2000op.cpp | 11 | ||||
-rw-r--r-- | src/devices/cpu/hpc/hpc.cpp | 144 | ||||
-rw-r--r-- | src/devices/cpu/hpc/hpc.h | 88 | ||||
-rw-r--r-- | src/devices/cpu/hpc/hpcdasm.cpp | 760 | ||||
-rw-r--r-- | src/devices/cpu/hpc/hpcdasm.h | 58 | ||||
-rw-r--r-- | src/devices/cpu/pic16c5x/pic16c5x.cpp | 4 | ||||
-rw-r--r-- | src/devices/machine/upd765.cpp | 31 | ||||
-rw-r--r-- | src/devices/sound/pokey.cpp | 87 | ||||
-rw-r--r-- | src/devices/sound/pokey.h | 9 | ||||
-rw-r--r-- | src/devices/sound/spkrdev.h | 4 | ||||
-rw-r--r-- | src/devices/video/mc6845.cpp | 2 |
12 files changed, 1137 insertions, 64 deletions
diff --git a/src/devices/cpu/amis2000/amis2000.h b/src/devices/cpu/amis2000/amis2000.h index 2739461b44b..58665c7f6bc 100644 --- a/src/devices/cpu/amis2000/amis2000.h +++ b/src/devices/cpu/amis2000/amis2000.h @@ -30,12 +30,13 @@ public: // S2000 has a hardcoded 7seg table, that (unlike S2200) is officially // uncustomizable, but wildfire proves to be an exception to that rule. - void set_7seg_table(const u8 *ptr) { m_7seg_table = ptr; } + void set_7seg_table(const u8 *ptr) { m_7seg_table = ptr; } // d0=A, d1=B, etc. void data_64x4(address_map &map); void data_80x4(address_map &map); void program_1_5k(address_map &map); void program_1k(address_map &map); + protected: // construction/destruction amis2000_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 bu_bits, u8 callstack_bits, u8 callstack_depth, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) diff --git a/src/devices/cpu/amis2000/amis2000op.cpp b/src/devices/cpu/amis2000/amis2000op.cpp index e67ee6d153b..92c2eaae3dc 100644 --- a/src/devices/cpu/amis2000/amis2000op.cpp +++ b/src/devices/cpu/amis2000/amis2000op.cpp @@ -220,11 +220,13 @@ void amis2000_base_device::op_disn() // DISN: set D-latch to ACC+carry via on-die segment decoder static const u8 lut_segment_decoder[0x10] = { - // 0-F digits in bit order [DP]abcdefg - 0x7e, 0x30, 0x6d, 0x79, 0x33, 0x5b, 0x5f, 0x70, 0x7f, 0x7b, 0x77, 0x1f, 0x4e, 0x3d, 0x4f, 0x47 + 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, // 0-7 + 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 // 8-F }; - const u8 *ptr = (m_7seg_table != nullptr) ? m_7seg_table : lut_segment_decoder; - m_d = ptr[m_acc] | (m_carry ? 0x80 : 0x00); + const u8 *lut = (m_7seg_table != nullptr) ? m_7seg_table : lut_segment_decoder; + + // segments are in order [DP]abcdefg + m_d = bitswap<7>(lut[m_acc],0,1,2,3,4,5,6) | (m_carry ? 0x80 : 0x00); d_latch_out(true); } @@ -500,7 +502,6 @@ void amis2000_base_device::op_rf2() } - // AMI S2152 specific handlers void amis2152_cpu_device::d2f_timer_clock() diff --git a/src/devices/cpu/hpc/hpc.cpp b/src/devices/cpu/hpc/hpc.cpp new file mode 100644 index 00000000000..399ca9164af --- /dev/null +++ b/src/devices/cpu/hpc/hpc.cpp @@ -0,0 +1,144 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + National Semiconductor High-Performance microController (HPC) + + Currently this device is just a stub with no actual execution core. + +**************************************************************************** + + HPC feature options by part number + + HPC16xxx Military temperature range (-55°C to +125°C) + HPC26xxx Automotive temperature range (-40°C to +105°C) + HPC36xxx Industrial temperature range (-40°C to +85°C) + HPC46xxx Commercial temperature range (0°C to +75°C) + + HPCxx1xx 8-channel A/D converter + HPCxx0xx No A/D converter + + HPCxxx6x 16k bytes of on-chip ROM + HPCxxx8x 8k bytes of on-chip ROM + HPCxxx0x No on-chip ROM + + HPCxxxx4 512 bytes of on-chip RAM + HPCxxxx3 256 bytes of on-chip RAM + +***************************************************************************/ + +#include "emu.h" +#include "hpc.h" +#include "hpcdasm.h" + +// device type definitions +DEFINE_DEVICE_TYPE(HPC46003, hpc46003_device, "hpc46003", "HPC46003") +DEFINE_DEVICE_TYPE(HPC46104, hpc46104_device, "hpc46104", "HPC46104") + + +void hpc46003_device::internal_map(address_map &map) +{ + map(0x0000, 0x00bf).ram(); + map(0x00c0, 0x00c0).rw(FUNC(hpc46003_device::psw_r), FUNC(hpc46003_device::psw_w)); + map(0x00c4, 0x00cf).ram().share("core_regs"); + // TODO: many other internal registers + map(0x01c0, 0x01ff).ram(); +} + +void hpc46104_device::internal_map(address_map &map) +{ + map(0x0000, 0x00bf).ram(); + map(0x00c0, 0x00c0).rw(FUNC(hpc46104_device::psw_r), FUNC(hpc46104_device::psw_w)); + map(0x00c4, 0x00cf).ram().share("core_regs"); + // TODO: many other internal registers + map(0x01c0, 0x02ff).ram(); +} + +std::unique_ptr<util::disasm_interface> hpc46003_device::create_disassembler() +{ + return std::make_unique<hpc16083_disassembler>(); +} + +std::unique_ptr<util::disasm_interface> hpc46104_device::create_disassembler() +{ + return std::make_unique<hpc16164_disassembler>(); +} + + +hpc_device::hpc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor map) + : cpu_device(mconfig, type, tag, owner, clock) + , m_program_config("program", ENDIANNESS_LITTLE, 16, 16, 0, map) + , m_program(nullptr) + , m_core_regs(*this, "core_regs") + , m_psw(0) + , m_icount(0) +{ +} + +hpc46003_device::hpc46003_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : hpc_device(mconfig, HPC46003, tag, owner, clock, address_map_constructor(FUNC(hpc46003_device::internal_map), this)) +{ +} + +hpc46104_device::hpc46104_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : hpc_device(mconfig, HPC46104, tag, owner, clock, address_map_constructor(FUNC(hpc46104_device::internal_map), this)) +{ +} + +device_memory_interface::space_config_vector hpc_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(AS_PROGRAM, &m_program_config), + }; +} + + +void hpc_device::device_start() +{ + m_program = &space(AS_PROGRAM); + + set_icountptr(m_icount); + + state_add(HPC_PSW, "PSW", m_psw); + state_add(HPC_SP, "SP", m_core_regs[0]); + state_add(HPC_PC, "PC", m_core_regs[1]); + state_add(STATE_GENPC, "GENPC", m_core_regs[1]).callimport().noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_core_regs[1]).callimport().noshow(); + state_add(HPC_A, "A", m_core_regs[2]); + state_add(HPC_K, "K", m_core_regs[3]); + state_add(HPC_B, "B", m_core_regs[4]); + state_add(HPC_X, "X", m_core_regs[5]); + + save_item(NAME(m_psw)); +} + +void hpc_device::device_reset() +{ + m_psw = 0x00; + std::fill_n(&m_core_regs[0], 6, 0x0000); +} + + +u8 hpc_device::psw_r() +{ + return m_psw; +} + +void hpc_device::psw_w(u8 data) +{ + m_psw = data; +} + + +void hpc_device::execute_run() +{ + m_core_regs[1] = m_program->read_word(0xfffe); + debugger_instruction_hook(m_core_regs[1]); + + m_icount = 0; +} + +void hpc_device::execute_set_input(int inputnum, int state) +{ + // TODO +} diff --git a/src/devices/cpu/hpc/hpc.h b/src/devices/cpu/hpc/hpc.h new file mode 100644 index 00000000000..5f73a0ee2e6 --- /dev/null +++ b/src/devices/cpu/hpc/hpc.h @@ -0,0 +1,88 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CPU_HPC_HPC_H +#define MAME_CPU_HPC_HPC_H + +#pragma once + + +class hpc_device : public cpu_device +{ +public: + enum { + HPC_PSW, + HPC_SP, + HPC_PC, + HPC_A, + HPC_K, + HPC_B, + HPC_X + }; + +protected: + // construction/destruction + hpc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor map); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // device_execute_interface overrides + virtual void execute_run() override; + virtual void execute_set_input(int inputnum, int state) override; + + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + + // internal register access + u8 psw_r(); + void psw_w(u8 data); + +private: + // address space + address_space_config m_program_config; + address_space *m_program; + + // internal state + required_shared_ptr<u16> m_core_regs; + u8 m_psw; + + // execution sequencing + s32 m_icount; +}; + +class hpc46003_device : public hpc_device +{ +public: + // construction/destruction + hpc46003_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // device_disasm_interface overrides + virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + +private: + void internal_map(address_map &map); +}; + +class hpc46104_device : public hpc_device +{ +public: + // construction/destruction + hpc46104_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // device_disasm_interface overrides + virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + +private: + void internal_map(address_map &map); +}; + + +// device type declarations +DECLARE_DEVICE_TYPE(HPC46003, hpc46003_device) +DECLARE_DEVICE_TYPE(HPC46104, hpc46104_device) + +#endif // MAME_CPU_HPC_HPC_H diff --git a/src/devices/cpu/hpc/hpcdasm.cpp b/src/devices/cpu/hpc/hpcdasm.cpp new file mode 100644 index 00000000000..54cec15e627 --- /dev/null +++ b/src/devices/cpu/hpc/hpcdasm.cpp @@ -0,0 +1,760 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + National Semiconductor HPC disassembler + + Note that though all 16-bit fields in instructions have the MSB first, + the HPC's memory organization is in fact little-endian. This is why r16 + is not used to read them. + +***************************************************************************/ + +#include "util/disasmintf.h" +#include "hpcdasm.h" + +#include "util/strformat.h" +#include <ctype.h> + +const char *const hpc16083_disassembler::s_regs[128] = +{ + "psw", nullptr, "SP", "PC", "A", "K", "B", "X", + "enir", "irpd", "ircd", "sio", "porti", nullptr, "halten", nullptr, + "porta", "portb", nullptr, "upic", nullptr, nullptr, nullptr, nullptr, + "dira", "dirb", "bfun", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, "portd", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "enu", "enui", "rbuf", "tbuf", "enur", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "t4", "r4", "t5", "r5", "t6", "r6", "t7", "r7", + "pwmode", "portp", nullptr, nullptr, nullptr, nullptr, "eicon", "eicr", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "i4cr", "i3cr", "i2cr", "r2", "t2", "r3", "t3", "divby", + "tmmode", "t0con", "watchdog", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +const char *const hpc16164_disassembler::s_regs[128] = +{ + "psw", nullptr, "SP", "PC", "A", "K", "B", "X", + "enir", "irpd", "ircd", "sio", "porti", nullptr, "halten", "romdump", + "porta", "portb", nullptr, "upic", nullptr, nullptr, nullptr, nullptr, + "dira", "dirb", "bfun", nullptr, nullptr, nullptr, nullptr, nullptr, + "adcr1", "adcr2", "portd", "adcr3", nullptr, nullptr, nullptr, nullptr, + "ad0", "ad1", "ad2", "ad3", "ad4", "ad5", "ad6", "ad7", + "enu", "enui", "rbuf", "tbuf", "enur", nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "t4", "r4", "t5", "r5", "t6", "r6", "t7", "r7", + "pwmode", "portp", nullptr, nullptr, nullptr, nullptr, "eicon", "eicr", + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + "i4cr", "i3cr", "i2cr", "r2", "t2", "r3", "t3", "divby", + "tmmode", "t0con", "watchdog", nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr +}; + +hpc_disassembler::hpc_disassembler(const char *const regs[]) + : util::disasm_interface() + , m_regs(regs) +{ +} + +u32 hpc_disassembler::opcode_alignment() const +{ + return 1; +} + +void hpc_disassembler::format_register(std::ostream &stream, u16 reg) const +{ + if (reg >= 0x00c0 && reg < 0x01c0) + { + const char *name = m_regs[(reg - 0x00c0) >> 1]; + if (name != nullptr) + { + stream << name; + if (BIT(reg, 0)) + stream << "+1"; + return; + } + } + + util::stream_format(stream, "0%X", reg); +} + +void hpc_disassembler::format_immediate_byte(std::ostream &stream, u8 data) const +{ + stream << "#"; + if (data >= 0x10) + stream << "0"; + util::stream_format(stream, "%02X", data); +} + +void hpc_disassembler::format_immediate_word(std::ostream &stream, u16 data) const +{ + stream << "#"; + if (data >= 0x1000) + stream << "0"; + util::stream_format(stream, "%04X", data); +} + +void hpc_disassembler::disassemble_op(std::ostream &stream, const char *op, u16 reg, u16 src, bool imm, bool indir, bool idx, bool w) const +{ + util::stream_format(stream, "%-8s", op); + if (idx) + stream << "A"; + else + format_register(stream, reg); + stream << ","; + if (imm) + { + if (w) + format_immediate_word(stream, src); + else + format_immediate_byte(stream, src); + } + else + { + if (idx) + util::stream_format(stream, "0%X", u16(reg)); + + if (indir) + stream << "["; + format_register(stream, src); + if (indir) + stream << "]"; + + if (w) + stream << ".w"; + else + stream << ".b"; + } +} + +void hpc_disassembler::disassemble_unary_op(std::ostream &stream, const char *op, u16 offset, u16 src, bool indir, bool idx, bool w) const +{ + util::stream_format(stream, "%-8s", op); + if (idx) + util::stream_format(stream, "0%X", offset); + + if (indir) + stream << "["; + format_register(stream, src); + if (indir) + stream << "]"; + + if (w) + { + if (src < 0x00c4 || src >= 0x00d0 || indir) + stream << ".w"; + } + else + stream << ".b"; +} + +void hpc_disassembler::disassemble_bit_op(std::ostream &stream, const char *op, u8 bit, u16 offset, u16 src, bool indir, bool idx) const +{ + if (src >= 0x00c0 && src < 0x01c0 && BIT(src, 0) && !indir && m_regs[(src - 0x00c0) >> 1] != nullptr) + { + src &= 0xfffe; + bit += 8; + } + + util::stream_format(stream, "%-8s%d,", op, bit); + + if (idx) + util::stream_format(stream, "0%X", offset); + + if (indir) + stream << "["; + format_register(stream, src); + if (indir) + stream << "].b"; +} + +offs_t hpc_disassembler::disassemble(std::ostream &stream, offs_t pc, const hpc_disassembler::data_buffer &opcodes, const hpc_disassembler::data_buffer ¶ms) +{ + u8 opcode = opcodes.r8(pc); + u16 reg = REGISTER_A; + u16 src = REGISTER_B; + bool imm = false; + bool dmode = false; + bool indir = true; + bool idx = false; + bool jmp = false; + offs_t bytes = 1; + + switch (opcode) + { + case 0x20: case 0x21: case 0x22: case 0x23: + case 0x24: case 0x25: case 0x26: case 0x27: + case 0x28: case 0x29: case 0x2a: case 0x2b: + case 0x2c: case 0x2d: case 0x2e: case 0x2f: + jmp = true; + src = 0xffd0 + (opcode & 0x0f) * 2; + bytes = 1; + break; + + case 0x30: case 0x31: case 0x32: case 0x33: + jmp = true; + src = pc + 2 + ((opcode & 0x03) << 8 | opcodes.r8(pc + 1)); + bytes = 2; + break; + + case 0x34: case 0x35: case 0x36: case 0x37: + jmp = true; + src = pc - ((opcode & 0x03) << 8 | opcodes.r8(pc + 1)); + bytes = 2; + break; + + case 0x38: case 0x39: case 0x3a: + reg = REGISTER_X; + break; + + case 0x3f: + case 0x89: case 0x8a: + case 0xa9: case 0xaa: case 0xaf: + indir = false; + src = opcodes.r8(pc + 1); + bytes = 2; + 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: + 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: + jmp = true; + src = pc + 1 + (opcode & 0x1f); + break; + + case 0x60: case 0x61: case 0x62: case 0x63: + case 0x64: case 0x65: case 0x66: case 0x67: + case 0x68: case 0x69: case 0x6a: case 0x6b: + case 0x6c: case 0x6d: case 0x6e: case 0x6f: + 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: + jmp = true; + src = pc - (opcode & 0x1f); + break; + + case 0x80: case 0x82: + case 0xa0: + dmode = true; + indir = false; + if (BIT(opcode, 1)) + imm = true; + + src = opcodes.r8(pc + 1); + reg = opcodes.r8(pc + 2); + opcode = opcodes.r8(pc + 3); + bytes = 4; + break; + + case 0x84: case 0x86: + case 0xa4: + dmode = true; + indir = false; + if (BIT(opcode, 1)) + imm = true; + + src = (opcodes.r8(pc + 1) << 8) | opcodes.r8(pc + 2); + reg = opcodes.r8(pc + 3); + opcode = opcodes.r8(pc + 4); + bytes = 5; + break; + + case 0x81: case 0x83: + case 0xa1: + dmode = true; + indir = false; + if (BIT(opcode, 1)) + imm = true; + + src = opcodes.r8(pc + 1); + reg = (opcodes.r8(pc + 2) << 8) | opcodes.r8(pc + 3); + opcode = opcodes.r8(pc + 4); + bytes = 5; + break; + + case 0xa2: + idx = true; + reg = opcodes.r8(pc + 1); + src = opcodes.r8(pc + 2); + opcode = opcodes.r8(pc + 3); + bytes = 4; + break; + + case 0x85: case 0x87: + case 0xa5: + dmode = true; + indir = false; + if (BIT(opcode, 1)) + imm = true; + + src = (opcodes.r8(pc + 1) << 8) | opcodes.r8(pc + 2); + reg = (opcodes.r8(pc + 3) << 8) | opcodes.r8(pc + 4); + opcode = opcodes.r8(pc + 5); + bytes = 6; + break; + + case 0xa6: + idx = true; + reg = (opcodes.r8(pc + 1) << 8) | opcodes.r8(pc + 2); + src = opcodes.r8(pc + 3); + opcode = opcodes.r8(pc + 4); + bytes = 5; + break; + + case 0x88: case 0x8b: case 0x8e: + case 0xa8: case 0xab: case 0xae: + indir = false; + src = opcodes.r8(pc + 1); + bytes = 2; + break; + + case 0x8c: + case 0xac: + indir = false; + src = opcodes.r8(pc + 1); + reg = opcodes.r8(pc + 2); + bytes = 3; + break; + + case 0x8d: + imm = true; + src = opcodes.r8(pc + 1); + reg = opcodes.r8(pc + 2); + bytes = 3; + break; + + case 0x8f: + src = REGISTER_X; + opcode = opcodes.r8(pc + 1); + bytes = 2; + break; + + case 0x90: case 0x91: case 0x92: case 0x93: + imm = true; + reg = 0x00c8 | ((opcode & 0x03) << 1); + src = opcodes.r8(pc + 1); + bytes = 2; + break; + + case 0x98: case 0x99: case 0x9a: case 0x9b: + case 0x9c: case 0x9d: case 0x9e: case 0x9f: + imm = true; + src = opcodes.r8(pc + 1); + bytes = 2; + break; + + case 0x94: + jmp = true; + src = pc + 2 + opcodes.r8(pc + 1); + bytes = 2; + break; + + case 0x95: + jmp = true; + src = pc - opcodes.r8(pc + 1); + bytes = 2; + break; + + case 0x96: + indir = false; + src = opcodes.r8(pc + 1); + opcode = opcodes.r8(pc + 2); + bytes = 3; + break; + + case 0x97: + indir = false; + imm = true; + src = opcodes.r8(pc + 1); + reg = opcodes.r8(pc + 2); + bytes = 3; + break; + + case 0xa7: + imm = true; + src = (opcodes.r8(pc + 1) << 8) | opcodes.r8(pc + 2); + reg = (opcodes.r8(pc + 3) << 8) | opcodes.r8(pc + 4); + bytes = 5; + break; + + case 0xad: + src = opcodes.r8(pc + 1); + opcode = opcodes.r8(pc + 2); + bytes = 3; + break; + + case 0xb0: case 0xb1: case 0xb2: case 0xb3: + imm = true; + reg = 0x00c8 | ((opcode & 0x03) << 1); + src = (opcodes.r8(pc + 1) << 8) | opcodes.r8(pc + 2); + bytes = 3; + break; + + case 0xb8: case 0xb9: case 0xba: case 0xbb: + case 0xbc: case 0xbd: case 0xbe: case 0xbf: + imm = true; + src = (opcodes.r8(pc + 1) << 8) | opcodes.r8(pc + 2); + bytes = 3; + break; + + case 0xb4: case 0xb5: + jmp = true; + src = pc + 3 + ((opcodes.r8(pc + 1) << 8) | opcodes.r8(pc + 2)); + bytes = 3; + break; + + case 0xb6: + indir = false; + src = (opcodes.r8(pc + 1) << 8) | opcodes.r8(pc + 2); + opcode = opcodes.r8(pc + 3); + bytes = 4; + break; + + case 0xb7: + imm = true; + src = (opcodes.r8(pc + 1) << 8) | opcodes.r8(pc + 2); + reg = opcodes.r8(pc + 3); + bytes = 4; + break; + + case 0xd4: case 0xd5: case 0xd6: + case 0xf4: case 0xf5: case 0xf6: + src = REGISTER_X; + break; + } + + switch (opcode) + { + case 0x00: + util::stream_format(stream, "%-8sA", "clr"); + break; + + case 0x01: + util::stream_format(stream, "%-8sA", "comp"); + break; + + case 0x02: + stream << "sc"; + break; + + case 0x03: + stream << "rc"; + break; + + case 0x04: + util::stream_format(stream, "%-8sA", "inc"); + break; + + case 0x05: + util::stream_format(stream, "%-8sA", "dec"); + break; + + case 0x06: + stream << "ifnc"; + break; + + case 0x07: + stream << "ifc"; + break; + + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x0c: case 0x0d: case 0x0e: case 0x0f: + disassemble_bit_op(stream, "sbit", opcode & 0x07, reg, src, indir, idx); + break; + + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x14: case 0x15: case 0x16: case 0x17: + disassemble_bit_op(stream, "ifbit", opcode & 0x07, reg, src, indir, idx); + break; + + case 0x18: case 0x19: case 0x1a: case 0x1b: + case 0x1c: case 0x1d: case 0x1e: case 0x1f: + disassemble_bit_op(stream, "rbit", opcode & 0x07, reg, src, indir, idx); + break; + + case 0x20: case 0x21: case 0x22: case 0x23: + case 0x24: case 0x25: case 0x26: case 0x27: + case 0x28: case 0x29: case 0x2a: case 0x2b: + case 0x2c: case 0x2d: case 0x2e: case 0x2f: + util::stream_format(stream, "%-8s", "jsrp"); + if (jmp) + util::stream_format(stream, "[0%X]", src); + else + stream << "???"; + bytes |= STEP_OVER; + break; + + case 0x30: case 0x31: case 0x32: case 0x33: + case 0x34: case 0x35: case 0x36: case 0x37: + util::stream_format(stream, "%-8s", "jsr"); + if (jmp) + util::stream_format(stream, "0%X", src); + else + stream << "???"; + bytes |= STEP_OVER; + break; + + case 0x38: + disassemble_op(stream, "rbit", reg, src, imm, indir, idx, false); + break; + + case 0x39: + disassemble_op(stream, "sbit", reg, src, imm, indir, idx, false); + break; + + case 0x3a: + disassemble_op(stream, "ifbit", reg, src, imm, indir, idx, false); + break; + + case 0x3b: + util::stream_format(stream, "%-8sA", "swap"); + break; + + case 0x3c: + stream << "ret"; + bytes |= STEP_OUT; + break; + + case 0x3d: + stream << "retsk"; + bytes |= STEP_OUT; + break; + + case 0x3e: + stream << "reti"; + bytes |= STEP_OUT; + break; + + case 0x3f: + util::stream_format(stream, "%-8s", "pop"); + format_register(stream, src); + break; + + case 0x40: + stream << "nop"; + break; + + 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: + 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: + case 0x60: case 0x61: case 0x62: case 0x63: + case 0x64: case 0x65: case 0x66: case 0x67: + case 0x68: case 0x69: case 0x6a: case 0x6b: + case 0x6c: case 0x6d: case 0x6e: case 0x6f: + 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: + util::stream_format(stream, "%-8s", "jp"); + if (jmp) + util::stream_format(stream, "0%X", src); + else + stream << "???"; + break; + + case 0x88: case 0x8c: + case 0x90: case 0x91: case 0x92: case 0x93: + case 0x97: + case 0xa8: case 0xac: + case 0xb0: case 0xb1: case 0xb2: case 0xb3: + case 0xb7: + case 0xc4: + case 0xd4: + case 0xe4: + case 0xf4: + disassemble_op(stream, "ld", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0x89: + case 0xa9: + disassemble_unary_op(stream, "inc", reg, src, indir, idx, BIT(opcode, 5)); + break; + + case 0x8a: + case 0xaa: + disassemble_unary_op(stream, "decsz", reg, src, indir, idx, BIT(opcode, 5)); + bytes |= STEP_OVER | (1 << OVERINSTSHIFT); + break; + + case 0x8b: + case 0xab: + case 0xc6: + case 0xd6: + case 0xe6: + case 0xf6: + disassemble_op(stream, dmode ? "ld" : "st", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0x8d: + util::stream_format(stream, "%-8sBK,", "ld"); + format_immediate_byte(stream, src); + stream << ","; + format_immediate_byte(stream, reg); + break; + + case 0x8e: + case 0xae: + case 0xc5: + case 0xd5: + case 0xe5: + case 0xf5: + disassemble_op(stream, "x", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0x94: case 0x95: + util::stream_format(stream, "%-8s", "jp"); + if (jmp) + util::stream_format(stream, "0%X", src); + else + stream << "???"; + break; + + case 0x98: case 0xb8: case 0xd8: case 0xf8: + disassemble_op(stream, "add", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0x99: case 0xb9: case 0xd9: case 0xf9: + disassemble_op(stream, "and", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0x9a: case 0xba: case 0xda: case 0xfa: + disassemble_op(stream, "or", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0x9b: case 0xbb: case 0xdb: case 0xfb: + disassemble_op(stream, "xor", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0x9c: case 0xbc: case 0xdc: case 0xfc: + disassemble_op(stream, "ifeq", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0x9d: case 0xbd: case 0xdd: case 0xfd: + disassemble_op(stream, "ifgt", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0x9e: case 0xbe: case 0xde: case 0xfe: + disassemble_op(stream, "mult", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0x9f: case 0xbf: case 0xdf: case 0xff: + disassemble_op(stream, "div", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0xa7: + util::stream_format(stream, "%-8sBK,", "ld"); + format_immediate_word(stream, src); + stream << ","; + format_immediate_word(stream, reg); + break; + + case 0xaf: + util::stream_format(stream, "%-8s", "push"); + format_register(stream, src); + break; + + case 0xb4: + util::stream_format(stream, "%-8s", "jmpl"); + if (jmp) + util::stream_format(stream, "0%X", src); + else + stream << "???"; + break; + + case 0xb5: + util::stream_format(stream, "%-8s", "jsrl"); + if (jmp) + util::stream_format(stream, "0%X", src); + else + stream << "???"; + bytes |= STEP_OVER; + break; + + case 0xc0: case 0xc2: + case 0xe0: case 0xe2: + util::stream_format(stream, "%-8sA,[B%c].%c", "lds", + BIT(opcode, 1) ? '-' : '+', + BIT(opcode, 5) ? 'w' : 'b'); + bytes |= STEP_OVER | (1 << OVERINSTSHIFT); + break; + + case 0xd0: case 0xd2: + case 0xf0: case 0xf2: + util::stream_format(stream, "%-8sA,[X%c].%c", "ld", + BIT(opcode, 1) ? '-' : '+', + BIT(opcode, 5) ? 'w' : 'b'); + break; + + case 0xc1: case 0xc3: + case 0xe1: case 0xe3: + util::stream_format(stream, "%-8sA,[B%c].%c", "xs", + BIT(opcode, 1) ? '-' : '+', + BIT(opcode, 5) ? 'w' : 'b'); + bytes |= STEP_OVER | (1 << OVERINSTSHIFT); + break; + + case 0xd1: case 0xd3: + case 0xf1: case 0xf3: + util::stream_format(stream, "%-8sA,[X%c].%c", "x", + BIT(opcode, 1) ? '-' : '+', + BIT(opcode, 5) ? 'w' : 'b'); + break; + + case 0xc7: case 0xe7: + util::stream_format(stream, "%-8sA", BIT(opcode, 5) ? "shl" : "shr"); + break; + + case 0xd7: case 0xf7: + util::stream_format(stream, "%-8sA", BIT(opcode, 5) ? "rlc" : "rrc"); + break; + + case 0xc8: case 0xe8: + disassemble_op(stream, "adc", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0xc9: case 0xe9: + disassemble_op(stream, "dadc", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0xca: case 0xea: + disassemble_op(stream, "dsubc", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0xcb: case 0xeb: + disassemble_op(stream, "subc", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + case 0xcc: case 0xec: + stream << "jid"; + if (BIT(opcode, 5)) + stream << "w"; + break; + + case 0xcf: case 0xef: + disassemble_op(stream, "divd", reg, src, imm, indir, idx, BIT(opcode, 5)); + break; + + default: + stream << "???"; + break; + } + + return bytes | SUPPORTED; +} diff --git a/src/devices/cpu/hpc/hpcdasm.h b/src/devices/cpu/hpc/hpcdasm.h new file mode 100644 index 00000000000..ed57c6b1a35 --- /dev/null +++ b/src/devices/cpu/hpc/hpcdasm.h @@ -0,0 +1,58 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_CPU_HPC_HPCDASM_H +#define MAME_CPU_HPC_HPCDASM_H + +#pragma once + +class hpc_disassembler : public util::disasm_interface +{ +protected: + enum : u16 + { + REGISTER_A = 0x00c8, + REGISTER_K = 0x00ca, + REGISTER_B = 0x00cc, + REGISTER_X = 0x00ce + }; + + // construction/destruction + hpc_disassembler(const char *const regs[]); + + // disassembler overrides + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + // internal helpers + void format_register(std::ostream &stream, u16 reg) const; + void format_immediate_byte(std::ostream &stream, u8 data) const; + void format_immediate_word(std::ostream &stream, u16 data) const; + void disassemble_op(std::ostream &stream, const char *op, u16 reg, u16 src, bool imm, bool indir, bool idx, bool w) const; + void disassemble_unary_op(std::ostream &stream, const char *op, u16 offset, u16 src, bool indir, bool idx, bool w) const; + void disassemble_bit_op(std::ostream &stream, const char *op, u8 bit, u16 offset, u16 src, bool indir, bool idx) const; + + // register names + const char *const *m_regs; +}; + +class hpc16083_disassembler : public hpc_disassembler +{ +public: + hpc16083_disassembler() : hpc_disassembler(s_regs) { } + +private: + static const char *const s_regs[128]; +}; + +class hpc16164_disassembler : public hpc_disassembler +{ +public: + hpc16164_disassembler() : hpc_disassembler(s_regs) { } + +private: + static const char *const s_regs[128]; +}; + +#endif // MAME_CPU_HPC_HPCDASM_H diff --git a/src/devices/cpu/pic16c5x/pic16c5x.cpp b/src/devices/cpu/pic16c5x/pic16c5x.cpp index fe1b0280d2a..21907b7d369 100644 --- a/src/devices/cpu/pic16c5x/pic16c5x.cpp +++ b/src/devices/cpu/pic16c5x/pic16c5x.cpp @@ -83,8 +83,8 @@ DEFINE_DEVICE_TYPE(PIC16C56, pic16c56_device, "pic16c56", "Microchip PIC16C56") DEFINE_DEVICE_TYPE(PIC16C57, pic16c57_device, "pic16c57", "Microchip PIC16C57") DEFINE_DEVICE_TYPE(PIC16C58, pic16c58_device, "pic16c58", "Microchip PIC16C58") -DEFINE_DEVICE_TYPE(PIC1650, pic1650_device, "pic1650", "Microchip PIC1650") -DEFINE_DEVICE_TYPE(PIC1655, pic1655_device, "pic1655", "Microchip PIC1655") +DEFINE_DEVICE_TYPE(PIC1650, pic1650_device, "pic1650", "GI PIC1650") +DEFINE_DEVICE_TYPE(PIC1655, pic1655_device, "pic1655", "GI PIC1655") /**************************************************************************** diff --git a/src/devices/machine/upd765.cpp b/src/devices/machine/upd765.cpp index ac5359ae07f..4a55eba7bae 100644 --- a/src/devices/machine/upd765.cpp +++ b/src/devices/machine/upd765.cpp @@ -18,6 +18,7 @@ #define LOG_MATCH (1U << 10) // Sector matching #define LOG_STATE (1U << 11) // State machine #define LOG_LIVE (1U << 12) // Live states +#define LOG_DONE (1U << 13) // Command done #define VERBOSE (LOG_GENERAL | LOG_WARN ) @@ -38,6 +39,7 @@ #define LOGMATCH(...) LOGMASKED(LOG_MATCH, __VA_ARGS__) #define LOGSTATE(...) LOGMASKED(LOG_STATE, __VA_ARGS__) #define LOGLIVE(...) LOGMASKED(LOG_LIVE, __VA_ARGS__) +#define LOGDONE(...) LOGMASKED(LOG_DONE, __VA_ARGS__) DEFINE_DEVICE_TYPE(UPD765A, upd765a_device, "upd765a", "NEC uPD765A FDC") DEFINE_DEVICE_TYPE(UPD765B, upd765b_device, "upd765b", "NEC uPD765B FDC") @@ -1484,7 +1486,7 @@ void upd765_family_device::execute_command(int cmd) void upd765_family_device::command_end(floppy_info &fi, bool data_completion) { - LOGCOMMAND("command done (%s) - %s\n", data_completion ? "data" : "seek", results()); + LOGDONE("command done (%s) - %s\n", data_completion ? "data" : "seek", results()); fi.main_state = fi.sub_state = IDLE; if(data_completion) data_irq = true; @@ -1756,7 +1758,16 @@ void upd765_family_device::read_data_continue(floppy_info &fi) fi.sub_state = COMMAND_DONE; break; } + // MZ: This st1 handling ensures that both HX5102 floppy and the + // Speedlock protection scheme are properly working. + // a) HX5102 requires that the ND flag not be set when no address + // marks could be found on the track at all (particularly due to + // wrong density) + // b) Speedlock requires the ND flag be set when there are valid + // sectors on the track, but the desired sector is missing, also + // when it has no valid address marks st1 &= ~ST1_MA; + st1 |= ST1_ND; if(!sector_matches()) { if(cur_live.idbuf[0] != command[2]) { if(cur_live.idbuf[0] == 0xff) @@ -1768,6 +1779,7 @@ void upd765_family_device::read_data_continue(floppy_info &fi) live_start(fi, SEARCH_ADDRESS_MARK_HEADER); return; } + st1 &= ~ST1_ND; LOGRW("reading sector %02x %02x %02x %02x\n", cur_live.idbuf[0], cur_live.idbuf[1], @@ -1786,11 +1798,6 @@ void upd765_family_device::read_data_continue(floppy_info &fi) case SCAN_ID_FAILED: LOGSTATE("SCAN_ID_FAILED\n"); fi.st0 |= ST0_FAIL; - // MZ: The HX5102 does not correctly detect a FM/MFM mismatch - // when the ND bit is set, because in the firmware the ND bit wins - // against MA, and thus concludes that the format is correct - // but the sector is missing. - // st1 |= ST1_ND; fi.sub_state = COMMAND_DONE; break; @@ -1862,7 +1869,7 @@ void upd765_family_device::write_data_start(floppy_info &fi) fi.main_state = WRITE_DATA; fi.sub_state = HEAD_LOAD; mfm = command[0] & 0x40; - LOGRW("command write%s data%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n", + LOGCOMMAND("command write%s data%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n", command[0] & 0x08 ? " deleted" : "", command[0] & 0x80 ? " mt" : "", command[0] & 0x40 ? " mfm" : "", @@ -1930,6 +1937,11 @@ void upd765_family_device::write_data_continue(floppy_info &fi) break; } st1 &= ~ST1_MA; + LOGRW("writing sector %02x %02x %02x %02x\n", + cur_live.idbuf[0], + cur_live.idbuf[1], + cur_live.idbuf[2], + cur_live.idbuf[3]); sector_size = calc_sector_size(cur_live.idbuf[3]); fifo_expect(sector_size, true); fi.sub_state = SECTOR_WRITTEN; @@ -2002,7 +2014,7 @@ void upd765_family_device::read_track_start(floppy_info &fi) mfm = command[0] & 0x40; sectors_read = 0; - LOGRW("command read track%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n", + LOGCOMMAND("command read track%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n", command[0] & 0x40 ? " mfm" : "", command[0], command[1], @@ -2326,8 +2338,7 @@ void upd765_family_device::read_id_continue(floppy_info &fi) case SCAN_ID_FAILED: LOGSTATE("SCAN_ID_FAILED\n"); fi.st0 |= ST0_FAIL; - // st1 |= ST1_ND|ST1_MA; - st1 = ST1_MA; + st1 |= ST1_ND|ST1_MA; fi.sub_state = COMMAND_DONE; break; diff --git a/src/devices/sound/pokey.cpp b/src/devices/sound/pokey.cpp index a7f175ddd1a..231dc01e8bf 100644 --- a/src/devices/sound/pokey.cpp +++ b/src/devices/sound/pokey.cpp @@ -161,8 +161,6 @@ #define CLK_28 1 #define CLK_114 2 -static const int clock_divisors[3] = {1, DIV_64, DIV_15}; - constexpr unsigned pokey_device::FREQ_17_EXACT; @@ -253,7 +251,8 @@ void pokey_device::device_start() m_pot_counter = 0; m_kbd_cnt = 0; m_out_filter = 0; - m_output = 0; + m_out_raw = 0; + m_old_raw_inval = true; m_kbd_state = 0; /* reset more internal state */ @@ -435,14 +434,7 @@ void pokey_device::execute_run() { do { - uint32_t new_out = step_one_clock(); - if (m_output != new_out) - { - //printf("forced update %08d %08x\n", m_icount, m_output); - m_stream->update(); - m_output = new_out; - } - + step_one_clock(); m_icount--; } while (m_icount > 0); @@ -570,25 +562,12 @@ void pokey_device::step_pot() * */ -uint32_t pokey_device::step_one_clock(void) +void pokey_device::step_one_clock(void) { - int const base_clock = (m_AUDCTL & CLK_15KHZ) ? CLK_114 : CLK_28; - + /* Clocks only count if we are not in a reset */ if (m_SKCTL & SK_RESET) { - /* Clocks only count if we are not in a reset */ - int clock_triggered[3] = {0,0,0}; - int clk; - for (clk = 0; clk < 3; clk++) - { - m_clock_cnt[clk]++; - if (m_clock_cnt[clk] >= clock_divisors[clk]) - { - m_clock_cnt[clk] = 0; - clock_triggered[clk] = 1; - } - } - + /* polynom pointers */ if (++m_p4 == 0x0000f) m_p4 = 0; if (++m_p5 == 0x0001f) @@ -598,7 +577,23 @@ uint32_t pokey_device::step_one_clock(void) if (++m_p17 == 0x1ffff) m_p17 = 0; - clk = (m_AUDCTL & CH1_HICLK) ? CLK_1 : base_clock; + /* CLK_1: no presacler */ + int clock_triggered[3] = {1,0,0}; + /* CLK_28: prescaler 63.9211 kHz */ + if (++m_clock_cnt[CLK_28] >= DIV_64) + { + m_clock_cnt[CLK_28] = 0; + clock_triggered[CLK_28] = 1; + } + /* CLK_114 prescaler 15.6999 kHz */ + if (++m_clock_cnt[CLK_114] >= DIV_15) + { + m_clock_cnt[CLK_114] = 0; + clock_triggered[CLK_114] = 1; + } + + int const base_clock = (m_AUDCTL & CLK_15KHZ) ? CLK_114 : CLK_28; + int clk = (m_AUDCTL & CH1_HICLK) ? CLK_1 : base_clock; if (clock_triggered[clk]) m_channel[CHAN1].inc_chan(); @@ -682,12 +677,23 @@ uint32_t pokey_device::step_one_clock(void) m_channel[CHAN1].m_filter_sample = 1; } - uint32_t sum = 0; - for (int ch = 0; ch < 4; ch++) + if (m_old_raw_inval) { - sum |= (((((m_channel[ch].m_output ^ m_channel[ch].m_filter_sample) || (m_channel[ch].m_AUDC & VOLUME_ONLY)) ? (m_channel[ch].m_AUDC & VOLUME_MASK) : 0 )) << (ch * 4)); + uint32_t sum = 0; + for (int ch = 0; ch < 4; ch++) + { + sum |= (((m_channel[ch].m_output ^ m_channel[ch].m_filter_sample) || (m_channel[ch].m_AUDC & VOLUME_ONLY)) ? + ((m_channel[ch].m_AUDC & VOLUME_MASK) << (ch * 4)) : 0); + } + + if (m_out_raw != sum) + { + //printf("forced update %08d %08x\n", m_icount, m_out_raw); + m_stream->update(); + } + m_old_raw_inval = false; + m_out_raw = sum; } - return sum; } //------------------------------------------------- @@ -704,7 +710,7 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i { int32_t out = 0; for (int i = 0; i < 4; i++) - out += ((m_output >> (4*i)) & 0x0f); + out += ((m_out_raw >> (4*i)) & 0x0f); out *= POKEY_DEFAULT_GAIN; out = (out > 0x7fff) ? 0x7fff : out; while( samples > 0 ) @@ -715,7 +721,7 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i } else if (m_output_type == RC_LOWPASS) { - double rTot = m_voltab[m_output]; + double rTot = m_voltab[m_out_raw]; double V0 = rTot / (rTot+m_r_pullup) * m_v_ref / 5.0 * 32767.0; double mult = (m_cap == 0.0) ? 1.0 : 1.0 - exp(-(rTot + m_r_pullup) / (m_cap * m_r_pullup * rTot) * m_clock_period.as_double()); @@ -731,7 +737,7 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i } else if (m_output_type == OPAMP_C_TO_GROUND) { - double rTot = m_voltab[m_output]; + double rTot = m_voltab[m_out_raw]; /* In this configuration there is a capacitor in parallel to the pokey output to ground. * With a LM324 in LTSpice this causes the opamp circuit to oscillate at around 100 kHz. * We are ignoring the capacitor here, since this oscillation would not be audible. @@ -753,7 +759,7 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i } else if (m_output_type == OPAMP_LOW_PASS) { - double rTot = m_voltab[m_output]; + double rTot = m_voltab[m_out_raw]; /* This post-pokey stage usually has a low-pass filter behind it * It is approximated by not adding in VRef below. */ @@ -771,7 +777,7 @@ void pokey_device::sound_stream_update(sound_stream &stream, stream_sample_t **i } else if (m_output_type == DISCRETE_VAR_R) { - int32_t out = m_voltab[m_output]; + int32_t out = m_voltab[m_out_raw]; while( samples > 0 ) { *buffer++ = out; @@ -898,6 +904,7 @@ void pokey_device::write_internal(offs_t offset, uint8_t data) case AUDC1_C: LOG_SOUND(("POKEY '%s' AUDC1 $%02x (%s)\n", tag(), data, audc2str(data))); m_channel[CHAN1].m_AUDC = data; + m_old_raw_inval = true; break; case AUDF2_C: @@ -908,6 +915,7 @@ void pokey_device::write_internal(offs_t offset, uint8_t data) case AUDC2_C: LOG_SOUND(("POKEY '%s' AUDC2 $%02x (%s)\n", tag(), data, audc2str(data))); m_channel[CHAN2].m_AUDC = data; + m_old_raw_inval = true; break; case AUDF3_C: @@ -918,6 +926,7 @@ void pokey_device::write_internal(offs_t offset, uint8_t data) case AUDC3_C: LOG_SOUND(("POKEY '%s' AUDC3 $%02x (%s)\n", tag(), data, audc2str(data))); m_channel[CHAN3].m_AUDC = data; + m_old_raw_inval = true; break; case AUDF4_C: @@ -928,6 +937,7 @@ void pokey_device::write_internal(offs_t offset, uint8_t data) case AUDC4_C: LOG_SOUND(("POKEY '%s' AUDC4 $%02x (%s)\n", tag(), data, audc2str(data))); m_channel[CHAN4].m_AUDC = data; + m_old_raw_inval = true; break; case AUDCTL_C: @@ -952,7 +962,7 @@ void pokey_device::write_internal(offs_t offset, uint8_t data) m_channel[i].m_output = 0; m_channel[i].m_filter_sample = (i<2 ? 1 : 0); } - + m_old_raw_inval = true; break; case SKREST_C: @@ -1070,6 +1080,7 @@ inline void pokey_device::process_channel(int ch) m_channel[ch].m_output = (m_poly9[m_p9] & 1); else m_channel[ch].m_output = (m_poly17[m_p17] & 1); + m_old_raw_inval = true; } } diff --git a/src/devices/sound/pokey.h b/src/devices/sound/pokey.h index 0fa9e21a17d..7e63e89e54d 100644 --- a/src/devices/sound/pokey.h +++ b/src/devices/sound/pokey.h @@ -264,7 +264,7 @@ private: static constexpr int POKEY_CHANNELS = 4; - uint32_t step_one_clock(); + void step_one_clock(); void step_keyboard(); void step_pot(); @@ -284,10 +284,11 @@ private: pokey_channel m_channel[POKEY_CHANNELS]; - uint32_t m_output; /* raw output */ - double m_out_filter; /* filtered output */ + uint32_t m_out_raw; /* raw output */ + bool m_old_raw_inval; /* true: recalc m_out_raw required */ + double m_out_filter; /* filtered output */ - int32_t m_clock_cnt[3]; /* clock counters */ + int32_t m_clock_cnt[3]; /* clock counters */ uint32_t m_p4; /* poly4 index */ uint32_t m_p5; /* poly5 index */ uint32_t m_p9; /* poly9 index */ diff --git a/src/devices/sound/spkrdev.h b/src/devices/sound/spkrdev.h index 7542d943793..49e953b5d40 100644 --- a/src/devices/sound/spkrdev.h +++ b/src/devices/sound/spkrdev.h @@ -21,9 +21,9 @@ public: ~speaker_sound_device() {} // configuration - void set_levels(int num_levels, const int16_t *levels) { m_num_levels = num_levels; m_levels = levels;} + void set_levels(int num_levels, const int16_t *levels) { m_num_levels = num_levels; m_levels = levels; } - void level_w(int new_level); + void level_w(int new_level); // can use as writeline protected: // device-level overrides diff --git a/src/devices/video/mc6845.cpp b/src/devices/video/mc6845.cpp index da4a015a1c6..fe8e4a0119b 100644 --- a/src/devices/video/mc6845.cpp +++ b/src/devices/video/mc6845.cpp @@ -582,8 +582,6 @@ void mc6845_device::recompute_parameters(bool postload) m_hsync_off_pos = hsync_off_pos; m_vsync_on_pos = vsync_on_pos; m_vsync_off_pos = vsync_off_pos; - if (!postload) // set m_line_counter to 0 on normal operation, but not on postload - m_line_counter = 0; } } |