diff options
author | 2015-09-13 08:41:44 +0200 | |
---|---|---|
committer | 2015-09-13 08:41:44 +0200 | |
commit | f88cefad27a1737c76e09d99c9fb43e173506081 (patch) | |
tree | 2d8167d03579c46e226471747eb4407bd00ed6fa /src/devices/bus/a1bus | |
parent | e92ac9e0fa8e99869894bea00589bbb526be30aa (diff) |
Move all devices into separate part of src tree (nw)
Diffstat (limited to 'src/devices/bus/a1bus')
-rw-r--r-- | src/devices/bus/a1bus/a1bus.c | 204 | ||||
-rw-r--r-- | src/devices/bus/a1bus/a1bus.h | 145 | ||||
-rw-r--r-- | src/devices/bus/a1bus/a1cassette.c | 201 | ||||
-rw-r--r-- | src/devices/bus/a1bus/a1cassette.h | 53 | ||||
-rw-r--r-- | src/devices/bus/a1bus/a1cffa.c | 156 | ||||
-rw-r--r-- | src/devices/bus/a1bus/a1cffa.h | 53 |
6 files changed, 812 insertions, 0 deletions
diff --git a/src/devices/bus/a1bus/a1bus.c b/src/devices/bus/a1bus/a1bus.c new file mode 100644 index 00000000000..7012d11a81b --- /dev/null +++ b/src/devices/bus/a1bus/a1bus.c @@ -0,0 +1,204 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/*************************************************************************** + + a1bus.c - Apple I slot bus and card emulation + +***************************************************************************/ + +#include "emu.h" +#include "emuopts.h" +#include "a1bus.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type A1BUS_SLOT = &device_creator<a1bus_slot_device>; + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// a1bus_slot_device - constructor +//------------------------------------------------- +a1bus_slot_device::a1bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, A1BUS_SLOT, "Apple I Slot", tag, owner, clock, "a1bus_slot", __FILE__), + device_slot_interface(mconfig, *this) +{ +} + +a1bus_slot_device::a1bus_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) : + device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_slot_interface(mconfig, *this) +{ +} + +void a1bus_slot_device::static_set_a1bus_slot(device_t &device, const char *tag, const char *slottag) +{ + a1bus_slot_device &a1bus_card = dynamic_cast<a1bus_slot_device &>(device); + a1bus_card.m_a1bus_tag = tag; + a1bus_card.m_a1bus_slottag = slottag; +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void a1bus_slot_device::device_start() +{ + device_a1bus_card_interface *dev = dynamic_cast<device_a1bus_card_interface *>(get_card_device()); + + if (dev) device_a1bus_card_interface::static_set_a1bus_tag(*dev, m_a1bus_tag, m_a1bus_slottag); +} + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type A1BUS = &device_creator<a1bus_device>; + +void a1bus_device::static_set_cputag(device_t &device, const char *tag) +{ + a1bus_device &a1bus = downcast<a1bus_device &>(device); + a1bus.m_cputag = tag; +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// a1bus_device - constructor +//------------------------------------------------- + +a1bus_device::a1bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, A1BUS, "Apple I Bus", tag, owner, clock, "a1bus", __FILE__), + m_out_irq_cb(*this), + m_out_nmi_cb(*this) +{ +} + +a1bus_device::a1bus_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) : + device_t(mconfig, type, name, tag, owner, clock, shortname, source), + m_out_irq_cb(*this), + m_out_nmi_cb(*this) +{ +} +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void a1bus_device::device_start() +{ + m_maincpu = machine().device<cpu_device>(m_cputag); + + // resolve callbacks + m_out_irq_cb.resolve_safe(); + m_out_nmi_cb.resolve_safe(); + + // clear slot + m_device = NULL; +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void a1bus_device::device_reset() +{ +} + +device_a1bus_card_interface *a1bus_device::get_a1bus_card() +{ + return m_device; +} + +void a1bus_device::add_a1bus_card(device_a1bus_card_interface *card) +{ + m_device = card; +} + +void a1bus_device::set_irq_line(int state) +{ + m_out_irq_cb(state); +} + +void a1bus_device::set_nmi_line(int state) +{ + m_out_nmi_cb(state); +} + +void a1bus_device::install_device(offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler) +{ + m_maincpu = machine().device<cpu_device>(m_cputag); + + m_maincpu->space(AS_PROGRAM).install_readwrite_handler(start, end, rhandler, whandler); +} + +void a1bus_device::install_bank(offs_t start, offs_t end, offs_t mask, offs_t mirror, const char *tag, UINT8 *data) +{ +// printf("install_bank: %s @ %x->%x mask %x mirror %x\n", tag, start, end, mask, mirror); + m_maincpu = machine().device<cpu_device>(m_cputag); + address_space &space = m_maincpu->space(AS_PROGRAM); + space.install_readwrite_bank(start, end, mask, mirror, tag ); + machine().root_device().membank(tag)->set_base(data); +} + +// interrupt request from a1bus card +WRITE_LINE_MEMBER( a1bus_device::irq_w ) { m_out_irq_cb(state); } +WRITE_LINE_MEMBER( a1bus_device::nmi_w ) { m_out_nmi_cb(state); } + +//************************************************************************** +// DEVICE CONFIG A1BUS CARD INTERFACE +//************************************************************************** + + +//************************************************************************** +// DEVICE A1BUS CARD INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_a1bus_card_interface - constructor +//------------------------------------------------- + +device_a1bus_card_interface::device_a1bus_card_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device), + m_a1bus(NULL), + m_a1bus_tag(NULL) +{ +} + + +//------------------------------------------------- +// ~device_a1bus_card_interface - destructor +//------------------------------------------------- + +device_a1bus_card_interface::~device_a1bus_card_interface() +{ +} + +void device_a1bus_card_interface::static_set_a1bus_tag(device_t &device, const char *tag, const char *slottag) +{ + device_a1bus_card_interface &a1bus_card = dynamic_cast<device_a1bus_card_interface &>(device); + a1bus_card.m_a1bus_tag = tag; + a1bus_card.m_a1bus_slottag = slottag; +} + +void device_a1bus_card_interface::set_a1bus_device() +{ + m_a1bus = dynamic_cast<a1bus_device *>(device().machine().device(m_a1bus_tag)); + m_a1bus->add_a1bus_card(this); +} + +void device_a1bus_card_interface::install_device(offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler) +{ + m_a1bus->install_device(start, end, rhandler, whandler); +} + +void device_a1bus_card_interface::install_bank(offs_t start, offs_t end, offs_t mask, offs_t mirror, char *tag, UINT8 *data) +{ + m_a1bus->install_bank(start, end, mask, mirror, tag, data); +} diff --git a/src/devices/bus/a1bus/a1bus.h b/src/devices/bus/a1bus/a1bus.h new file mode 100644 index 00000000000..ecdb440f948 --- /dev/null +++ b/src/devices/bus/a1bus/a1bus.h @@ -0,0 +1,145 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/*************************************************************************** + + a1bus.h - Apple I expansion slot and card emulation + +***************************************************************************/ + +#pragma once + +#ifndef __A1BUS_H__ +#define __A1BUS_H__ + +#include "emu.h" + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_A1BUS_CPU(_cputag) \ + a1bus_device::static_set_cputag(*device, _cputag); + +#define MCFG_A1BUS_OUT_IRQ_CB(_devcb) \ + devcb = &a1bus_device::set_out_irq_callback(*device, DEVCB_##_devcb); + +#define MCFG_A1BUS_OUT_NMI_CB(_devcb) \ + devcb = &a1bus_device::set_out_nmi_callback(*device, DEVCB_##_devcb); + +#define MCFG_A1BUS_SLOT_ADD(_nbtag, _tag, _slot_intf, _def_slot) \ + MCFG_DEVICE_ADD(_tag, A1BUS_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \ + a1bus_slot_device::static_set_a1bus_slot(*device, _nbtag, _tag); +#define MCFG_A1BUS_SLOT_REMOVE(_tag) \ + MCFG_DEVICE_REMOVE(_tag) + +#define MCFG_A1BUS_ONBOARD_ADD(_nbtag, _tag, _dev_type, _def_inp) \ + MCFG_DEVICE_ADD(_tag, _dev_type, 0) \ + MCFG_DEVICE_INPUT_DEFAULTS(_def_inp) \ + device_a1bus_card_interface::static_set_a1bus_tag(*device, _nbtag, _tag); + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class a1bus_device; + +class a1bus_slot_device : public device_t, + public device_slot_interface +{ +public: + // construction/destruction + a1bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + a1bus_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + + // device-level overrides + virtual void device_start(); + + // inline configuration + static void static_set_a1bus_slot(device_t &device, const char *tag, const char *slottag); +protected: + // configuration + const char *m_a1bus_tag, *m_a1bus_slottag; +}; + +// device type definition +extern const device_type A1BUS_SLOT; + + +class device_a1bus_card_interface; +// ======================> a1bus_device +class a1bus_device : public device_t +{ +public: + // construction/destruction + a1bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + a1bus_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + + // inline configuration + static void static_set_cputag(device_t &device, const char *tag); + template<class _Object> static devcb_base &set_out_irq_callback(device_t &device, _Object object) { return downcast<a1bus_device &>(device).m_out_irq_cb.set_callback(object); } + template<class _Object> static devcb_base &set_out_nmi_callback(device_t &device, _Object object) { return downcast<a1bus_device &>(device).m_out_nmi_cb.set_callback(object); } + + void add_a1bus_card(device_a1bus_card_interface *card); + device_a1bus_card_interface *get_a1bus_card(); + + void set_irq_line(int state); + void set_nmi_line(int state); + + void install_device(offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler); + void install_bank(offs_t start, offs_t end, offs_t mask, offs_t mirror, const char *tag, UINT8 *data); + + DECLARE_WRITE_LINE_MEMBER( irq_w ); + DECLARE_WRITE_LINE_MEMBER( nmi_w ); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // internal state + cpu_device *m_maincpu; + + devcb_write_line m_out_irq_cb; + devcb_write_line m_out_nmi_cb; + + device_a1bus_card_interface *m_device; + const char *m_cputag; +}; + + +// device type definition +extern const device_type A1BUS; + +// ======================> device_a1bus_card_interface + +// class representing interface-specific live a1bus card +class device_a1bus_card_interface : public device_slot_card_interface +{ + friend class a1bus_device; +public: + // construction/destruction + device_a1bus_card_interface(const machine_config &mconfig, device_t &device); + virtual ~device_a1bus_card_interface(); + + device_a1bus_card_interface *next() const { return m_next; } + + void set_a1bus_device(); + + void raise_slot_irq() { m_a1bus->set_irq_line(ASSERT_LINE); } + void lower_slot_irq() { m_a1bus->set_irq_line(CLEAR_LINE); } + void raise_slot_nmi() { m_a1bus->set_nmi_line(ASSERT_LINE); } + void lower_slot_nmi() { m_a1bus->set_nmi_line(CLEAR_LINE); } + + void install_device(offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler); + void install_bank(offs_t start, offs_t end, offs_t mask, offs_t mirror, char *tag, UINT8 *data); + + // inline configuration + static void static_set_a1bus_tag(device_t &device, const char *tag, const char *slottag); +public: + a1bus_device *m_a1bus; + const char *m_a1bus_tag, *m_a1bus_slottag; + device_a1bus_card_interface *m_next; +}; + +#endif /* __A1BUS_H__ */ diff --git a/src/devices/bus/a1bus/a1cassette.c b/src/devices/bus/a1bus/a1cassette.c new file mode 100644 index 00000000000..daa79b15ce5 --- /dev/null +++ b/src/devices/bus/a1bus/a1cassette.c @@ -0,0 +1,201 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/********************************************************************* + + a1cassette.c + + Apple I Cassette Interface + +*********************************************************************/ + +#include "a1cassette.h" + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +#define CASSETTE_ROM_REGION "casrom" + +const device_type A1BUS_CASSETTE = &device_creator<a1bus_cassette_device>; + +/* sound output */ + +MACHINE_CONFIG_FRAGMENT( cassette ) + MCFG_CASSETTE_ADD("cassette") + MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED) + MCFG_CASSETTE_INTERFACE("apple1_cass") +MACHINE_CONFIG_END + +ROM_START( cassette ) + /* 256-byte cassette interface ROM, in two 82s129 or mmi6301 256x4 proms at locations 3 and 4 on the cassette interface daughtercard (they are labeled "MMI 6301-IJ // 7623L // APPLE-A3" and "MMI 6301-IJ // 7623L // APPLE-A4") */ + ROM_REGION(0x100, CASSETTE_ROM_REGION, 0) + ROM_LOAD_NIB_HIGH( "apple-a3.3", 0x0000, 0x0100, CRC(6eae8f52) SHA1(71906932727ef70952ef6afe6b08708df15cd67d) ) + ROM_LOAD_NIB_LOW( "apple-a4.4", 0x0000, 0x0100, CRC(94efa977) SHA1(851f3bd6863859a1a6909179a5e5bf744b3d807e) ) +ROM_END + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor a1bus_cassette_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( cassette ); +} + +const rom_entry *a1bus_cassette_device::device_rom_region() const +{ + return ROM_NAME( cassette ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +a1bus_cassette_device::a1bus_cassette_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, A1BUS_CASSETTE, "Apple I cassette board", tag, owner, clock, "a1cass", __FILE__), + device_a1bus_card_interface(mconfig, *this), + m_cassette(*this, "cassette") +{ +} + +a1bus_cassette_device::a1bus_cassette_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) : + device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_a1bus_card_interface(mconfig, *this), + m_cassette(*this, "cassette") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void a1bus_cassette_device::device_start() +{ + set_a1bus_device(); + + m_rom = device().machine().root_device().memregion(this->subtag(CASSETTE_ROM_REGION).c_str())->base(); + + install_device(0xc000, 0xc0ff, read8_delegate(FUNC(a1bus_cassette_device::cassette_r), this), write8_delegate(FUNC(a1bus_cassette_device::cassette_w), this)); + install_bank(0xc100, 0xc1ff, 0, 0, (char *)"bank_a1cas", m_rom); + + save_item(NAME(m_cassette_output_flipflop)); +} + +void a1bus_cassette_device::device_reset() +{ + m_cassette_output_flipflop = 0; +} + +/***************************************************************************** +** Cassette interface I/O +** +** The Apple I's cassette interface was a small card that plugged +** into the expansion connector on the motherboard. (This was a +** slot-type connector, separate from the motherboard's edge +** connector, but with the same signals.) The cassette interface +** provided separate cassette input and output jacks, some very +** simple interface hardware, and 256 bytes of ROM containing the +** cassette I/O code. +** +** The interface was mostly software-controlled. The only hardware +** was an output flip-flop for generating the cassette output signal, +** a National Semiconductor LM311 voltage comparator for generating a +** digital signal from the analog cassette input, an input +** signal-level LED, and some gates to control the interface logic +** and address decoding. The cassette ROM code did most of the work +** of generating and interpreting tape signals. It also contained +** its own mini-monitor for issuing tape read and write commands. +** +** The cassette interface was assigned to the $C000-$CFFF block of +** addresses, although it did not use most of the space in that +** block. Addresses were mapped as follows: +** +** $C000-$C0FF: Cassette I/O space. +** Any access here toggles the output signal. +** $C000-$C07F: Cassette output only; input disabled. +** Mirrors $C100-$C17F on reads. +** $C080-$C0FF: Cassette input and output. +** When input low, mirrors $C180-$C1FF on reads. +** When input high, both odd and even addresses +** mirror even ROM addresses $C180-$C1FE. +** $C100-$C1FF: Cassette ROM code. +** +** Note the peculiar addressing scheme. Data was written simply +** through repeated accesses, rather than by writing to an address. +** Data was read by reading an odd input address and comparing the +** ROM byte returned to detect signal changes. +** +** The standard tape signal was a simple square wave, although this +** was often greatly distorted by the cassette recorder. A single +** tape record consisted of a 10-second 800-Hz leader, followed by a +** single short square-wave cycle used as a sync bit, followed by the +** tape data. The data was encoded using a single square-wave cycle +** for each bit; "1" bits were at 1000 Hz, "0" bits at 2000 Hz. (All +** of these frequencies are approximate and could vary due to +** differences in recorder speed.) Each byte was written starting +** from the most significant bit; bytes were written from low to high +** addresses. No error detection was provided. Multiple records +** could be placed on a single tape. +*****************************************************************************/ + +/* The cassette output signal for writing tapes is generated by a + flip-flop which is toggled to produce the output waveform. Any + access to the cassette I/O range, whether a read or a write, + toggles this flip-flop. */ +void a1bus_cassette_device::cassette_toggle_output() +{ + m_cassette_output_flipflop = !m_cassette_output_flipflop; + m_cassette->output(m_cassette_output_flipflop ? 1.0 : -1.0); +} + +READ8_MEMBER(a1bus_cassette_device::cassette_r) +{ + cassette_toggle_output(); + + if (offset <= 0x7f) + { + /* If the access is to address range $C000-$C07F, the cassette + input signal is ignored . In this case the value read + always comes from the corresponding cassette ROM location + in $C100-$C17F. */ + + return m_rom[offset]; + } + else + { + /* For accesses to address range $C080-$C0FF, the cassette + input signal is enabled. If the signal is low, the value + read comes from the corresponding cassette ROM location in + $C180-$C1FF. If the signal is high, the low bit of the + address is masked before the corresponding cassette ROM + location is accessed; e.g., a read from $C081 would return + the ROM byte at $C180. The cassette ROM routines detect + changes in the cassette input signal by repeatedly reading + from $C081 and comparing the values read. */ + + /* (Don't try putting a non-zero "noise threshhold" here, + because it can cause tape header bits on real cassette + images to be misread as data bits.) */ + if (m_cassette->input() > 0.0) + return m_rom[0xc100 + (offset & ~1)]; + else + return m_rom[0xc100 + offset]; + } +} + +WRITE8_MEMBER(a1bus_cassette_device::cassette_w) +{ + /* Writes toggle the output flip-flop in the same way that reads + do; other than that they have no effect. Any repeated accesses + to the cassette I/O address range can be used to write data to + cassette, and the cassette ROM always uses reads to do this. + However, we still have to handle writes, since they may be done + by user code. */ + + cassette_toggle_output(); +} diff --git a/src/devices/bus/a1bus/a1cassette.h b/src/devices/bus/a1bus/a1cassette.h new file mode 100644 index 00000000000..e8d656c1c3a --- /dev/null +++ b/src/devices/bus/a1bus/a1cassette.h @@ -0,0 +1,53 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/********************************************************************* + + a1cassette.h + + Apple I Cassette Interface + +*********************************************************************/ + +#ifndef __A1BUS_CASSETTE__ +#define __A1BUS_CASSETTE__ + +#include "a1bus.h" +#include "imagedev/cassette.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class a1bus_cassette_device: + public device_t, + public device_a1bus_card_interface +{ +public: + // construction/destruction + a1bus_cassette_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + a1bus_cassette_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + virtual const rom_entry *device_rom_region() const; + + optional_device<cassette_image_device> m_cassette; + + DECLARE_READ8_MEMBER(cassette_r); + DECLARE_WRITE8_MEMBER(cassette_w); + +protected: + virtual void device_start(); + virtual void device_reset(); + + void cassette_toggle_output(); + +private: + UINT8 *m_rom; + int m_cassette_output_flipflop; +}; + +// device type definition +extern const device_type A1BUS_CASSETTE; + +#endif /* __A1BUS_CASSETTE__ */ diff --git a/src/devices/bus/a1bus/a1cffa.c b/src/devices/bus/a1bus/a1cffa.c new file mode 100644 index 00000000000..f67470bb5db --- /dev/null +++ b/src/devices/bus/a1bus/a1cffa.c @@ -0,0 +1,156 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/********************************************************************* + + a1cffa.c + + Rich Dreher's Compact Flash for Apple I + +*********************************************************************/ + +#include "a1cffa.h" + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +#define CFFA_ROM_REGION "cffa_rom" +#define CFFA_ATA_TAG "cffa_ata" + +const device_type A1BUS_CFFA = &device_creator<a1bus_cffa_device>; + +MACHINE_CONFIG_FRAGMENT( cffa ) + MCFG_ATA_INTERFACE_ADD(CFFA_ATA_TAG, ata_devices, "hdd", NULL, false) +MACHINE_CONFIG_END + +ROM_START( cffa ) + ROM_REGION(0x2000, CFFA_ROM_REGION, 0) + ROM_LOAD ("cffaromv1.1.bin", 0x0000, 0x1fe0, CRC(bf6b55ad) SHA1(6a290be18485a06f243a3561c4e01be5aafa4bfe) ) +ROM_END + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor a1bus_cffa_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( cffa ); +} + +const rom_entry *a1bus_cffa_device::device_rom_region() const +{ + return ROM_NAME( cffa ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +a1bus_cffa_device::a1bus_cffa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, A1BUS_CFFA, "CFFA Compact Flash for Apple I", tag, owner, clock, "cffa1", __FILE__), + device_a1bus_card_interface(mconfig, *this), + m_ata(*this, CFFA_ATA_TAG) +{ +} + +a1bus_cffa_device::a1bus_cffa_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) : + device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_a1bus_card_interface(mconfig, *this), + m_ata(*this, CFFA_ATA_TAG) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void a1bus_cffa_device::device_start() +{ + set_a1bus_device(); + + m_rom = device().machine().root_device().memregion(this->subtag(CFFA_ROM_REGION).c_str())->base(); + + install_device(0xafe0, 0xafff, read8_delegate(FUNC(a1bus_cffa_device::cffa_r), this), write8_delegate(FUNC(a1bus_cffa_device::cffa_w), this)); + install_bank(0x9000, 0xafdf, 0, 0, (char *)"bank_cffa1", m_rom); + + save_item(NAME(m_lastdata)); + save_item(NAME(m_writeprotect)); +} + +void a1bus_cffa_device::device_reset() +{ + m_writeprotect = false; + m_lastdata = 0; +} + +READ8_MEMBER(a1bus_cffa_device::cffa_r) +{ + switch (offset & 0xf) + { + case 0x0: + return m_lastdata>>8; + + case 0x3: + m_writeprotect = false; + break; + + case 0x4: + m_writeprotect = true; + break; + + case 0x8: + m_lastdata = m_ata->read_cs0(space, (offset & 0xf) - 8, 0xff); + return m_lastdata & 0x00ff; + + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + return m_ata->read_cs0(space, (offset & 0xf) - 8, 0xff); + } + + return 0xff; +} + +WRITE8_MEMBER(a1bus_cffa_device::cffa_w) +{ + switch (offset & 0xf) + { + case 0x0: + m_lastdata &= 0x00ff; + m_lastdata |= data<<8; + break; + + case 0x3: + m_writeprotect = false; + break; + + case 0x4: + m_writeprotect = true; + break; + + + case 0x8: + m_ata->write_cs0(space, (offset & 0xf) - 8, data, 0xff); + break; + + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + m_ata->write_cs0(space, (offset & 0xf) - 8, data, 0xff); + break; + + } +} diff --git a/src/devices/bus/a1bus/a1cffa.h b/src/devices/bus/a1bus/a1cffa.h new file mode 100644 index 00000000000..a1dc4258cbc --- /dev/null +++ b/src/devices/bus/a1bus/a1cffa.h @@ -0,0 +1,53 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/********************************************************************* + + a1cffa.h + + Rich Dreher's Compact Flash for Apple I + +*********************************************************************/ + +#ifndef __A1BUS_CFFA__ +#define __A1BUS_CFFA__ + +#include "emu.h" +#include "a1bus.h" +#include "machine/ataintf.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class a1bus_cffa_device: + public device_t, + public device_a1bus_card_interface +{ +public: + // construction/destruction + a1bus_cffa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + a1bus_cffa_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; + virtual const rom_entry *device_rom_region() const; + + required_device<ata_interface_device> m_ata; + + DECLARE_READ8_MEMBER(cffa_r); + DECLARE_WRITE8_MEMBER(cffa_w); + +protected: + virtual void device_start(); + virtual void device_reset(); + +private: + UINT8 *m_rom; + UINT16 m_lastdata; + bool m_writeprotect; +}; + +// device type definition +extern const device_type A1BUS_CFFA; + +#endif /* __A1BUS_CFFA__ */ |