mb88xx: add pla mask option

This commit is contained in:
hap 2024-12-02 14:37:59 +01:00
parent bfb156de8d
commit f0a3637af6
14 changed files with 87 additions and 90 deletions

View File

@ -122,7 +122,8 @@ mb88_cpu_device::mb88_cpu_device(const machine_config &mconfig, device_type type
(data_width == 5) ? address_map_constructor(FUNC(mb88_cpu_device::data_5bit), this) :
(data_width == 6) ? address_map_constructor(FUNC(mb88_cpu_device::data_6bit), this) :
address_map_constructor(FUNC(mb88_cpu_device::data_7bit), this))
, m_PLA(nullptr)
, m_pla_data(nullptr)
, m_pla_bits(8)
, m_read_k(*this, 0)
, m_write_o(*this)
, m_write_p(*this)
@ -194,6 +195,7 @@ void mb88_cpu_device::device_start()
m_serial = timer_alloc(FUNC(mb88_cpu_device::serial_timer), this);
m_ctr = 0;
m_o_output = 0;
save_item(NAME(m_PC));
save_item(NAME(m_PA));
@ -348,17 +350,28 @@ TIMER_CALLBACK_MEMBER(mb88_cpu_device::serial_timer)
m_pending_interrupt |= INT_CAUSE_SERIAL;
}
}
}
int mb88_cpu_device::pla(int inA, int inB)
void mb88_cpu_device::write_pla(u8 index)
{
int index = ((inB & 1) << 4) | (inA & 0x0f);
u8 mask = 0xff;
if (m_PLA)
return m_PLA[index];
if (m_pla_bits == 8)
{
const u8 shift = (index & 0x10) ? 4 : 0;
mask = 0xf << shift;
m_o_output = (m_o_output & ~mask) | (index << shift & mask);
}
else
{
// if the driver hasn't supplied PLA data, just output the index
if (m_pla_data)
m_o_output = m_pla_data[index];
else
m_o_output = index;
}
return index;
m_write_o(0, m_o_output, mask);
}
void mb88_cpu_device::execute_set_input(int inputnum, int state)
@ -492,7 +505,7 @@ void mb88_cpu_device::execute_run()
break;
case 0x01: // outO ZCS:...
m_write_o(pla(m_A, TEST_CF()));
write_pla(TEST_CF() << 4 | m_A);
m_st = 1;
break;

View File

@ -94,7 +94,9 @@ public:
// SO: serial output
auto write_so() { return m_write_so.bind(); }
void set_pla(u8 *pla) { m_PLA = pla; }
// PLA mask option (default to 8-bit)
void set_pla_bits(u8 bits) { m_pla_bits = bits; } // 4-bit or 8-bit (4-bit requires PLA data)
void set_pla_data(u8 *pla) { m_pla_data = pla; }
void clock_w(int state);
@ -136,36 +138,40 @@ private:
address_space_config m_program_config;
address_space_config m_data_config;
u8 m_PC; // Program Counter: 6 bits
u8 m_PA; // Page Address: 4 bits
u16 m_SP[4]; // Stack is 4*10 bit addresses deep, but we also use 3 top bits per address to store flags during irq
u8 m_SI; // Stack index: 2 bits
u8 m_A; // Accumulator: 4 bits
u8 m_X; // Index X: 4 bits
u8 m_Y; // Index Y: 4 bits
u8 m_st; // State flag: 1 bit
u8 m_zf; // Zero flag: 1 bit
u8 m_cf; // Carry flag: 1 bit
u8 m_vf; // Timer overflow flag: 1 bit
u8 m_sf; // Serial Full/Empty flag: 1 bit
u8 m_if; // Interrupt flag: 1 bit
u8 m_PC; // Program Counter: 6 bits
u8 m_PA; // Page Address: 4 bits
u16 m_SP[4]; // Stack is 4*10 bit addresses deep, but we also use 3 top bits per address to store flags during irq
u8 m_SI; // Stack index: 2 bits
u8 m_A; // Accumulator: 4 bits
u8 m_X; // Index X: 4 bits
u8 m_Y; // Index Y: 4 bits
u8 m_st; // State flag: 1 bit
u8 m_zf; // Zero flag: 1 bit
u8 m_cf; // Carry flag: 1 bit
u8 m_vf; // Timer overflow flag: 1 bit
u8 m_sf; // Serial Full/Empty flag: 1 bit
u8 m_if; // Interrupt flag: 1 bit
// Peripheral Control
u8 m_pio; // Peripheral enable bits: 8 bits
u8 m_pio; // Peripheral enable bits: 8 bits
// Timer registers
u8 m_TH; // Timer High: 4 bits
u8 m_TL; // Timer Low: 4 bits
u8 m_TP; // Timer Prescale: 6 bits?
u8 m_ctr; // current external counter value
u8 m_TH; // Timer High: 4 bits
u8 m_TL; // Timer Low: 4 bits
u8 m_TP; // Timer Prescale: 6 bits?
u8 m_ctr; // current external counter value
// Serial registers
u8 m_SB; // Serial buffer: 4 bits
u16 m_SBcount;// number of bits received
u8 m_SB; // Serial buffer: 4 bits
u16 m_SBcount; // number of bits received
emu_timer *m_serial;
// PLA configuration and port callbacks
u8 *m_PLA;
// PLA configuration
u8 *m_pla_data;
u8 m_pla_bits;
u8 m_o_output;
// port callbacks
devcb_read8 m_read_k;
devcb_write8 m_write_o;
devcb_write8 m_write_p;
@ -189,7 +195,7 @@ private:
u8 m_debugger_flags;
TIMER_CALLBACK_MEMBER(serial_timer);
int pla(int inA, int inB);
void write_pla(u8 index);
void update_pio_enable(u8 newpio);
void increment_timer();
void update_pio(int cycles);

View File

@ -1313,7 +1313,7 @@ void mcs48_cpu_device::burn_cycles(int count)
m_prescaler += count;
m_timer += m_prescaler >> 5;
m_prescaler &= 0x1f;
timerover = (oldtimer != 0 && m_timer == 0);
timerover = m_timer < oldtimer;
}
// if the counter is enabled, poll the T1 test input once for each cycle

View File

@ -185,6 +185,7 @@ void scrablex_state::scrablex(machine_config &config)
{
// basic machine hardware
MB8841(config, m_maincpu, 500000); // approximation - RC osc. R=15K, C=100pF
m_maincpu->set_pla_bits(4);
m_maincpu->write_o().set(FUNC(scrablex_state::write_o));
m_maincpu->write_p().set(FUNC(scrablex_state::write_p));
m_maincpu->read_r<0>().set(FUNC(scrablex_state::read_r<0>));

View File

@ -162,13 +162,9 @@ void namco_50xx_device::O_w(uint8_t data)
machine().scheduler().synchronize(timer_expired_delegate(FUNC(namco_50xx_device::O_w_sync),this), data);
}
TIMER_CALLBACK_MEMBER( namco_50xx_device::O_w_sync )
TIMER_CALLBACK_MEMBER(namco_50xx_device::O_w_sync)
{
uint8_t out = (param & 0x0f);
if (param & 0x10)
m_portO = (m_portO & 0x0f) | (out << 4);
else
m_portO = (m_portO & 0xf0) | (out);
m_portO = param;
}
void namco_50xx_device::rw(int state)
@ -176,7 +172,7 @@ void namco_50xx_device::rw(int state)
machine().scheduler().synchronize(timer_expired_delegate(FUNC(namco_50xx_device::rw_sync),this), state);
}
TIMER_CALLBACK_MEMBER( namco_50xx_device::rw_sync )
TIMER_CALLBACK_MEMBER(namco_50xx_device::rw_sync)
{
m_rw = param;
}
@ -191,7 +187,7 @@ void namco_50xx_device::write(uint8_t data)
machine().scheduler().synchronize(timer_expired_delegate(FUNC(namco_50xx_device::write_sync),this), data);
}
TIMER_CALLBACK_MEMBER( namco_50xx_device::write_sync )
TIMER_CALLBACK_MEMBER(namco_50xx_device::write_sync)
{
m_cmd = param;
}
@ -214,8 +210,8 @@ ROM_END
DEFINE_DEVICE_TYPE(NAMCO_50XX, namco_50xx_device, "namco50", "Namco 50xx")
namco_50xx_device::namco_50xx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, NAMCO_50XX, tag, owner, clock),
namco_50xx_device::namco_50xx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, NAMCO_50XX, tag, owner, clock),
m_cpu(*this, "mcu"),
m_rw(0),
m_cmd(0),

View File

@ -32,9 +32,9 @@ private:
uint8_t m_cmd;
uint8_t m_portO;
TIMER_CALLBACK_MEMBER( O_w_sync );
TIMER_CALLBACK_MEMBER( rw_sync );
TIMER_CALLBACK_MEMBER( write_sync );
TIMER_CALLBACK_MEMBER(O_w_sync);
TIMER_CALLBACK_MEMBER(rw_sync);
TIMER_CALLBACK_MEMBER(write_sync);
uint8_t K_r();
uint8_t R0_r();

View File

@ -78,7 +78,7 @@ void namco_51xx_device::rw(int state)
machine().scheduler().synchronize(timer_expired_delegate(FUNC(namco_51xx_device::rw_sync),this), state);
}
TIMER_CALLBACK_MEMBER( namco_51xx_device::rw_sync )
TIMER_CALLBACK_MEMBER(namco_51xx_device::rw_sync)
{
m_rw = param;
}
@ -98,7 +98,7 @@ void namco_51xx_device::write(uint8_t data)
machine().scheduler().synchronize(timer_expired_delegate(FUNC(namco_51xx_device::write_sync),this), data);
}
TIMER_CALLBACK_MEMBER( namco_51xx_device::write_sync )
TIMER_CALLBACK_MEMBER(namco_51xx_device::write_sync)
{
m_portO = param;
}
@ -133,13 +133,9 @@ void namco_51xx_device::O_w(uint8_t data)
machine().scheduler().synchronize(timer_expired_delegate(FUNC(namco_51xx_device::O_w_sync),this), data);
}
TIMER_CALLBACK_MEMBER( namco_51xx_device::O_w_sync )
TIMER_CALLBACK_MEMBER(namco_51xx_device::O_w_sync)
{
uint8_t out = (param & 0x0f);
if (param & 0x10)
m_portO = (m_portO & 0x0f) | (out << 4);
else
m_portO = (m_portO & 0xf0) | (out);
m_portO = param;
}
void namco_51xx_device::P_w(uint8_t data)

View File

@ -47,9 +47,9 @@ private:
void O_w(uint8_t data);
void P_w(uint8_t data);
TIMER_CALLBACK_MEMBER( rw_sync );
TIMER_CALLBACK_MEMBER( write_sync );
TIMER_CALLBACK_MEMBER( O_w_sync );
TIMER_CALLBACK_MEMBER(rw_sync);
TIMER_CALLBACK_MEMBER(write_sync);
TIMER_CALLBACK_MEMBER(O_w_sync);
};
DECLARE_DEVICE_TYPE(NAMCO_51XX, namco_51xx_device)

View File

@ -94,10 +94,7 @@ void namco_52xx_device::R3_w(uint8_t data)
void namco_52xx_device::O_w(uint8_t data)
{
if (data & 0x10)
m_address = (m_address & 0x0fff) | ((data & 0xf) << 12);
else
m_address = (m_address & 0xf0ff) | ((data & 0xf) << 8);
m_address = (m_address & 0x00ff) | (data << 8);
}
@ -106,7 +103,7 @@ void namco_52xx_device::write(uint8_t data)
machine().scheduler().synchronize(timer_expired_delegate(FUNC(namco_52xx_device::write_sync),this), data);
}
TIMER_CALLBACK_MEMBER( namco_52xx_device::write_sync )
TIMER_CALLBACK_MEMBER(namco_52xx_device::write_sync)
{
m_latched_cmd = param;
}
@ -116,7 +113,7 @@ void namco_52xx_device::chip_select(int state)
m_cpu->set_input_line(0, state);
}
TIMER_CALLBACK_MEMBER( namco_52xx_device::external_clock_pulse )
TIMER_CALLBACK_MEMBER(namco_52xx_device::external_clock_pulse)
{
m_cpu->clock_w(ASSERT_LINE);
m_cpu->clock_w(CLEAR_LINE);

View File

@ -27,8 +27,8 @@ protected:
virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
TIMER_CALLBACK_MEMBER( write_sync );
TIMER_CALLBACK_MEMBER( external_clock_pulse );
TIMER_CALLBACK_MEMBER(write_sync);
TIMER_CALLBACK_MEMBER(external_clock_pulse);
private:
// internal state

View File

@ -93,11 +93,7 @@ uint8_t namco_53xx_device::R3_r()
void namco_53xx_device::O_w(uint8_t data)
{
uint8_t out = (data & 0x0f);
if (data & 0x10)
m_portO = (m_portO & 0x0f) | (out << 4);
else
m_portO = (m_portO & 0xf0) | (out);
m_portO = data;
}
void namco_53xx_device::P_w(uint8_t data)

View File

@ -69,20 +69,17 @@ uint8_t namco_54xx_device::R0_r()
return m_latched_cmd & 0x0f;
}
void namco_54xx_device::O_w(uint8_t data)
void namco_54xx_device::O_w(offs_t offset, uint8_t data, uint8_t mem_mask)
{
uint8_t out = (data & 0x0f);
if (data & 0x10)
m_discrete->write(NAMCO_54XX_1_DATA(m_basenode), out);
if (mem_mask == 0x0f)
m_discrete->write(NAMCO_54XX_0_DATA(m_basenode), data & 0x0f);
else
m_discrete->write(NAMCO_54XX_0_DATA(m_basenode), out);
m_discrete->write(NAMCO_54XX_1_DATA(m_basenode), data >> 4);
}
void namco_54xx_device::R1_w(uint8_t data)
{
uint8_t out = (data & 0x0f);
m_discrete->write(NAMCO_54XX_2_DATA(m_basenode), out);
m_discrete->write(NAMCO_54XX_2_DATA(m_basenode), data & 0x0f);
}
@ -91,7 +88,7 @@ void namco_54xx_device::write(uint8_t data)
machine().scheduler().synchronize(timer_expired_delegate(FUNC(namco_54xx_device::write_sync),this), data);
}
TIMER_CALLBACK_MEMBER( namco_54xx_device::write_sync )
TIMER_CALLBACK_MEMBER(namco_54xx_device::write_sync)
{
m_latched_cmd = param;
}
@ -114,8 +111,8 @@ ROM_END
DEFINE_DEVICE_TYPE(NAMCO_54XX, namco_54xx_device, "namco54", "Namco 54xx")
namco_54xx_device::namco_54xx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, NAMCO_54XX, tag, owner, clock),
namco_54xx_device::namco_54xx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, NAMCO_54XX, tag, owner, clock),
m_cpu(*this, "mcu"),
m_discrete(*this, finder_base::DUMMY_TAG),
m_basenode(0),
@ -138,7 +135,7 @@ void namco_54xx_device::device_start()
void namco_54xx_device::device_add_mconfig(machine_config &config)
{
MB8844(config, m_cpu, DERIVED_CLOCK(1,1)); /* parent clock, internally divided by 6 */
MB8844(config, m_cpu, DERIVED_CLOCK(1,1)); // parent clock, internally divided by 6
m_cpu->read_k().set(FUNC(namco_54xx_device::K_r));
m_cpu->write_o().set(FUNC(namco_54xx_device::O_w));
m_cpu->read_r<0>().set(FUNC(namco_54xx_device::R0_r));

View File

@ -35,9 +35,9 @@ private:
uint8_t K_r();
uint8_t R0_r();
void O_w(uint8_t data);
void O_w(offs_t offset, uint8_t data, uint8_t mem_mask);
void R1_w(uint8_t data);
TIMER_CALLBACK_MEMBER( write_sync );
TIMER_CALLBACK_MEMBER(write_sync);
};
DECLARE_DEVICE_TYPE(NAMCO_54XX, namco_54xx_device)

View File

@ -619,12 +619,7 @@ uint8_t arabian_state::mcu_portk_r()
void arabian_state::mcu_port_o_w(uint8_t data)
{
uint8_t out = data & 0x0f;
if (data & 0x10)
m_mcu_port_o = (m_mcu_port_o & 0x0f) | (out << 4);
else
m_mcu_port_o = (m_mcu_port_o & 0xf0) | out;
m_mcu_port_o = data;
}
void arabian_state::mcu_port_p_w(uint8_t data)