src/mess/machine/a2bus.c
| r0 | r14801 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | a2bus.c - Apple II slot bus and card emulation |
| 4 | |
| 5 | by R. Belmont |
| 6 | |
| 7 | ***************************************************************************/ |
| 8 | |
| 9 | #include "emu.h" |
| 10 | #include "emuopts.h" |
| 11 | #include "machine/a2bus.h" |
| 12 | |
| 13 | |
| 14 | //************************************************************************** |
| 15 | // GLOBAL VARIABLES |
| 16 | //************************************************************************** |
| 17 | |
| 18 | const device_type A2BUS_SLOT = &device_creator<a2bus_slot_device>; |
| 19 | |
| 20 | //************************************************************************** |
| 21 | // LIVE DEVICE |
| 22 | //************************************************************************** |
| 23 | |
| 24 | //------------------------------------------------- |
| 25 | // a2bus_slot_device - constructor |
| 26 | //------------------------------------------------- |
| 27 | a2bus_slot_device::a2bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 28 | device_t(mconfig, A2BUS_SLOT, "A2BUS_SLOT", tag, owner, clock), |
| 29 | device_slot_interface(mconfig, *this) |
| 30 | { |
| 31 | } |
| 32 | |
| 33 | a2bus_slot_device::a2bus_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : |
| 34 | device_t(mconfig, type, name, tag, owner, clock), |
| 35 | device_slot_interface(mconfig, *this) |
| 36 | { |
| 37 | } |
| 38 | |
| 39 | void a2bus_slot_device::static_set_a2bus_slot(device_t &device, const char *tag, const char *slottag) |
| 40 | { |
| 41 | a2bus_slot_device &a2bus_card = dynamic_cast<a2bus_slot_device &>(device); |
| 42 | a2bus_card.m_a2bus_tag = tag; |
| 43 | a2bus_card.m_a2bus_slottag = slottag; |
| 44 | } |
| 45 | |
| 46 | //------------------------------------------------- |
| 47 | // device_start - device-specific startup |
| 48 | //------------------------------------------------- |
| 49 | |
| 50 | void a2bus_slot_device::device_start() |
| 51 | { |
| 52 | device_a2bus_card_interface *dev = dynamic_cast<device_a2bus_card_interface *>(get_card_device()); |
| 53 | |
| 54 | if (dev) device_a2bus_card_interface::static_set_a2bus_tag(*dev, m_a2bus_tag, m_a2bus_slottag); |
| 55 | } |
| 56 | |
| 57 | //************************************************************************** |
| 58 | // GLOBAL VARIABLES |
| 59 | //************************************************************************** |
| 60 | |
| 61 | const device_type A2BUS = &device_creator<a2bus_device>; |
| 62 | |
| 63 | void a2bus_device::static_set_cputag(device_t &device, const char *tag) |
| 64 | { |
| 65 | a2bus_device &a2bus = downcast<a2bus_device &>(device); |
| 66 | a2bus.m_cputag = tag; |
| 67 | } |
| 68 | |
| 69 | //------------------------------------------------- |
| 70 | // device_config_complete - perform any |
| 71 | // operations now that the configuration is |
| 72 | // complete |
| 73 | //------------------------------------------------- |
| 74 | |
| 75 | void a2bus_device::device_config_complete() |
| 76 | { |
| 77 | // inherit a copy of the static data |
| 78 | const a2bus_interface *intf = reinterpret_cast<const a2bus_interface *>(static_config()); |
| 79 | if (intf != NULL) |
| 80 | { |
| 81 | *static_cast<a2bus_interface *>(this) = *intf; |
| 82 | } |
| 83 | |
| 84 | // or initialize to defaults if none provided |
| 85 | else |
| 86 | { |
| 87 | memset(&m_out_irq_cb, 0, sizeof(m_out_irq_cb)); |
| 88 | memset(&m_out_nmi_cb, 0, sizeof(m_out_nmi_cb)); |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | //************************************************************************** |
| 93 | // LIVE DEVICE |
| 94 | //************************************************************************** |
| 95 | |
| 96 | //------------------------------------------------- |
| 97 | // a2bus_device - constructor |
| 98 | //------------------------------------------------- |
| 99 | |
| 100 | a2bus_device::a2bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 101 | device_t(mconfig, A2BUS, "A2BUS", tag, owner, clock) |
| 102 | { |
| 103 | } |
| 104 | |
| 105 | a2bus_device::a2bus_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : |
| 106 | device_t(mconfig, type, name, tag, owner, clock) |
| 107 | { |
| 108 | } |
| 109 | //------------------------------------------------- |
| 110 | // device_start - device-specific startup |
| 111 | //------------------------------------------------- |
| 112 | |
| 113 | void a2bus_device::device_start() |
| 114 | { |
| 115 | m_maincpu = machine().device(m_cputag); |
| 116 | // resolve callbacks |
| 117 | m_out_irq_func.resolve(m_out_irq_cb, *this); |
| 118 | m_out_irq_func.resolve(m_out_nmi_cb, *this); |
| 119 | } |
| 120 | |
| 121 | //------------------------------------------------- |
| 122 | // device_reset - device-specific reset |
| 123 | //------------------------------------------------- |
| 124 | |
| 125 | void a2bus_device::device_reset() |
| 126 | { |
| 127 | } |
| 128 | |
| 129 | void a2bus_device::add_a2bus_card(device_a2bus_card_interface *card) |
| 130 | { |
| 131 | m_device_list.append(*card); |
| 132 | } |
| 133 | |
| 134 | void a2bus_device::set_irq_line(int state) |
| 135 | { |
| 136 | m_out_irq_func(state); |
| 137 | } |
| 138 | |
| 139 | void a2bus_device::set_nmi_line(int state) |
| 140 | { |
| 141 | m_out_nmi_func(state); |
| 142 | } |
| 143 | |
| 144 | // interrupt request from a2bus card |
| 145 | WRITE_LINE_MEMBER( a2bus_device::irq_w ) { m_out_irq_func(state); } |
| 146 | WRITE_LINE_MEMBER( a2bus_device::nmi_w ) { m_out_nmi_func(state); } |
| 147 | |
| 148 | //************************************************************************** |
| 149 | // DEVICE CONFIG A2BUS CARD INTERFACE |
| 150 | //************************************************************************** |
| 151 | |
| 152 | |
| 153 | //************************************************************************** |
| 154 | // DEVICE A2BUS CARD INTERFACE |
| 155 | //************************************************************************** |
| 156 | |
| 157 | //------------------------------------------------- |
| 158 | // device_a2bus_card_interface - constructor |
| 159 | //------------------------------------------------- |
| 160 | |
| 161 | device_a2bus_card_interface::device_a2bus_card_interface(const machine_config &mconfig, device_t &device) |
| 162 | : device_slot_card_interface(mconfig, device), |
| 163 | m_a2bus(NULL), |
| 164 | m_a2bus_tag(NULL) |
| 165 | { |
| 166 | } |
| 167 | |
| 168 | |
| 169 | //------------------------------------------------- |
| 170 | // ~device_a2bus_card_interface - destructor |
| 171 | //------------------------------------------------- |
| 172 | |
| 173 | device_a2bus_card_interface::~device_a2bus_card_interface() |
| 174 | { |
| 175 | } |
| 176 | |
| 177 | void device_a2bus_card_interface::static_set_a2bus_tag(device_t &device, const char *tag, const char *slottag) |
| 178 | { |
| 179 | device_a2bus_card_interface &a2bus_card = dynamic_cast<device_a2bus_card_interface &>(device); |
| 180 | a2bus_card.m_a2bus_tag = tag; |
| 181 | a2bus_card.m_a2bus_slottag = slottag; |
| 182 | } |
| 183 | |
| 184 | void device_a2bus_card_interface::set_a2bus_device() |
| 185 | { |
| 186 | // extract the slot number from the last digit of the slot tag |
| 187 | int tlen = strlen(m_a2bus_slottag); |
| 188 | |
| 189 | m_slot = (m_a2bus_slottag[tlen-1] - '0'); |
| 190 | |
| 191 | if (m_slot < 0 || m_slot > 7) |
| 192 | { |
| 193 | fatalerror("Slot %x out of range for Apple II Bus\n", m_slot); |
| 194 | } |
| 195 | |
| 196 | m_a2bus = dynamic_cast<a2bus_device *>(device().machine().device(m_a2bus_tag)); |
| 197 | m_a2bus->add_a2bus_card(this); |
| 198 | } |
| 199 | |
| 200 | |
src/mess/machine/a2bus.h
| r0 | r14801 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | a2bus.h - Apple II slot bus and card emulation |
| 4 | |
| 5 | by R. Belmont |
| 6 | |
| 7 | ***************************************************************************/ |
| 8 | |
| 9 | #pragma once |
| 10 | |
| 11 | #ifndef __A2BUS_H__ |
| 12 | #define __A2BUS_H__ |
| 13 | |
| 14 | #include "emu.h" |
| 15 | |
| 16 | |
| 17 | //************************************************************************** |
| 18 | // INTERFACE CONFIGURATION MACROS |
| 19 | //************************************************************************** |
| 20 | |
| 21 | #define MCFG_A2BUS_BUS_ADD(_tag, _cputag, _config) \ |
| 22 | MCFG_DEVICE_ADD(_tag, A2BUS, 0) \ |
| 23 | MCFG_DEVICE_CONFIG(_config) \ |
| 24 | a2bus_device::static_set_cputag(*device, _cputag); \ |
| 25 | |
| 26 | #define MCFG_A2BUS_SLOT_ADD(_nbtag, _tag, _slot_intf, _def_slot, _def_inp) \ |
| 27 | MCFG_DEVICE_ADD(_tag, A2BUS_SLOT, 0) \ |
| 28 | MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp) \ |
| 29 | a2bus_slot_device::static_set_a2bus_slot(*device, _nbtag, _tag); \ |
| 30 | |
| 31 | #define MCFG_A2BUS_SLOT_REMOVE(_tag) \ |
| 32 | MCFG_DEVICE_REMOVE(_tag) |
| 33 | |
| 34 | #define MCFG_A2BUS_ONBOARD_ADD(_nbtag, _tag, _dev_type, _def_inp) \ |
| 35 | MCFG_DEVICE_ADD(_tag, _dev_type, 0) \ |
| 36 | MCFG_DEVICE_INPUT_DEFAULTS(_def_inp) \ |
| 37 | device_a2bus_card_interface::static_set_a2bus_tag(*device, _nbtag, _tag); |
| 38 | |
| 39 | #define MCFG_A2BUS_BUS_REMOVE(_tag) \ |
| 40 | MCFG_DEVICE_REMOVE(_tag) |
| 41 | |
| 42 | //************************************************************************** |
| 43 | // TYPE DEFINITIONS |
| 44 | //************************************************************************** |
| 45 | |
| 46 | class a2bus_device; |
| 47 | |
| 48 | class a2bus_slot_device : public device_t, |
| 49 | public device_slot_interface |
| 50 | { |
| 51 | public: |
| 52 | // construction/destruction |
| 53 | a2bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 54 | a2bus_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); |
| 55 | |
| 56 | // device-level overrides |
| 57 | virtual void device_start(); |
| 58 | |
| 59 | // inline configuration |
| 60 | static void static_set_a2bus_slot(device_t &device, const char *tag, const char *slottag); |
| 61 | protected: |
| 62 | // configuration |
| 63 | const char *m_a2bus_tag, *m_a2bus_slottag; |
| 64 | }; |
| 65 | |
| 66 | // device type definition |
| 67 | extern const device_type A2BUS_SLOT; |
| 68 | |
| 69 | // ======================> a2bus_interface |
| 70 | |
| 71 | struct a2bus_interface |
| 72 | { |
| 73 | devcb_write_line m_out_irq_cb; |
| 74 | devcb_write_line m_out_nmi_cb; |
| 75 | }; |
| 76 | |
| 77 | class device_a2bus_card_interface; |
| 78 | // ======================> a2bus_device |
| 79 | class a2bus_device : public device_t, |
| 80 | public a2bus_interface |
| 81 | { |
| 82 | public: |
| 83 | // construction/destruction |
| 84 | a2bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 85 | a2bus_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); |
| 86 | // inline configuration |
| 87 | static void static_set_cputag(device_t &device, const char *tag); |
| 88 | |
| 89 | void add_a2bus_card(device_a2bus_card_interface *card); |
| 90 | void set_irq_line(int state); |
| 91 | void set_nmi_line(int state); |
| 92 | |
| 93 | DECLARE_WRITE_LINE_MEMBER( irq_w ); |
| 94 | DECLARE_WRITE_LINE_MEMBER( nmi_w ); |
| 95 | |
| 96 | protected: |
| 97 | // device-level overrides |
| 98 | virtual void device_start(); |
| 99 | virtual void device_reset(); |
| 100 | virtual void device_config_complete(); |
| 101 | |
| 102 | // internal state |
| 103 | device_t *m_maincpu; |
| 104 | |
| 105 | devcb_resolved_write_line m_out_irq_func; |
| 106 | devcb_resolved_write_line m_out_nmi_func; |
| 107 | |
| 108 | simple_list<device_a2bus_card_interface> m_device_list; |
| 109 | const char *m_cputag; |
| 110 | }; |
| 111 | |
| 112 | |
| 113 | // device type definition |
| 114 | extern const device_type A2BUS; |
| 115 | |
| 116 | // ======================> device_a2bus_card_interface |
| 117 | |
| 118 | // class representing interface-specific live a2bus card |
| 119 | class device_a2bus_card_interface : public device_slot_card_interface |
| 120 | { |
| 121 | friend class a2bus_device; |
| 122 | public: |
| 123 | // construction/destruction |
| 124 | device_a2bus_card_interface(const machine_config &mconfig, device_t &device); |
| 125 | virtual ~device_a2bus_card_interface(); |
| 126 | |
| 127 | device_a2bus_card_interface *next() const { return m_next; } |
| 128 | |
| 129 | void set_a2bus_device(); |
| 130 | |
| 131 | UINT32 get_slotromspace() { return 0xc000 | (m_slot<<8); } // return Cn00 address for this slot |
| 132 | UINT32 get_slotiospace() { return 0xc080 + (m_slot<<4); } // return C0n0 address for this slot |
| 133 | |
| 134 | void raise_slot_irq() { m_a2bus->set_irq_line(ASSERT_LINE); } |
| 135 | void lower_slot_irq() { m_a2bus->set_irq_line(CLEAR_LINE); } |
| 136 | void raise_slot_nmi() { m_a2bus->set_nmi_line(ASSERT_LINE); } |
| 137 | void lower_slot_nmi() { m_a2bus->set_nmi_line(CLEAR_LINE); } |
| 138 | |
| 139 | // inline configuration |
| 140 | static void static_set_a2bus_tag(device_t &device, const char *tag, const char *slottag); |
| 141 | public: |
| 142 | a2bus_device *m_a2bus; |
| 143 | const char *m_a2bus_tag, *m_a2bus_slottag; |
| 144 | int m_slot; |
| 145 | device_a2bus_card_interface *m_next; |
| 146 | }; |
| 147 | |
| 148 | #endif /* __A2BUS_H__ */ |