// license:BSD-3-Clause // copyright-holders:David Haywood, Charles MacDonald #ifndef MAME_MACHINE_DECO146_H #define MAME_MACHINE_DECO146_H #pragma once #include "machine/gen_latch.h" #define BLK (0xff) #define INPUT_PORT_A (-1) #define INPUT_PORT_B (-2) #define INPUT_PORT_C (-3) #define NIB3__ 0xc, 0xd, 0xe, 0xf #define NIB3R1 0xd, 0xe, 0xf, 0xc #define NIB3R2 0xe, 0xf, 0xc, 0xd #define NIB3R3 0xf, 0xc, 0xd, 0xe #define NIB2__ 0x8, 0x9, 0xa, 0xb #define NIB2R1 0x9, 0xa, 0xb, 0x8 #define NIB2R2 0xa, 0xb, 0x8, 0x9 #define NIB2R3 0xb, 0x8, 0x9, 0xa #define NIB1__ 0x4, 0x5, 0x6, 0x7 #define NIB1R1 0x5, 0x6, 0x7, 0x4 #define NIB1R2 0x6, 0x7, 0x4, 0x5 #define NIB1R3 0x7, 0x4, 0x5, 0x6 #define NIB0__ 0x0, 0x1, 0x2, 0x3 #define NIB0R1 0x1, 0x2, 0x3, 0x0 #define NIB0R2 0x2, 0x3, 0x0, 0x1 #define NIB0R3 0x3, 0x0, 0x1, 0x2 #define BLANK_ BLK, BLK, BLK, BLK struct deco146port_xx { int write_offset; u8 mapping[16]; int use_xor; int use_nand; }; /* Data East 146 protection chip */ class deco_146_base_device : public device_t { public: void write_data(u16 address, u16 data, u16 mem_mask, u8 &csflags); u16 read_data(u16 address, u8 &csflags); auto port_a_cb() { return m_port_a_r.bind(); } auto port_b_cb() { return m_port_b_r.bind(); } auto port_c_cb() { return m_port_c_r.bind(); } // there are some standard ways the chip gets hooked up, so have them here ready to use void set_interface_scramble(u8 a9, u8 a8, u8 a7, u8 a6, u8 a5, u8 a4, u8 a3,u8 a2,u8 a1,u8 a0) { m_external_addrswap[9] = a9; m_external_addrswap[8] = a8; m_external_addrswap[7] = a7; m_external_addrswap[6] = a6; m_external_addrswap[5] = a5; m_external_addrswap[4] = a4; m_external_addrswap[3] = a3; m_external_addrswap[2] = a2; m_external_addrswap[1] = a1; m_external_addrswap[0] = a0; } void set_interface_scramble_reverse() { set_interface_scramble(0,1,2,3,4,5,6,7,8,9); } void set_interface_scramble_interleave() { set_interface_scramble(4, 5, 3, 6, 2, 7, 1, 8, 0, 9); } void set_use_magic_read_address_xor(bool use_xor) { m_magic_read_address_xor_enabled = use_xor; } auto soundlatch_irq_cb() { return m_soundlatch_irq_cb.bind(); } u8 soundlatch_r(); devcb_read16 m_port_a_r; devcb_read16 m_port_b_r; devcb_read16 m_port_c_r; u8 m_bankswitch_swap_read_address; u16 m_magic_read_address_xor; bool m_magic_read_address_xor_enabled; u8 m_xor_port; u8 m_mask_port; u8 m_soundlatch_port; u8 m_external_addrswap[10]; deco146port_xx const *m_lookup_table; protected: deco_146_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); virtual void device_start() override; virtual void device_reset() override; u16 read_protport(u16 address); virtual void write_protport(u16 address, u16 data, u16 mem_mask); virtual u16 read_data_getloc(u16 address, int& location); std::unique_ptr m_rambank[2]; int m_current_rambank; u16 m_nand; u16 m_xor; u16 m_latchaddr; u16 m_latchdata; u8 m_configregion; // which value of upper 4 address lines accesses the config region int m_latchflag; private: TIMER_CALLBACK_MEMBER(write_soundlatch); u8 region_selects[6]; u8 m_soundlatch; devcb_write_line m_soundlatch_irq_cb; }; class deco146_device : public deco_146_base_device { public: deco146_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; DECLARE_DEVICE_TYPE(DECO146PROT, deco146_device) #endif // MAME_MACHINE_DECO146_H