mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
bus/a2bus updates: [Vas Crabb, Golden Child]
* Added Orange Micro Buffered Grappler+ printer interface card. * Synchronise all I/O for Apple Parallel Interface Card.
This commit is contained in:
parent
d7199ad66f
commit
0a687da2ae
@ -323,46 +323,25 @@ void a2bus_pic_device::device_reset()
|
||||
|
||||
WRITE_LINE_MEMBER(a2bus_pic_device::ack_w)
|
||||
{
|
||||
if (bool(state) != bool(m_ack_in))
|
||||
{
|
||||
m_ack_in = state ? 1U : 0U;
|
||||
LOG("/ACK=%u\n", m_ack_in);
|
||||
if (started() && (m_ack_in != BIT(m_input_sw1->read(), 4)))
|
||||
{
|
||||
LOG("Active /ACK edge\n");
|
||||
set_ack_latch();
|
||||
}
|
||||
}
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(a2bus_pic_device::set_ack_in), this), state ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(a2bus_pic_device::perror_w)
|
||||
{
|
||||
if (bool(state) != bool(m_perror_in))
|
||||
{
|
||||
m_perror_in = state ? 1U : 0U;
|
||||
LOG("PAPER EMPTY=%u\n", m_perror_in);
|
||||
}
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(a2bus_pic_device::set_perror_in), this), state ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(a2bus_pic_device::select_w)
|
||||
{
|
||||
if (bool(state) != bool(m_select_in))
|
||||
{
|
||||
m_select_in = state ? 1U : 0U;
|
||||
LOG("SELECT=%u\n", m_select_in);
|
||||
}
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(a2bus_pic_device::set_select_in), this), state ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(a2bus_pic_device::fault_w)
|
||||
{
|
||||
if (bool(state) != bool(m_fault_in))
|
||||
{
|
||||
m_fault_in = state ? 1U : 0U;
|
||||
LOG("/FAULT=%u\n", m_fault_in);
|
||||
}
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(a2bus_pic_device::set_fault_in), this), state ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
@ -380,6 +359,56 @@ TIMER_CALLBACK_MEMBER(a2bus_pic_device::release_strobe)
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
// synchronised inputs
|
||||
//----------------------------------------------
|
||||
|
||||
void a2bus_pic_device::set_ack_in(void *ptr, s32 param)
|
||||
{
|
||||
if (u32(param) != m_ack_in)
|
||||
{
|
||||
m_ack_in = u8(u32(param));
|
||||
LOG("/ACK=%u\n", m_ack_in);
|
||||
if (started() && (m_ack_in != BIT(m_input_sw1->read(), 4)))
|
||||
{
|
||||
LOG("Active /ACK edge\n");
|
||||
set_ack_latch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void a2bus_pic_device::set_perror_in(void *ptr, s32 param)
|
||||
{
|
||||
if (u32(param) != m_perror_in)
|
||||
{
|
||||
m_perror_in = u8(u32(param));
|
||||
LOG("PAPER EMPTY=%u\n", m_perror_in);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void a2bus_pic_device::set_select_in(void *ptr, s32 param)
|
||||
{
|
||||
if (u32(param) != m_select_in)
|
||||
{
|
||||
m_select_in = u8(u32(param));
|
||||
LOG("SELECT=%u\n", m_select_in);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void a2bus_pic_device::set_fault_in(void *ptr, s32 param)
|
||||
{
|
||||
if (u32(param) != m_fault_in)
|
||||
{
|
||||
m_fault_in = u8(u32(param));
|
||||
LOG("/FAULT=%u\n", m_fault_in);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
// helpers
|
||||
//----------------------------------------------
|
||||
|
@ -91,6 +91,12 @@ private:
|
||||
// timer handlers
|
||||
TIMER_CALLBACK_MEMBER(release_strobe);
|
||||
|
||||
// synchronised inputs
|
||||
void set_ack_in(void *ptr, s32 param);
|
||||
void set_perror_in(void *ptr, s32 param);
|
||||
void set_select_in(void *ptr, s32 param);
|
||||
void set_fault_in(void *ptr, s32 param);
|
||||
|
||||
// helpers
|
||||
void reset_mode();
|
||||
void start_strobe();
|
||||
|
@ -1,5 +1,10 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
/*
|
||||
* TODO for Buffered Grappler+:
|
||||
* - /RST does not reset the MCU, it’s connected to P27
|
||||
* - On the schematic, P22 is pulled up, but the program checks it - perhaps a test mode?
|
||||
*/
|
||||
#include "emu.h"
|
||||
#include "grapplerplus.h"
|
||||
|
||||
@ -22,6 +27,18 @@ ROM_START(grapplerplus)
|
||||
ROM_END
|
||||
|
||||
|
||||
ROM_START(bufgrapplerplus)
|
||||
// TODO: get proper ROM labels and confirm contents
|
||||
// despite having the same version string, this differs from the Grapper+ 3.2.u9 ROM
|
||||
|
||||
ROM_REGION(0x1000, "rom", 0)
|
||||
ROM_LOAD( "3.2.u18", 0x0000, 0x1000, CRC(cd07c7ef) SHA1(6c2f1375b5df6bb65dfca1444c064661242fef1a) )
|
||||
|
||||
ROM_REGION(0x0400, "mcu", 0)
|
||||
ROM_LOAD( "8048.u10", 0x0000, 0x0400, CRC(f60c14a9) SHA1(e7d87dd2f7af42f0eed776b839dea0a351ab67bc) )
|
||||
ROM_END
|
||||
|
||||
|
||||
INPUT_PORTS_START(grapplerplus)
|
||||
PORT_START("S1")
|
||||
PORT_DIPNAME(0x07, 0x00, "Printer Type") PORT_DIPLOCATION("S1:4,3,2")
|
||||
@ -33,7 +50,7 @@ INPUT_PORTS_START(grapplerplus)
|
||||
PORT_DIPSETTING( 0x06, "Okidata 84 w/o Step II Graphics")
|
||||
PORT_DIPSETTING( 0x05, "Apple Dot Matrix")
|
||||
PORT_DIPSETTING( 0x07, "invalid")
|
||||
PORT_DIPNAME(0x08, 0x08, "Most Significant Bit") PORT_DIPLOCATION("S1:1") PORT_CHANGED_MEMBER(DEVICE_SELF, a2bus_grapplerplus_device, sw_msb, 0)
|
||||
PORT_DIPNAME(0x08, 0x08, "Most Significant Bit") PORT_DIPLOCATION("S1:1") PORT_CHANGED_MEMBER(DEVICE_SELF, a2bus_grapplerplus_device_base, sw_msb, 0)
|
||||
PORT_DIPSETTING( 0x08, "Software Control")
|
||||
PORT_DIPSETTING( 0x00, "Not Transmitted")
|
||||
INPUT_PORTS_END
|
||||
@ -43,70 +60,85 @@ INPUT_PORTS_END
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE(A2BUS_GRAPPLERPLUS, a2bus_grapplerplus_device, "a2grapplerplus", "Orange Micro Grappler+ Printer Interface")
|
||||
DEFINE_DEVICE_TYPE(A2BUS_BUFGRAPPLERPLUS, a2bus_buf_grapplerplus_device, "a2bufgrapplerplus", "Orange Micro Buffered Grappler+ Printer Interface")
|
||||
|
||||
|
||||
|
||||
a2bus_grapplerplus_device::a2bus_grapplerplus_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
|
||||
device_t(mconfig, A2BUS_GRAPPLERPLUS, tag, owner, clock),
|
||||
//==============================================================
|
||||
// Grappler+ base
|
||||
//==============================================================
|
||||
|
||||
a2bus_grapplerplus_device_base::a2bus_grapplerplus_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) :
|
||||
device_t(mconfig, type, tag, owner, clock),
|
||||
device_a2bus_card_interface(mconfig, *this),
|
||||
m_printer_conn(*this, "prn"),
|
||||
m_printer_out(*this, "prn_out"),
|
||||
m_s1(*this, "S1"),
|
||||
m_rom(*this, "rom"),
|
||||
m_strobe_timer(nullptr),
|
||||
m_rom_bank(0x0000U),
|
||||
m_data_latch(0xffU),
|
||||
m_ack_latch(0x01U),
|
||||
m_irq_disable(1U),
|
||||
m_irq(0x00U),
|
||||
m_next_strobe(1U),
|
||||
m_ack_latch(1U),
|
||||
m_ack_in(1U),
|
||||
m_busy_in(0x8U),
|
||||
m_pe_in(0x04U),
|
||||
m_slct_in(0x02U)
|
||||
m_busy_in(1U),
|
||||
m_pe_in(1U),
|
||||
m_slct_in(1U)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
// DIP switch handlers
|
||||
//----------------------------------------------
|
||||
//--------------------------------------------------
|
||||
// device_t implementation
|
||||
//--------------------------------------------------
|
||||
|
||||
INPUT_CHANGED_MEMBER(a2bus_grapplerplus_device::sw_msb)
|
||||
void a2bus_grapplerplus_device_base::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
if (BIT(m_data_latch, 7))
|
||||
m_printer_out->write(m_data_latch & (BIT(m_s1->read(), 3) ? 0xffU : 0x7fU));
|
||||
CENTRONICS(config, m_printer_conn, centronics_devices, "printer");
|
||||
m_printer_conn->busy_handler().set(FUNC(a2bus_grapplerplus_device_base::busy_w));
|
||||
m_printer_conn->perror_handler().set(FUNC(a2bus_grapplerplus_device_base::pe_w));
|
||||
m_printer_conn->select_handler().set(FUNC(a2bus_grapplerplus_device_base::slct_w));
|
||||
|
||||
OUTPUT_LATCH(config, m_printer_out);
|
||||
m_printer_conn->set_output_latch(*m_printer_out);
|
||||
}
|
||||
|
||||
|
||||
ioport_constructor a2bus_grapplerplus_device_base::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(grapplerplus);
|
||||
}
|
||||
|
||||
|
||||
void a2bus_grapplerplus_device_base::device_start()
|
||||
{
|
||||
save_item(NAME(m_rom_bank));
|
||||
save_item(NAME(m_ack_latch));
|
||||
save_item(NAME(m_ack_in));
|
||||
save_item(NAME(m_busy_in));
|
||||
save_item(NAME(m_pe_in));
|
||||
save_item(NAME(m_slct_in));
|
||||
}
|
||||
|
||||
|
||||
void a2bus_grapplerplus_device_base::device_reset()
|
||||
{
|
||||
m_ack_latch = 1U;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
//--------------------------------------------------
|
||||
// device_a2bus_card_interface implementation
|
||||
//----------------------------------------------
|
||||
//--------------------------------------------------
|
||||
|
||||
u8 a2bus_grapplerplus_device::read_c0nx(u8 offset)
|
||||
{
|
||||
return
|
||||
m_irq |
|
||||
((m_s1->read() & 0x07U) << 4) |
|
||||
m_busy_in |
|
||||
m_pe_in |
|
||||
m_slct_in |
|
||||
m_ack_latch;
|
||||
}
|
||||
|
||||
|
||||
void a2bus_grapplerplus_device::write_c0nx(u8 offset, u8 data)
|
||||
void a2bus_grapplerplus_device_base::write_c0nx(u8 offset, u8 data)
|
||||
{
|
||||
LOG("Write C0n%01X=%02X\n", offset, data);
|
||||
|
||||
if (!(offset & 0x03U)) // !A0 && !A1 - write data
|
||||
{
|
||||
// latch output data - remember MSB can be forced low by DIP switch
|
||||
// latch output data
|
||||
LOG("Latch data %02X\n", data);
|
||||
m_data_latch = data;
|
||||
m_printer_out->write(data & (BIT(m_s1->read(), 3) ? 0xffU : 0x7fU));
|
||||
data_latched(data);
|
||||
|
||||
// clearing the ACK latch will acknowledge an interrupt
|
||||
if (m_ack_in)
|
||||
@ -115,27 +147,13 @@ void a2bus_grapplerplus_device::write_c0nx(u8 offset, u8 data)
|
||||
LOG("Clearing acknowledge latch\n");
|
||||
else
|
||||
LOG("Previous data not acknowledged\n");
|
||||
m_ack_latch = 0x00U;
|
||||
if (m_irq)
|
||||
{
|
||||
assert(!m_irq_disable);
|
||||
LOG("Releasing slot IRQ\n");
|
||||
m_irq = 0x00U;
|
||||
lower_slot_irq();
|
||||
}
|
||||
m_ack_latch = 0U;
|
||||
ack_latch_cleared();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("/ACK asserted, not clearing acknowledge latch\n");
|
||||
}
|
||||
|
||||
// generate strobe pulse after one clock cycle
|
||||
m_next_strobe = 0U;
|
||||
if (!m_strobe_timer->enabled())
|
||||
{
|
||||
LOG("Start strobe timer\n");
|
||||
m_strobe_timer->adjust(attotime::from_ticks(1, clock()));
|
||||
}
|
||||
}
|
||||
|
||||
if (BIT(offset, 0)) // A0 - select high ROM bank
|
||||
@ -146,6 +164,168 @@ void a2bus_grapplerplus_device::write_c0nx(u8 offset, u8 data)
|
||||
LOG("High ROM bank already selected\n");
|
||||
m_rom_bank = 0x0800U;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
u8 a2bus_grapplerplus_device_base::read_cnxx(u8 offset)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (m_rom_bank)
|
||||
LOG("Select low ROM bank\n");
|
||||
m_rom_bank = 0x0000U;
|
||||
}
|
||||
return m_rom[(!m_ack_latch && BIT(offset, 7)) ? (offset & 0xbfU) : offset];
|
||||
}
|
||||
|
||||
|
||||
void a2bus_grapplerplus_device_base::write_cnxx(u8 offset, u8 data)
|
||||
{
|
||||
LOG("Write Cn%02X=%02X (bus conflict)\n", offset, data);
|
||||
|
||||
if (m_rom_bank)
|
||||
LOG("Select low ROM bank\n");
|
||||
m_rom_bank = 0x0000U;
|
||||
}
|
||||
|
||||
|
||||
u8 a2bus_grapplerplus_device_base::read_c800(u16 offset)
|
||||
{
|
||||
return m_rom[(offset & 0x07ffU) | m_rom_bank];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// printer status inputs
|
||||
//--------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER(a2bus_grapplerplus_device_base::ack_w)
|
||||
{
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(a2bus_grapplerplus_device_base::set_ack_in), this), state ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(a2bus_grapplerplus_device_base::busy_w)
|
||||
{
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(a2bus_grapplerplus_device_base::set_busy_in), this), state ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(a2bus_grapplerplus_device_base::pe_w)
|
||||
{
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(a2bus_grapplerplus_device_base::set_pe_in), this), state ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(a2bus_grapplerplus_device_base::slct_w)
|
||||
{
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(a2bus_grapplerplus_device_base::set_slct_in), this), state ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// synchronised printer status inputs
|
||||
//--------------------------------------------------
|
||||
|
||||
void a2bus_grapplerplus_device_base::set_ack_in(void *ptr, s32 param)
|
||||
{
|
||||
if (u32(param) != m_ack_in)
|
||||
{
|
||||
LOG("/ACK=%d\n", param);
|
||||
m_ack_in = u8(u32(param));
|
||||
if (!param)
|
||||
{
|
||||
if (!m_ack_latch)
|
||||
LOG("Set acknowledge latch\n");
|
||||
else
|
||||
LOG("No data written since previous acknowledge\n");
|
||||
m_ack_latch = 1U;
|
||||
ack_latch_set();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void a2bus_grapplerplus_device_base::set_busy_in(void *ptr, s32 param)
|
||||
{
|
||||
if (u32(param) != m_busy_in)
|
||||
{
|
||||
LOG("BUSY=%d\n", param);
|
||||
m_busy_in = u8(u32(param));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void a2bus_grapplerplus_device_base::set_pe_in(void *ptr, s32 param)
|
||||
{
|
||||
if (u32(param) != m_pe_in)
|
||||
{
|
||||
LOG("PAPER EMPTY=%d\n", param);
|
||||
m_pe_in = u8(u32(param));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void a2bus_grapplerplus_device_base::set_slct_in(void *ptr, s32 param)
|
||||
{
|
||||
if (u32(param) != m_slct_in)
|
||||
{
|
||||
LOG("SELECT=%d\n", state);
|
||||
m_slct_in = u8(u32(param));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============================================================
|
||||
// Grappler+ implementation
|
||||
//==============================================================
|
||||
|
||||
a2bus_grapplerplus_device::a2bus_grapplerplus_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
|
||||
a2bus_grapplerplus_device_base(mconfig, A2BUS_GRAPPLERPLUS, tag, owner, clock),
|
||||
m_strobe_timer(nullptr),
|
||||
m_data_latch(0xffU),
|
||||
m_irq_disable(1U),
|
||||
m_irq(0x00U),
|
||||
m_next_strobe(1U)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// DIP switch handlers
|
||||
//--------------------------------------------------
|
||||
|
||||
INPUT_CHANGED_MEMBER(a2bus_grapplerplus_device::sw_msb)
|
||||
{
|
||||
if (BIT(m_data_latch, 7))
|
||||
m_printer_out->write(m_data_latch & (BIT(m_s1->read(), 3) ? 0xffU : 0x7fU));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// device_a2bus_card_interface implementation
|
||||
//--------------------------------------------------
|
||||
|
||||
u8 a2bus_grapplerplus_device::read_c0nx(u8 offset)
|
||||
{
|
||||
return
|
||||
m_irq |
|
||||
((m_s1->read() & 0x07U) << 4) |
|
||||
(busy_in() << 3) |
|
||||
(pe_in() << 2) |
|
||||
(slct_in() << 1) |
|
||||
ack_latch();
|
||||
}
|
||||
|
||||
|
||||
void a2bus_grapplerplus_device::write_c0nx(u8 offset, u8 data)
|
||||
{
|
||||
a2bus_grapplerplus_device_base::write_c0nx(offset, data);
|
||||
|
||||
if (BIT(offset, 1)) // A1 - disable interrupt
|
||||
{
|
||||
@ -156,7 +336,7 @@ void a2bus_grapplerplus_device::write_c0nx(u8 offset, u8 data)
|
||||
m_irq_disable = 1U;
|
||||
if (m_irq)
|
||||
{
|
||||
assert(m_ack_latch);
|
||||
assert(ack_latch());
|
||||
LOG("Releasing slot IRQ\n");
|
||||
m_irq = 0x00U;
|
||||
lower_slot_irq();
|
||||
@ -169,7 +349,7 @@ void a2bus_grapplerplus_device::write_c0nx(u8 offset, u8 data)
|
||||
else
|
||||
LOG("Interrupt request already enabled\n");
|
||||
m_irq_disable = 0U;
|
||||
if (m_ack_latch && !m_irq)
|
||||
if (ack_latch() && !m_irq)
|
||||
{
|
||||
LOG("Asserting slot IRQ\n");
|
||||
m_irq = 0x80U;
|
||||
@ -179,38 +359,10 @@ void a2bus_grapplerplus_device::write_c0nx(u8 offset, u8 data)
|
||||
}
|
||||
|
||||
|
||||
u8 a2bus_grapplerplus_device::read_cnxx(u8 offset)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (m_rom_bank)
|
||||
LOG("Select low ROM bank\n");
|
||||
m_rom_bank = 0x0000U;
|
||||
}
|
||||
return m_rom[(!m_ack_latch && BIT(offset, 7)) ? (offset & 0xbfU) : offset];
|
||||
}
|
||||
|
||||
|
||||
void a2bus_grapplerplus_device::write_cnxx(u8 offset, u8 data)
|
||||
{
|
||||
LOG("Write Cn%02X=%02X (bus conflict)\n", offset, data);
|
||||
|
||||
if (m_rom_bank)
|
||||
LOG("Select low ROM bank\n");
|
||||
m_rom_bank = 0x0000U;
|
||||
}
|
||||
|
||||
|
||||
u8 a2bus_grapplerplus_device::read_c800(u16 offset)
|
||||
{
|
||||
return m_rom[(offset & 0x07ffU) | m_rom_bank];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
//--------------------------------------------------
|
||||
// device_t implementation
|
||||
//----------------------------------------------
|
||||
//--------------------------------------------------
|
||||
|
||||
tiny_rom_entry const *a2bus_grapplerplus_device::device_rom_region() const
|
||||
{
|
||||
@ -220,47 +372,33 @@ tiny_rom_entry const *a2bus_grapplerplus_device::device_rom_region() const
|
||||
|
||||
void a2bus_grapplerplus_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
CENTRONICS(config, m_printer_conn, centronics_devices, "printer");
|
||||
a2bus_grapplerplus_device_base::device_add_mconfig(config);
|
||||
|
||||
m_printer_conn->ack_handler().set(FUNC(a2bus_grapplerplus_device::ack_w));
|
||||
m_printer_conn->busy_handler().set(FUNC(a2bus_grapplerplus_device::busy_w));
|
||||
m_printer_conn->perror_handler().set(FUNC(a2bus_grapplerplus_device::pe_w));
|
||||
m_printer_conn->select_handler().set(FUNC(a2bus_grapplerplus_device::slct_w));
|
||||
|
||||
OUTPUT_LATCH(config, m_printer_out);
|
||||
m_printer_conn->set_output_latch(*m_printer_out);
|
||||
}
|
||||
|
||||
|
||||
ioport_constructor a2bus_grapplerplus_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(grapplerplus);
|
||||
}
|
||||
|
||||
|
||||
void a2bus_grapplerplus_device::device_start()
|
||||
{
|
||||
a2bus_grapplerplus_device_base::device_start();
|
||||
|
||||
m_strobe_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(a2bus_grapplerplus_device::update_strobe), this));
|
||||
|
||||
m_next_strobe = 1U;
|
||||
|
||||
save_item(NAME(m_rom_bank));
|
||||
save_item(NAME(m_data_latch));
|
||||
save_item(NAME(m_ack_latch));
|
||||
save_item(NAME(m_irq_disable));
|
||||
save_item(NAME(m_irq));
|
||||
save_item(NAME(m_next_strobe));
|
||||
save_item(NAME(m_ack_in));
|
||||
save_item(NAME(m_busy_in));
|
||||
save_item(NAME(m_pe_in));
|
||||
save_item(NAME(m_slct_in));
|
||||
|
||||
m_strobe_timer->adjust(attotime::from_ticks(1, clock()));
|
||||
m_strobe_timer->adjust(attotime::from_ticks(7, clock()));
|
||||
}
|
||||
|
||||
|
||||
void a2bus_grapplerplus_device::device_reset()
|
||||
{
|
||||
m_ack_latch = 0x01U;
|
||||
a2bus_grapplerplus_device_base::device_reset();
|
||||
|
||||
m_irq_disable = 1U;
|
||||
if (m_irq)
|
||||
{
|
||||
@ -271,68 +409,53 @@ void a2bus_grapplerplus_device::device_reset()
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
// printer status inputs
|
||||
//----------------------------------------------
|
||||
//--------------------------------------------------
|
||||
// a2bus_grapplerplus_device_base implementation
|
||||
//--------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER(a2bus_grapplerplus_device::ack_w)
|
||||
void a2bus_grapplerplus_device::data_latched(u8 data)
|
||||
{
|
||||
if (bool(state) != bool(m_ack_in))
|
||||
// remember MSB can be forced low by DIP switch
|
||||
m_data_latch = data;
|
||||
m_printer_out->write(m_data_latch & (BIT(m_s1->read(), 3) ? 0xffU : 0x7fU));
|
||||
|
||||
// generate strobe pulse after one clock cycle
|
||||
m_next_strobe = 0U;
|
||||
if (!m_strobe_timer->enabled())
|
||||
{
|
||||
LOG("/ACK=%d\n", state);
|
||||
m_ack_in = state ? 1U : 0U;
|
||||
if (!state)
|
||||
{
|
||||
if (!m_ack_latch)
|
||||
LOG("Set acknowledge latch\n");
|
||||
else
|
||||
LOG("No data written since previous acknowledge\n");
|
||||
m_ack_latch = 0x01U;
|
||||
if (!m_irq_disable && !m_irq)
|
||||
{
|
||||
LOG("Asserting slot IRQ\n");
|
||||
m_irq = 0x80U;
|
||||
raise_slot_irq();
|
||||
}
|
||||
}
|
||||
LOG("Start strobe timer\n");
|
||||
m_strobe_timer->adjust(attotime::from_ticks(7, clock()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(a2bus_grapplerplus_device::busy_w)
|
||||
void a2bus_grapplerplus_device::ack_latch_set()
|
||||
{
|
||||
if (bool(state) != bool(m_busy_in))
|
||||
if (!m_irq_disable && !m_irq)
|
||||
{
|
||||
LOG("BUSY=%d\n", state);
|
||||
m_busy_in = state ? 0x08U : 0x00U;
|
||||
LOG("Asserting slot IRQ\n");
|
||||
m_irq = 0x80U;
|
||||
raise_slot_irq();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(a2bus_grapplerplus_device::pe_w)
|
||||
void a2bus_grapplerplus_device::ack_latch_cleared()
|
||||
{
|
||||
if (bool(state) != bool(m_pe_in))
|
||||
if (m_irq)
|
||||
{
|
||||
LOG("PAPER EMPTY=%d\n", state);
|
||||
m_pe_in = state ? 0x04U : 0x00U;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(a2bus_grapplerplus_device::slct_w)
|
||||
{
|
||||
if (bool(state) != bool(m_slct_in))
|
||||
{
|
||||
LOG("SELECT=%d\n", state);
|
||||
m_slct_in = state ? 0x02U : 0x00U;
|
||||
assert(!m_irq_disable);
|
||||
LOG("Releasing slot IRQ\n");
|
||||
m_irq = 0x00U;
|
||||
lower_slot_irq();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
//--------------------------------------------------
|
||||
// timer handlers
|
||||
//----------------------------------------------
|
||||
//--------------------------------------------------
|
||||
|
||||
TIMER_CALLBACK_MEMBER(a2bus_grapplerplus_device::update_strobe)
|
||||
{
|
||||
@ -342,6 +465,288 @@ TIMER_CALLBACK_MEMBER(a2bus_grapplerplus_device::update_strobe)
|
||||
{
|
||||
LOG("Start strobe timer\n");
|
||||
m_next_strobe = 1U;
|
||||
m_strobe_timer->adjust(attotime::from_ticks(1, clock()));
|
||||
m_strobe_timer->adjust(attotime::from_ticks(7, clock()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============================================================
|
||||
// Buffered Grappler+ implementation
|
||||
//==============================================================
|
||||
|
||||
a2bus_buf_grapplerplus_device::a2bus_buf_grapplerplus_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
|
||||
a2bus_grapplerplus_device_base(mconfig, A2BUS_BUFGRAPPLERPLUS, tag, owner, clock),
|
||||
m_mcu(*this, "mcu"),
|
||||
m_ram(),
|
||||
m_ram_row(0xff00),
|
||||
m_mcu_p2(0xffU),
|
||||
m_data_latch(0xffU),
|
||||
m_ibusy(1U),
|
||||
m_buf_ack_latch(1U),
|
||||
m_buf_ack_in(1U)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// device_a2bus_card_interface implementation
|
||||
//--------------------------------------------------
|
||||
|
||||
u8 a2bus_buf_grapplerplus_device::read_c0nx(u8 offset)
|
||||
{
|
||||
return
|
||||
((m_s1->read() & 0x0fU) << 4) |
|
||||
(m_ibusy << 3) |
|
||||
(pe_in() << 2) |
|
||||
(slct_in() << 1) |
|
||||
ack_latch();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// device_t implementation
|
||||
//--------------------------------------------------
|
||||
|
||||
tiny_rom_entry const *a2bus_buf_grapplerplus_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(bufgrapplerplus);
|
||||
}
|
||||
|
||||
|
||||
void a2bus_buf_grapplerplus_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
a2bus_grapplerplus_device_base::device_add_mconfig(config);
|
||||
|
||||
m_printer_conn->ack_handler().set(FUNC(a2bus_buf_grapplerplus_device::buf_ack_w));
|
||||
|
||||
I8048(config, m_mcu, DERIVED_CLOCK(1, 1));
|
||||
m_mcu->set_addrmap(AS_IO, &a2bus_buf_grapplerplus_device::mcu_io);
|
||||
m_mcu->p2_out_cb().set(FUNC(a2bus_buf_grapplerplus_device::mcu_p2_w));
|
||||
m_mcu->t0_in_cb().set([this] () { return busy_in(); });
|
||||
m_mcu->t1_in_cb().set([this] () { return m_buf_ack_latch; });
|
||||
m_mcu->bus_in_cb().set(FUNC(a2bus_buf_grapplerplus_device::mcu_bus_r));
|
||||
m_mcu->bus_out_cb().set(FUNC(a2bus_buf_grapplerplus_device::mcu_bus_w));
|
||||
}
|
||||
|
||||
|
||||
void a2bus_buf_grapplerplus_device::device_start()
|
||||
{
|
||||
a2bus_grapplerplus_device_base::device_start();
|
||||
|
||||
m_ram = std::make_unique<u8 []>(0x10000);
|
||||
|
||||
save_pointer(NAME(m_ram), 0x10000);
|
||||
save_item(NAME(m_ram_row));
|
||||
save_item(NAME(m_mcu_p2));
|
||||
save_item(NAME(m_data_latch));
|
||||
save_item(NAME(m_ibusy));
|
||||
save_item(NAME(m_buf_ack_latch));
|
||||
save_item(NAME(m_buf_ack_in));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// a2bus_grapplerplus_device_base implementation
|
||||
//--------------------------------------------------
|
||||
|
||||
void a2bus_buf_grapplerplus_device::data_latched(u8 data)
|
||||
{
|
||||
// IBUSY is exposed on C0nX
|
||||
if (!m_ibusy)
|
||||
LOG("Setting IBUSY\n");
|
||||
else
|
||||
LOG("IBUSY already set\n");
|
||||
m_ibusy = 1U;
|
||||
|
||||
// these signals cross executable device domains
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(a2bus_buf_grapplerplus_device::set_buf_data), this), int(unsigned(data)));
|
||||
m_mcu->set_input_line(MCS48_INPUT_IRQ, ASSERT_LINE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// printer status inputs
|
||||
//--------------------------------------------------
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(a2bus_buf_grapplerplus_device::buf_ack_w)
|
||||
{
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(a2bus_buf_grapplerplus_device::set_buf_ack_in), this), state ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// MCU I/O handlers
|
||||
//--------------------------------------------------
|
||||
|
||||
void a2bus_buf_grapplerplus_device::mcu_io(address_map &map)
|
||||
{
|
||||
map(0x00, 0xff).nopr(); // read to put the BUS lines in high-impedance state before a real read using INS
|
||||
}
|
||||
|
||||
|
||||
void a2bus_buf_grapplerplus_device::mcu_p2_w(u8 data)
|
||||
{
|
||||
//P22 = pulled up
|
||||
//P27 = /RST
|
||||
|
||||
// check for changed bits
|
||||
u8 const diff(data ^ m_mcu_p2);
|
||||
m_mcu_p2 = data;
|
||||
|
||||
// P20 enables /CAS on /RD or /WR
|
||||
if (BIT(diff, 0))
|
||||
LOG("RAM EN=%u\n", BIT(data, 0));
|
||||
|
||||
// row address strobe
|
||||
if (BIT(diff, 1))
|
||||
{
|
||||
if (!BIT(data, 1))
|
||||
{
|
||||
LOG("Row address %02X\n", m_mcu->p1_r());
|
||||
m_ram_row = u16(m_mcu->p1_r()) << 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("Released /RAS\n");
|
||||
}
|
||||
}
|
||||
|
||||
// P23 is the /IOEN signal
|
||||
if (BIT(diff, 3))
|
||||
LOG("/IOEN=%u\n", BIT(data, 3));
|
||||
|
||||
// P24 allows fast DRAM refresh using ALE for /RAS
|
||||
if (BIT(diff, 4))
|
||||
LOG(BIT(data, 4) ? "Start DRAM refresh\n" : "End DRAM refresh\n");
|
||||
|
||||
// P25 is the strobe output and clears the acknowledge latch
|
||||
if (BIT(diff, 5))
|
||||
{
|
||||
if (BIT(data, 5))
|
||||
{
|
||||
if (m_buf_ack_in)
|
||||
{
|
||||
if (m_buf_ack_latch)
|
||||
LOG("T1 already set\n");
|
||||
else
|
||||
LOG("Setting T1\n");
|
||||
m_buf_ack_latch = 1U;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("/ACK asserted, not setting T1\n");
|
||||
}
|
||||
}
|
||||
LOG("Output /STROBE=%u\n", BIT(data, 5));
|
||||
m_printer_conn->write_strobe(BIT(data, 5));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
u8 a2bus_buf_grapplerplus_device::mcu_bus_r()
|
||||
{
|
||||
u8 result(0xffU);
|
||||
|
||||
// RAM EN enables RAM
|
||||
if (BIT(m_mcu_p2, 0))
|
||||
{
|
||||
if (!BIT(m_mcu_p2, 1))
|
||||
{
|
||||
u16 const addr(m_ram_row | u16(m_mcu->p1_r()));
|
||||
LOG("Read RAM @%04X=%02X\n", addr, m_ram[addr]);
|
||||
result &= m_ram[addr];
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("/RD asserted /CAS while /RAS not asserted\n");
|
||||
}
|
||||
}
|
||||
|
||||
// /IOEN enables the data latch, pulses /IACK and clears IBUSY on /RD
|
||||
if (!BIT(m_mcu_p2, 3))
|
||||
{
|
||||
LOG("Read data latch %02X\n", m_data_latch);
|
||||
result &= m_data_latch;
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(a2bus_buf_grapplerplus_device::clear_ibusy), this));
|
||||
m_mcu->set_input_line(MCS48_INPUT_IRQ, CLEAR_LINE);
|
||||
ack_w(0);
|
||||
ack_w(1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void a2bus_buf_grapplerplus_device::mcu_bus_w(u8 data)
|
||||
{
|
||||
// RAM EN enables RAM
|
||||
if (BIT(m_mcu_p2, 0))
|
||||
{
|
||||
if (!BIT(m_mcu_p2, 1))
|
||||
{
|
||||
u16 const addr(m_ram_row | u16(m_mcu->p1_r()));
|
||||
LOG("Wrote RAM @%04X=%02X\n", addr, data);
|
||||
m_ram[addr] = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("/WR asserted /CAS while /RAS not asserted\n");
|
||||
}
|
||||
}
|
||||
|
||||
// /IOEN enables output latch
|
||||
if (!BIT(m_mcu_p2, 3))
|
||||
{
|
||||
LOG("Output data %02X\n", data);
|
||||
m_printer_out->write(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// synchronised signals
|
||||
//--------------------------------------------------
|
||||
|
||||
void a2bus_buf_grapplerplus_device::set_buf_data(void *ptr, s32 param)
|
||||
{
|
||||
m_data_latch = u8(u32(param));
|
||||
}
|
||||
|
||||
|
||||
void a2bus_buf_grapplerplus_device::set_buf_ack_in(void *ptr, s32 param)
|
||||
{
|
||||
if (u32(param) != m_buf_ack_in)
|
||||
{
|
||||
LOG("/ACK=%d\n", param);
|
||||
m_buf_ack_in = u8(u32(param));
|
||||
if (!param)
|
||||
{
|
||||
if (m_buf_ack_latch)
|
||||
LOG("Clearing T1\n");
|
||||
else
|
||||
LOG("No data output since previous acknowledge\n");
|
||||
m_buf_ack_latch = 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void a2bus_buf_grapplerplus_device::clear_ibusy(void *ptr, s32 param)
|
||||
{
|
||||
if (m_ibusy)
|
||||
{
|
||||
LOG("Clearing IBUSY\n");
|
||||
m_ibusy = 0U;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("IBUSY already clear\n");
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,24 @@
|
||||
P.E. 23 24 GND
|
||||
SLCT 25 26 GND
|
||||
|
||||
Orange Micro Buffered Grappler+ Printer Interface
|
||||
|
||||
26-pin two-row header to printer:
|
||||
|
||||
STB 1 2 GND
|
||||
D0 3 4 GND
|
||||
D1 5 6 GND
|
||||
D2 7 8 GND
|
||||
D3 9 10 GND
|
||||
D4 11 12 GND
|
||||
D5 23 14 GND
|
||||
D6 15 16 GND
|
||||
D7 17 18 GND
|
||||
ACK 19 20 GND
|
||||
BUSY 21 22 GND
|
||||
P.E. 23 24 GND
|
||||
SLCT 25 26 N/C
|
||||
|
||||
***********************************************************************/
|
||||
#ifndef MAME_BUS_A2BUS_GRAPPLERPLUS_H
|
||||
#define MAME_BUS_A2BUS_GRAPPLERPLUS_H
|
||||
@ -33,60 +51,155 @@
|
||||
#pragma once
|
||||
|
||||
#include "a2bus.h"
|
||||
#include "bus/centronics/ctronics.h"
|
||||
|
||||
class a2bus_grapplerplus_device : public device_t, public device_a2bus_card_interface
|
||||
#include "bus/centronics/ctronics.h"
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
|
||||
|
||||
class a2bus_grapplerplus_device_base : public device_t, public device_a2bus_card_interface
|
||||
{
|
||||
public:
|
||||
a2bus_grapplerplus_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
// DIP switch handlers
|
||||
DECLARE_INPUT_CHANGED_MEMBER(sw_msb);
|
||||
virtual DECLARE_INPUT_CHANGED_MEMBER(sw_msb) { }
|
||||
|
||||
// device_a2bus_card_interface implementation
|
||||
virtual u8 read_c0nx(u8 offset) override;
|
||||
virtual void write_c0nx(u8 offset, u8 data) override;
|
||||
virtual u8 read_cnxx(u8 offset) override;
|
||||
virtual void write_cnxx(u8 offset, u8 data) override;
|
||||
virtual u8 read_c800(u16 offset) override;
|
||||
|
||||
protected:
|
||||
a2bus_grapplerplus_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
// device_t implementation
|
||||
virtual tiny_rom_entry const *device_rom_region() const override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// timer handlers
|
||||
TIMER_CALLBACK_MEMBER(update_strobe);
|
||||
|
||||
private:
|
||||
// printer status inputs
|
||||
// ACK latch set input
|
||||
DECLARE_WRITE_LINE_MEMBER(ack_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(busy_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(pe_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(slct_w);
|
||||
|
||||
// signal state
|
||||
u8 ack_latch() const { return m_ack_latch; }
|
||||
u8 busy_in() const { return m_busy_in; }
|
||||
u8 pe_in() const { return m_pe_in; }
|
||||
u8 slct_in() const { return m_slct_in; }
|
||||
|
||||
required_device<centronics_device> m_printer_conn;
|
||||
required_device<output_latch_device> m_printer_out;
|
||||
required_ioport m_s1;
|
||||
required_region_ptr<u8> m_rom;
|
||||
emu_timer * m_strobe_timer;
|
||||
|
||||
private:
|
||||
// printer status inputs
|
||||
DECLARE_WRITE_LINE_MEMBER(busy_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(pe_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(slct_w);
|
||||
|
||||
// synchronised printer status inputs
|
||||
void set_ack_in(void *ptr, s32 param);
|
||||
void set_busy_in(void *ptr, s32 param);
|
||||
void set_pe_in(void *ptr, s32 param);
|
||||
void set_slct_in(void *ptr, s32 param);
|
||||
|
||||
// for derived devices to implement
|
||||
virtual void data_latched(u8 data) = 0;
|
||||
virtual void ack_latch_set() { }
|
||||
virtual void ack_latch_cleared() { }
|
||||
|
||||
required_region_ptr<u8> m_rom;
|
||||
|
||||
u16 m_rom_bank; // U2D (pin 13)
|
||||
u8 m_data_latch; // U10
|
||||
u8 m_ack_latch; // U2C (pin 9)
|
||||
u8 m_ack_in; // printer connector pin 19 (synchronised)
|
||||
u8 m_busy_in; // printer connector pin 21 (synchronised)
|
||||
u8 m_pe_in; // printer connector pin 23 (synchronised)
|
||||
u8 m_slct_in; // printer connector pin 25 (synchronised)
|
||||
};
|
||||
|
||||
|
||||
class a2bus_grapplerplus_device : public a2bus_grapplerplus_device_base
|
||||
{
|
||||
public:
|
||||
a2bus_grapplerplus_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
// DIP switch handlers
|
||||
virtual DECLARE_INPUT_CHANGED_MEMBER(sw_msb) override;
|
||||
|
||||
// device_a2bus_card_interface implementation
|
||||
virtual u8 read_c0nx(u8 offset) override;
|
||||
virtual void write_c0nx(u8 offset, u8 data) override;
|
||||
|
||||
protected:
|
||||
// device_t implementation
|
||||
virtual tiny_rom_entry const *device_rom_region() const override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
// a2bus_grapplerplus_device_base implementation
|
||||
virtual void data_latched(u8 data) override;
|
||||
virtual void ack_latch_set() override;
|
||||
virtual void ack_latch_cleared() override;
|
||||
|
||||
// timer handlers
|
||||
TIMER_CALLBACK_MEMBER(update_strobe);
|
||||
|
||||
emu_timer * m_strobe_timer;
|
||||
|
||||
u8 m_data_latch; // U10
|
||||
u8 m_irq_disable; // U2A (pin 4)
|
||||
u8 m_irq; // U3D (pin 13)
|
||||
u8 m_next_strobe; // U5A (pin 5)
|
||||
u8 m_ack_in; // printer connector pin 19
|
||||
u8 m_busy_in; // printer connector pin 21
|
||||
u8 m_pe_in; // printer connector pin 23
|
||||
u8 m_slct_in; // printer connector pin 25
|
||||
};
|
||||
|
||||
|
||||
class a2bus_buf_grapplerplus_device : public a2bus_grapplerplus_device_base
|
||||
{
|
||||
public:
|
||||
a2bus_buf_grapplerplus_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
// device_a2bus_card_interface implementation
|
||||
virtual u8 read_c0nx(u8 offset) override;
|
||||
|
||||
protected:
|
||||
// device_t implementation
|
||||
virtual tiny_rom_entry const *device_rom_region() const override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual void device_start() override;
|
||||
|
||||
private:
|
||||
// a2bus_grapplerplus_device_base implementation
|
||||
virtual void data_latched(u8 data) override;
|
||||
|
||||
// printer status inputs
|
||||
DECLARE_WRITE_LINE_MEMBER(buf_ack_w);
|
||||
|
||||
// MCU I/O handlers
|
||||
void mcu_io(address_map &map);
|
||||
void mcu_p2_w(u8 data);
|
||||
u8 mcu_bus_r();
|
||||
void mcu_bus_w(u8 data);
|
||||
|
||||
// synchronised signals
|
||||
void set_buf_data(void *ptr, s32 param);
|
||||
void set_buf_ack_in(void *ptr, s32 param);
|
||||
void clear_ibusy(void *ptr, s32 param);
|
||||
|
||||
required_device<mcs48_cpu_device> m_mcu;
|
||||
std::unique_ptr<u8 []> m_ram;
|
||||
|
||||
u16 m_ram_row; // U1-U8
|
||||
u8 m_mcu_p2; // U10
|
||||
u8 m_data_latch; // U14 (synchronised)
|
||||
u8 m_ibusy; // U12
|
||||
u8 m_buf_ack_latch; // U12
|
||||
u8 m_buf_ack_in; // printer connector pin 19 (synchronised)
|
||||
};
|
||||
|
||||
|
||||
DECLARE_DEVICE_TYPE(A2BUS_GRAPPLERPLUS, a2bus_grapplerplus_device)
|
||||
DECLARE_DEVICE_TYPE(A2BUS_BUFGRAPPLERPLUS, a2bus_buf_grapplerplus_device)
|
||||
|
||||
#endif // MAME_BUS_A2BUS_GRAPPLERPLUS_H
|
||||
|
@ -1314,7 +1314,8 @@ static void apple2_cards(device_slot_interface &device)
|
||||
device.option_add("aevm80", A2BUS_AEVIEWMASTER80); /* Applied Engineering ViewMaster 80 */
|
||||
device.option_add("parprn", A2BUS_PARPRN); /* Apple II Parallel Printer Interface Card */
|
||||
device.option_add("parallel", A2BUS_PIC); /* Apple II Parallel Interface Card */
|
||||
device.option_add("grapplerplus", A2BUS_GRAPPLERPLUS); /* Orange Micro Grappler+ Printer Interface card */
|
||||
device.option_add("grapplus", A2BUS_GRAPPLERPLUS); /* Orange Micro Grappler+ Printer Interface card */
|
||||
device.option_add("bufgrapplus", A2BUS_BUFGRAPPLERPLUS); /* Orange Micro Buffered Grappler+ Printer Interface card */
|
||||
device.option_add("corvus", A2BUS_CORVUS); /* Corvus flat-cable HDD interface (see notes in a2corvus.c) */
|
||||
device.option_add("mcms1", A2BUS_MCMS1); /* Mountain Computer Music System, card 1 of 2 */
|
||||
device.option_add("mcms2", A2BUS_MCMS2); /* Mountain Computer Music System, card 2 of 2. must be in card 1's slot + 1! */
|
||||
|
@ -4665,7 +4665,8 @@ static void apple2_cards(device_slot_interface &device)
|
||||
device.option_add("aevm80", A2BUS_AEVIEWMASTER80); /* Applied Engineering ViewMaster 80 */
|
||||
device.option_add("parprn", A2BUS_PARPRN); /* Apple II Parallel Printer Interface Card */
|
||||
device.option_add("parallel", A2BUS_PIC); /* Apple II Parallel Interface Card */
|
||||
device.option_add("grapplerplus", A2BUS_GRAPPLERPLUS); /* Orange Micro Grappler+ Printer Interface card */
|
||||
device.option_add("grapplus", A2BUS_GRAPPLERPLUS); /* Orange Micro Grappler+ Printer Interface card */
|
||||
device.option_add("bufgrapplus", A2BUS_BUFGRAPPLERPLUS); /* Orange Micro Buffered Grappler+ Printer Interface card */
|
||||
device.option_add("corvus", A2BUS_CORVUS); /* Corvus flat-cable HDD interface (see notes in a2corvus.c) */
|
||||
device.option_add("mcms1", A2BUS_MCMS1); /* Mountain Computer Music System, card 1 of 2 */
|
||||
device.option_add("mcms2", A2BUS_MCMS2); /* Mountain Computer Music System, card 2 of 2. must be in card 1's slot + 1! */
|
||||
|
@ -4763,7 +4763,8 @@ static void apple2_cards(device_slot_interface &device)
|
||||
device.option_add("aevm80", A2BUS_AEVIEWMASTER80); /* Applied Engineering ViewMaster 80 */
|
||||
device.option_add("parprn", A2BUS_PARPRN); /* Apple II Parallel Printer Interface Card */
|
||||
device.option_add("parallel", A2BUS_PIC); /* Apple Parallel Interface Card */
|
||||
device.option_add("grapplerplus", A2BUS_GRAPPLERPLUS); /* Orange Micro Grappler+ Printer Interface card */
|
||||
device.option_add("grapplus", A2BUS_GRAPPLERPLUS); /* Orange Micro Grappler+ Printer Interface card */
|
||||
device.option_add("bufgrapplus", A2BUS_BUFGRAPPLERPLUS); /* Orange Micro Buffered Grappler+ Printer Interface card */
|
||||
device.option_add("corvus", A2BUS_CORVUS); /* Corvus flat-cable HDD interface (see notes in a2corvus.c) */
|
||||
device.option_add("mcms1", A2BUS_MCMS1); /* Mountain Computer Music System, card 1 of 2 */
|
||||
device.option_add("mcms2", A2BUS_MCMS2); /* Mountain Computer Music System, card 2 of 2. must be in card 1's slot + 1! */
|
||||
|
Loading…
Reference in New Issue
Block a user