summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/machine.lua11
-rw-r--r--src/devices/bus/a2bus/a2sd.cpp68
-rw-r--r--src/devices/bus/a2bus/a2sd.h49
-rw-r--r--src/devices/bus/bbc/cart/mastersd.cpp68
-rw-r--r--src/devices/bus/bbc/cart/mastersd.h67
-rw-r--r--src/devices/bus/bbc/userport/sdcard.cpp65
-rw-r--r--src/devices/bus/bbc/userport/sdcard.h58
-rw-r--r--src/devices/bus/electron/cart/elksdp1.cpp48
-rw-r--r--src/devices/bus/electron/cart/elksdp1.h46
-rw-r--r--src/devices/bus/electron/elksd128.cpp58
-rw-r--r--src/devices/bus/electron/elksd128.h58
-rw-r--r--src/devices/bus/electron/elksd64.cpp44
-rw-r--r--src/devices/bus/electron/elksd64.h44
-rw-r--r--src/devices/bus/spectrum/neogs.cpp3
-rw-r--r--src/devices/bus/vtech/memexp/sdloader.cpp66
-rw-r--r--src/devices/bus/vtech/memexp/sdloader.h57
-rw-r--r--src/devices/cpu/mcs40/mcs40.cpp30
-rw-r--r--src/devices/cpu/mcs40/mcs40.h2
-rw-r--r--src/devices/machine/spi_psram.cpp306
-rw-r--r--src/devices/machine/spi_psram.h57
-rw-r--r--src/devices/machine/spi_sdcard.cpp302
-rw-r--r--src/devices/machine/spi_sdcard.h73
-rw-r--r--src/mame/sinclair/chloe.cpp3
-rw-r--r--src/mame/sinclair/pentevo.cpp3
-rw-r--r--src/mame/sinclair/specnext.cpp3
-rw-r--r--src/mame/sinclair/tsconf.cpp1
-rw-r--r--src/mame/sinclair/tsconf.h2
-rw-r--r--src/mame/tvgames/gpm4530a_lexibook_jg7420.cpp3
28 files changed, 1093 insertions, 502 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua
index dd42c45d984..d462d65ee8f 100644
--- a/scripts/src/machine.lua
+++ b/scripts/src/machine.lua
@@ -4573,6 +4573,17 @@ end
---------------------------------------------------
--
+--@src/devices/machine/spi_psram.h,MACHINES["SPIPSRAM"] = true
+---------------------------------------------------
+if (MACHINES["SPIPSRAM"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/machine/spi_psram.cpp",
+ MAME_DIR .. "src/devices/machine/spi_psram.h",
+ }
+end
+
+---------------------------------------------------
+--
--@src/devices/machine/spi_sdcard.h,MACHINES["SPISDCARD"] = true
---------------------------------------------------
if (MACHINES["SPISDCARD"]~=null) then
diff --git a/src/devices/bus/a2bus/a2sd.cpp b/src/devices/bus/a2bus/a2sd.cpp
index e415ece84bc..14e6ad88c14 100644
--- a/src/devices/bus/a2bus/a2sd.cpp
+++ b/src/devices/bus/a2bus/a2sd.cpp
@@ -22,13 +22,18 @@
#include "emu.h"
#include "a2sd.h"
+#include "machine/at28c64b.h"
+#include "machine/spi_sdcard.h"
+
#define LOG_SPI (1U << 1)
-//#define VERBOSE (LOG_COMMAND)
+//#define VERBOSE (LOG_GENERAL)
#define LOG_OUTPUT_FUNC osd_printf_info
#include "logmacro.h"
+namespace {
+
/***************************************************************************
PARAMETERS
***************************************************************************/
@@ -41,17 +46,56 @@ static constexpr u8 C0N1_TC = 0x80; // SPI transfer complete
static constexpr u8 C0N3_CD = 0x40; // card detect
static constexpr u8 C0N3_BIT_SS = 7;
-//**************************************************************************
-// GLOBAL VARIABLES
-//**************************************************************************
-
-DEFINE_DEVICE_TYPE(A2BUS_A2SD, a2bus_a2sd_device, "a2sd", "Apple II SD Card")
-
ROM_START( a2sd )
ROM_REGION(0x2000, "flash", ROMREGION_ERASE00)
ROM_LOAD( "appleiisd.bin", 0x000000, 0x000800, CRC(e82eea8a) SHA1(7e0acef01e622eeed6f8e87893d07c701bbef016) )
ROM_END
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class a2bus_a2sd_device:
+ public device_t,
+ public device_a2bus_card_interface
+{
+public:
+ // construction/destruction
+ a2bus_a2sd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ a2bus_a2sd_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+ virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
+
+ // overrides of standard a2bus slot functions
+ 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(uint16_t offset) override;
+ virtual void write_c800(uint16_t offset, u8 data) override;
+
+ // SPI 4-wire interface
+ void spi_miso_w(int state) { m_in_bit = state; }
+
+ TIMER_CALLBACK_MEMBER(shift_tick);
+
+private:
+ required_device<at28c64b_device> m_flash;
+ required_device<spi_sdcard_device> m_sdcard;
+
+ u8 m_datain, m_in_latch, m_out_latch;
+ u8 m_c0n1, m_c0n3;
+ int m_in_bit;
+
+ int m_shift_count;
+ emu_timer *m_shift_timer;
+};
+
/***************************************************************************
FUNCTION PROTOTYPES
***************************************************************************/
@@ -64,6 +108,7 @@ void a2bus_a2sd_device::device_add_mconfig(machine_config &config)
AT28C64B(config, m_flash, 0);
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
m_sdcard->spi_miso_callback().set(FUNC(a2bus_a2sd_device::spi_miso_w));
}
@@ -277,3 +322,12 @@ void a2bus_a2sd_device::write_c800(u16 offset, u8 data)
{
m_flash->write(offset + 0x100, data);
}
+
+} // anonymous namespace
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(A2BUS_A2SD, device_a2bus_card_interface, a2bus_a2sd_device, "a2sd", "Apple II SD Card")
diff --git a/src/devices/bus/a2bus/a2sd.h b/src/devices/bus/a2bus/a2sd.h
index e17c728f8ac..6f8702fa903 100644
--- a/src/devices/bus/a2bus/a2sd.h
+++ b/src/devices/bus/a2bus/a2sd.h
@@ -14,54 +14,7 @@
#pragma once
#include "a2bus.h"
-#include "machine/at28c64b.h"
-#include "machine/spi_sdcard.h"
-//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-
-class a2bus_a2sd_device:
- public device_t,
- public device_a2bus_card_interface
-{
-public:
- // construction/destruction
- a2bus_a2sd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
- a2bus_a2sd_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
- virtual void device_start() override ATTR_COLD;
- virtual void device_reset() override ATTR_COLD;
- virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
- virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
-
- // overrides of standard a2bus slot functions
- 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(uint16_t offset) override;
- virtual void write_c800(uint16_t offset, u8 data) override;
-
- // SPI 4-wire interface
- void spi_miso_w(int state) { m_in_bit = state; }
-
- TIMER_CALLBACK_MEMBER(shift_tick);
-private:
- required_device<at28c64b_device> m_flash;
- required_device<spi_sdcard_device> m_sdcard;
-
- u8 m_datain, m_in_latch, m_out_latch;
- u8 m_c0n1, m_c0n3;
- int m_in_bit;
-
- int m_shift_count;
- emu_timer *m_shift_timer;
-};
-
-// device type definition
-DECLARE_DEVICE_TYPE(A2BUS_A2SD, a2bus_a2sd_device)
+DECLARE_DEVICE_TYPE(A2BUS_A2SD, device_a2bus_card_interface)
#endif // MAME_BUS_A2BUS_A2SD_H
diff --git a/src/devices/bus/bbc/cart/mastersd.cpp b/src/devices/bus/bbc/cart/mastersd.cpp
index afeb9921785..94d5428386f 100644
--- a/src/devices/bus/bbc/cart/mastersd.cpp
+++ b/src/devices/bus/bbc/cart/mastersd.cpp
@@ -12,13 +12,64 @@
#include "emu.h"
#include "mastersd.h"
+#include "machine/spi_sdcard.h"
+
+
+namespace {
//**************************************************************************
-// DEVICE DEFINITIONS
+// TYPE DEFINITIONS
//**************************************************************************
-DEFINE_DEVICE_TYPE(BBC_MASTERSD, bbc_mastersd_device, "bbc_mastersd", "MasterSD BBC Master SD Cartridge")
-DEFINE_DEVICE_TYPE(BBC_MASTERSDR2, bbc_mastersdr2_device, "bbc_mastersdr2", "MasterSD R2 BBC Master SD Cartridge")
+// ======================> bbc_mastersd_device
+
+class bbc_mastersd_device : public device_t, public device_bbc_cart_interface
+{
+public:
+ // construction/destruction
+ bbc_mastersd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ bbc_mastersd_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ // device_t implementation
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+
+ // device_bbc_cart_interface implementation
+ virtual uint8_t read(offs_t offset, int infc, int infd, int romqa, int oe, int oe2) override;
+ virtual void write(offs_t offset, uint8_t data, int infc, int infd, int romqa, int oe, int oe2) override;
+
+ TIMER_CALLBACK_MEMBER(spi_clock);
+
+ required_device<spi_sdcard_device> m_sdcard;
+
+ emu_timer *m_spi_clock;
+ bool m_spi_clock_state;
+ bool m_spi_clock_sysclk;
+ int m_spi_clock_cycles;
+ int m_in_bit;
+ uint8_t m_in_latch;
+ uint8_t m_out_latch;
+
+ std::unique_ptr<uint8_t[]> m_ram;
+};
+
+
+// ======================> bbc_mastersdr2_device
+
+class bbc_mastersdr2_device : public bbc_mastersd_device
+{
+public:
+ // construction/destruction
+ bbc_mastersdr2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device_bbc_cart_interface implementation
+ virtual uint8_t read(offs_t offset, int infc, int infd, int romqa, int oe, int oe2) override;
+ virtual void write(offs_t offset, uint8_t data, int infc, int infd, int romqa, int oe, int oe2) override;
+};
//-------------------------------------------------
@@ -28,6 +79,7 @@ DEFINE_DEVICE_TYPE(BBC_MASTERSDR2, bbc_mastersdr2_device, "bbc_mastersdr2", "Mas
void bbc_mastersd_device::device_add_mconfig(machine_config &config)
{
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
m_sdcard->spi_miso_callback().set([this](int state) { m_in_bit = state; });
}
@@ -245,3 +297,13 @@ TIMER_CALLBACK_MEMBER(bbc_mastersd_device::spi_clock)
m_spi_clock->adjust(attotime::never);
}
}
+
+} // anonymous namespace
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(BBC_MASTERSD, device_bbc_cart_interface, bbc_mastersd_device, "bbc_mastersd", "MasterSD BBC Master SD Cartridge")
+DEFINE_DEVICE_TYPE_PRIVATE(BBC_MASTERSDR2, device_bbc_cart_interface, bbc_mastersdr2_device, "bbc_mastersdr2", "MasterSD R2 BBC Master SD Cartridge")
diff --git a/src/devices/bus/bbc/cart/mastersd.h b/src/devices/bus/bbc/cart/mastersd.h
index 51fd09b03c7..39a2a1ed7d7 100644
--- a/src/devices/bus/bbc/cart/mastersd.h
+++ b/src/devices/bus/bbc/cart/mastersd.h
@@ -9,71 +9,12 @@
#ifndef MAME_BUS_BBC_CART_MASTERSD_H
#define MAME_BUS_BBC_CART_MASTERSD_H
-#include "slot.h"
-#include "machine/spi_sdcard.h"
-
-
-//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-
-// ======================> bbc_mastersd_device
-
-class bbc_mastersd_device : public device_t, public device_bbc_cart_interface
-{
-public:
- // construction/destruction
- bbc_mastersd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
- bbc_mastersd_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
- // device-level overrides
- virtual void device_start() override ATTR_COLD;
- virtual void device_reset() override ATTR_COLD;
-
- // optional information overrides
- virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
-
- // electron_cart_interface overrides
- virtual uint8_t read(offs_t offset, int infc, int infd, int romqa, int oe, int oe2) override;
- virtual void write(offs_t offset, uint8_t data, int infc, int infd, int romqa, int oe, int oe2) override;
-
- required_device<spi_sdcard_device> m_sdcard;
-
- TIMER_CALLBACK_MEMBER(spi_clock);
-
- emu_timer *m_spi_clock;
- bool m_spi_clock_state;
- bool m_spi_clock_sysclk;
- int m_spi_clock_cycles;
- int m_in_bit;
- uint8_t m_in_latch;
- uint8_t m_out_latch;
-
- std::unique_ptr<uint8_t[]> m_ram;
-};
-
-
-// ======================> bbc_mastersdr2_device
-
-class bbc_mastersdr2_device : public bbc_mastersd_device
-{
-public:
- // construction/destruction
- bbc_mastersdr2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
- // electron_cart_interface overrides
- virtual uint8_t read(offs_t offset, int infc, int infd, int romqa, int oe, int oe2) override;
- virtual void write(offs_t offset, uint8_t data, int infc, int infd, int romqa, int oe, int oe2) override;
-};
-
+#pragma once
+#include "slot.h"
-// device type definition
-DECLARE_DEVICE_TYPE(BBC_MASTERSD, bbc_mastersd_device)
-DECLARE_DEVICE_TYPE(BBC_MASTERSDR2, bbc_mastersdr2_device)
+DECLARE_DEVICE_TYPE(BBC_MASTERSD, device_bbc_cart_interface)
+DECLARE_DEVICE_TYPE(BBC_MASTERSDR2, device_bbc_cart_interface)
#endif // MAME_BUS_BBC_CART_MASTERSD_H
diff --git a/src/devices/bus/bbc/userport/sdcard.cpp b/src/devices/bus/bbc/userport/sdcard.cpp
index ccd5337d840..36f0bf2c1ac 100644
--- a/src/devices/bus/bbc/userport/sdcard.cpp
+++ b/src/devices/bus/bbc/userport/sdcard.cpp
@@ -43,12 +43,59 @@
#include "emu.h"
#include "sdcard.h"
+#include "machine/spi_sdcard.h"
+
+
+namespace {
+
//**************************************************************************
-// DEVICE DEFINITIONS
+// TYPE DEFINITIONS
//**************************************************************************
-DEFINE_DEVICE_TYPE(BBC_SDCARD, bbc_sdcard_device, "bbc_sdcard", "BBC Micro SD Card")
-DEFINE_DEVICE_TYPE(BBC_SDCARDT, bbc_sdcardt_device, "bbc_sdcardt", "BBC Micro Turbo SD Card")
+// ======================> bbc_sdcard_device
+
+class bbc_sdcard_device : public device_t, public device_bbc_userport_interface
+{
+public:
+ // construction/destruction
+ bbc_sdcard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ bbc_sdcard_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ // device_t implementation
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+
+ // device_bbc_userport_interface implementation
+ virtual void pb_w(uint8_t data) override;
+ virtual void write_cb1(int state) override;
+
+ required_device<spi_sdcard_device> m_sdcard;
+};
+
+
+// ======================> bbc_sdcardt_device
+
+class bbc_sdcardt_device : public bbc_sdcard_device
+{
+public:
+ // construction/destruction
+ bbc_sdcardt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device_t implementation
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+
+ // device_bbc_userport_interface implementation
+ virtual void pb_w(uint8_t data) override;
+ virtual void write_cb1(int state) override;
+ virtual void write_cb2(int state) override;
+
+private:
+ bool m_turbo;
+};
//-------------------------------------------------
@@ -58,12 +105,14 @@ DEFINE_DEVICE_TYPE(BBC_SDCARDT, bbc_sdcardt_device, "bbc_sdcardt", "BBC Micro Tu
void bbc_sdcard_device::device_add_mconfig(machine_config &config)
{
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
m_sdcard->spi_miso_callback().set([this](int state) { m_slot->cb2_w(state); });
}
void bbc_sdcardt_device::device_add_mconfig(machine_config &config)
{
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
m_sdcard->spi_miso_callback().set([this](int state) { if (!m_turbo) m_slot->cb2_w(state); });
}
@@ -154,3 +203,13 @@ void bbc_sdcardt_device::pb_w(uint8_t data)
m_slot->cb1_w(BIT(data, 1));
}
+
+} // anonymous namespace
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(BBC_SDCARD, device_bbc_userport_interface, bbc_sdcard_device, "bbc_sdcard", "BBC Micro SD Card")
+DEFINE_DEVICE_TYPE_PRIVATE(BBC_SDCARDT, device_bbc_userport_interface, bbc_sdcardt_device, "bbc_sdcardt", "BBC Micro Turbo SD Card")
diff --git a/src/devices/bus/bbc/userport/sdcard.h b/src/devices/bus/bbc/userport/sdcard.h
index 3eef17434a0..30cae6748ee 100644
--- a/src/devices/bus/bbc/userport/sdcard.h
+++ b/src/devices/bus/bbc/userport/sdcard.h
@@ -13,63 +13,9 @@
#pragma once
#include "userport.h"
-#include "machine/spi_sdcard.h"
-//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-
-// ======================> bbc_sdcard_device
-
-class bbc_sdcard_device : public device_t, public device_bbc_userport_interface
-{
-public:
- // construction/destruction
- bbc_sdcard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
- bbc_sdcard_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
- // device-level overrides
- virtual void device_start() override ATTR_COLD;
-
- // optional information overrides
- virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
-
- virtual void pb_w(uint8_t data) override;
- virtual void write_cb1(int state) override;
-
- required_device<spi_sdcard_device> m_sdcard;
-};
-
-
-// ======================> bbc_sdcardt_device
-
-class bbc_sdcardt_device : public bbc_sdcard_device
-{
-public:
- // construction/destruction
- bbc_sdcardt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
- // device-level overrides
- virtual void device_start() override ATTR_COLD;
-
- // optional information overrides
- virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
-
- virtual void pb_w(uint8_t data) override;
- virtual void write_cb1(int state) override;
- virtual void write_cb2(int state) override;
-
-private:
- bool m_turbo;
-};
-
-
-// device type definition
-DECLARE_DEVICE_TYPE(BBC_SDCARD, bbc_sdcard_device)
-DECLARE_DEVICE_TYPE(BBC_SDCARDT, bbc_sdcardt_device)
+DECLARE_DEVICE_TYPE(BBC_SDCARD, device_bbc_userport_interface)
+DECLARE_DEVICE_TYPE(BBC_SDCARDT, device_bbc_userport_interface)
#endif // MAME_BUS_BBC_USERPORT_SDCARD_H
diff --git a/src/devices/bus/electron/cart/elksdp1.cpp b/src/devices/bus/electron/cart/elksdp1.cpp
index c2baf7e7801..11b4d140fba 100644
--- a/src/devices/bus/electron/cart/elksdp1.cpp
+++ b/src/devices/bus/electron/cart/elksdp1.cpp
@@ -12,12 +12,46 @@
#include "emu.h"
#include "elksdp1.h"
+#include "machine/spi_sdcard.h"
+
+
+namespace {
//**************************************************************************
-// DEVICE DEFINITIONS
+// TYPE DEFINITIONS
//**************************************************************************
-DEFINE_DEVICE_TYPE(ELECTRON_ELKSDP1, electron_elksdp1_device, "electron_elksdp1", "ElkSD-Plus 1 Electron SD Cartridge")
+class electron_elksdp1_device : public device_t, public device_electron_cart_interface
+{
+public:
+ // construction/destruction
+ electron_elksdp1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device_t implementation
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+
+ // device_electron_cart_interface implementation
+ virtual uint8_t read(offs_t offset, int infc, int infd, int romqa, int oe, int oe2) override;
+ virtual void write(offs_t offset, uint8_t data, int infc, int infd, int romqa, int oe, int oe2) override;
+
+private:
+ TIMER_CALLBACK_MEMBER(spi_clock);
+
+ required_device<spi_sdcard_device> m_sdcard;
+
+ emu_timer *m_spi_clock;
+ bool m_spi_clock_state;
+ bool m_spi_clock_sysclk;
+ int m_spi_clock_cycles;
+ int m_in_bit;
+ uint8_t m_in_latch;
+ uint8_t m_out_latch;
+
+ std::unique_ptr<uint8_t[]> m_ram;
+};
//-------------------------------------------------
@@ -27,6 +61,7 @@ DEFINE_DEVICE_TYPE(ELECTRON_ELKSDP1, electron_elksdp1_device, "electron_elksdp1"
void electron_elksdp1_device::device_add_mconfig(machine_config &config)
{
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
m_sdcard->spi_miso_callback().set([this](int state) { m_in_bit = state; });
}
@@ -182,3 +217,12 @@ TIMER_CALLBACK_MEMBER(electron_elksdp1_device::spi_clock)
m_spi_clock->adjust(attotime::never);
}
}
+
+} // anonymous namespace
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(ELECTRON_ELKSDP1, device_electron_cart_interface, electron_elksdp1_device, "electron_elksdp1", "ElkSD-Plus 1 Electron SD Cartridge")
diff --git a/src/devices/bus/electron/cart/elksdp1.h b/src/devices/bus/electron/cart/elksdp1.h
index 7450af080aa..10f109bc7a2 100644
--- a/src/devices/bus/electron/cart/elksdp1.h
+++ b/src/devices/bus/electron/cart/elksdp1.h
@@ -9,51 +9,11 @@
#ifndef MAME_BUS_ELECTRON_CART_ELKSDP1_H
#define MAME_BUS_ELECTRON_CART_ELKSDP1_H
-#include "slot.h"
-#include "machine/spi_sdcard.h"
-
-
-//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-
-class electron_elksdp1_device : public device_t, public device_electron_cart_interface
-{
-public:
- // construction/destruction
- electron_elksdp1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
- // device-level overrides
- virtual void device_start() override ATTR_COLD;
- virtual void device_reset() override ATTR_COLD;
-
- // optional information overrides
- virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
-
- // electron_cart_interface overrides
- virtual uint8_t read(offs_t offset, int infc, int infd, int romqa, int oe, int oe2) override;
- virtual void write(offs_t offset, uint8_t data, int infc, int infd, int romqa, int oe, int oe2) override;
-
-private:
- required_device<spi_sdcard_device> m_sdcard;
-
- TIMER_CALLBACK_MEMBER(spi_clock);
-
- emu_timer *m_spi_clock;
- bool m_spi_clock_state;
- bool m_spi_clock_sysclk;
- int m_spi_clock_cycles;
- int m_in_bit;
- uint8_t m_in_latch;
- uint8_t m_out_latch;
-
- std::unique_ptr<uint8_t[]> m_ram;
-};
+#pragma once
+#include "slot.h"
-// device type definition
-DECLARE_DEVICE_TYPE(ELECTRON_ELKSDP1, electron_elksdp1_device)
+DECLARE_DEVICE_TYPE(ELECTRON_ELKSDP1, device_electron_cart_interface)
#endif // MAME_BUS_ELECTRON_CART_ELKSDP1_H
diff --git a/src/devices/bus/electron/elksd128.cpp b/src/devices/bus/electron/elksd128.cpp
index d57fb07dfff..932e586aed0 100644
--- a/src/devices/bus/electron/elksd128.cpp
+++ b/src/devices/bus/electron/elksd128.cpp
@@ -14,12 +14,56 @@
#include "emu.h"
#include "elksd128.h"
+#include "machine/spi_sdcard.h"
+
+
+namespace {
//**************************************************************************
-// DEVICE DEFINITIONS
+// TYPE DEFINITIONS
//**************************************************************************
-DEFINE_DEVICE_TYPE(ELECTRON_ELKSD128, electron_elksd128_device, "electron_elksd128", "ElkSD128 Electron SD Interface")
+class electron_elksd128_device:
+ public device_t,
+ public device_electron_expansion_interface
+{
+public:
+ // construction/destruction
+ electron_elksd128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device_t implementation
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+ virtual ioport_constructor device_input_ports() const override ATTR_COLD;
+ virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
+
+ // device_electron_expansion_interface implementation
+ virtual uint8_t expbus_r(offs_t offset) override;
+ virtual void expbus_w(offs_t offset, uint8_t data) override;
+
+private:
+ required_memory_region m_flash;
+ required_device<spi_sdcard_device> m_sdcard;
+ required_ioport m_joy;
+
+ uint8_t m_romsel;
+ uint8_t m_adc_channel;
+ uint8_t m_swr_lock;
+
+ TIMER_CALLBACK_MEMBER(spi_clock);
+
+ emu_timer *m_spi_clock;
+ bool m_spi_clock_state;
+ bool m_spi_clock_sysclk;
+ int m_spi_clock_cycles;
+ int m_in_bit;
+ uint8_t m_in_latch;
+ uint8_t m_out_latch;
+
+ std::unique_ptr<uint8_t[]> m_ram;
+};
static INPUT_PORTS_START( elksd128 )
@@ -58,6 +102,7 @@ ROM_END
void electron_elksd128_device::device_add_mconfig(machine_config &config)
{
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
m_sdcard->spi_miso_callback().set([this](int state) { m_in_bit = state; });
}
@@ -316,3 +361,12 @@ TIMER_CALLBACK_MEMBER(electron_elksd128_device::spi_clock)
m_spi_clock->adjust(attotime::never);
}
}
+
+} // anonymous namespace
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(ELECTRON_ELKSD128, device_electron_expansion_interface, electron_elksd128_device, "electron_elksd128", "ElkSD128 Electron SD Interface")
diff --git a/src/devices/bus/electron/elksd128.h b/src/devices/bus/electron/elksd128.h
index 2fe86ec30d2..b11b33f1cf6 100644
--- a/src/devices/bus/electron/elksd128.h
+++ b/src/devices/bus/electron/elksd128.h
@@ -6,64 +6,14 @@
**********************************************************************/
-
#ifndef MAME_BUS_ELECTRON_ELKSD128_H
#define MAME_BUS_ELECTRON_ELKSD128_H
-#include "exp.h"
-#include "machine/spi_sdcard.h"
-
-
-//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-
-class electron_elksd128_device:
- public device_t,
- public device_electron_expansion_interface
-{
-public:
- // construction/destruction
- electron_elksd128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
- // device-level overrides
- virtual void device_start() override ATTR_COLD;
- virtual void device_reset() override ATTR_COLD;
-
- // optional information overrides
- virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
- virtual ioport_constructor device_input_ports() const override ATTR_COLD;
- virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
-
- virtual uint8_t expbus_r(offs_t offset) override;
- virtual void expbus_w(offs_t offset, uint8_t data) override;
-
-private:
- required_memory_region m_flash;
- required_device<spi_sdcard_device> m_sdcard;
- required_ioport m_joy;
-
- uint8_t m_romsel;
- uint8_t m_adc_channel;
- uint8_t m_swr_lock;
-
- TIMER_CALLBACK_MEMBER(spi_clock);
-
- emu_timer *m_spi_clock;
- bool m_spi_clock_state;
- bool m_spi_clock_sysclk;
- int m_spi_clock_cycles;
- int m_in_bit;
- uint8_t m_in_latch;
- uint8_t m_out_latch;
-
- std::unique_ptr<uint8_t[]> m_ram;
-};
+#pragma once
+#include "exp.h"
-// device type definition
-DECLARE_DEVICE_TYPE(ELECTRON_ELKSD128, electron_elksd128_device)
+DECLARE_DEVICE_TYPE(ELECTRON_ELKSD128, device_electron_expansion_interface)
-#endif /* MAME_BUS_ELECTRON_ELKSD128_H */
+#endif // MAME_BUS_ELECTRON_ELKSD128_H
diff --git a/src/devices/bus/electron/elksd64.cpp b/src/devices/bus/electron/elksd64.cpp
index 033f0aceb4d..3a8a3216599 100644
--- a/src/devices/bus/electron/elksd64.cpp
+++ b/src/devices/bus/electron/elksd64.cpp
@@ -14,12 +14,42 @@
#include "emu.h"
#include "elksd64.h"
+#include "machine/spi_sdcard.h"
+
+
+namespace {
//**************************************************************************
-// DEVICE DEFINITIONS
+// TYPE DEFINITIONS
//**************************************************************************
-DEFINE_DEVICE_TYPE(ELECTRON_ELKSD64, electron_elksd64_device, "electron_elksd64", "ElkSD64 Electron SD Interface")
+class electron_elksd64_device:
+ public device_t,
+ public device_electron_expansion_interface
+{
+public:
+ // construction/destruction
+ electron_elksd64_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device_t implementation
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+ virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
+
+ // device_electron_expansion_interface implementation
+ virtual uint8_t expbus_r(offs_t offset) override;
+ virtual void expbus_w(offs_t offset, uint8_t data) override;
+
+private:
+ required_memory_region m_flash;
+ required_device<spi_sdcard_device> m_sdcard;
+
+ uint8_t m_romsel;
+ uint8_t m_status;
+
+ std::unique_ptr<uint8_t[]> m_ram;
+};
//-------------------------------------------------
@@ -39,6 +69,7 @@ ROM_END
void electron_elksd64_device::device_add_mconfig(machine_config &config)
{
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
m_sdcard->spi_miso_callback().set([this](int state) { m_status = state << 7; });
}
@@ -159,3 +190,12 @@ void electron_elksd64_device::expbus_w(offs_t offset, uint8_t data)
}
}
}
+
+} // anonymous namespace
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(ELECTRON_ELKSD64, device_electron_expansion_interface, electron_elksd64_device, "electron_elksd64", "ElkSD64 Electron SD Interface")
diff --git a/src/devices/bus/electron/elksd64.h b/src/devices/bus/electron/elksd64.h
index 32435b026c5..11ab9536df8 100644
--- a/src/devices/bus/electron/elksd64.h
+++ b/src/devices/bus/electron/elksd64.h
@@ -6,50 +6,14 @@
**********************************************************************/
-
#ifndef MAME_BUS_ELECTRON_ELKSD64_H
#define MAME_BUS_ELECTRON_ELKSD64_H
-#include "exp.h"
-#include "machine/spi_sdcard.h"
-
-
-//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-
-class electron_elksd64_device:
- public device_t,
- public device_electron_expansion_interface
-{
-public:
- // construction/destruction
- electron_elksd64_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
- // device-level overrides
- virtual void device_start() override ATTR_COLD;
-
- // optional information overrides
- virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
- virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
-
- virtual uint8_t expbus_r(offs_t offset) override;
- virtual void expbus_w(offs_t offset, uint8_t data) override;
-
-private:
- required_memory_region m_flash;
- required_device<spi_sdcard_device> m_sdcard;
-
- uint8_t m_romsel;
- uint8_t m_status;
-
- std::unique_ptr<uint8_t[]> m_ram;
-};
+#pragma once
+#include "exp.h"
-// device type definition
-DECLARE_DEVICE_TYPE(ELECTRON_ELKSD64, electron_elksd64_device)
+DECLARE_DEVICE_TYPE(ELECTRON_ELKSD64, device_electron_expansion_interface)
-#endif /* MAME_BUS_ELECTRON_ELKSD64_H */
+#endif // MAME_BUS_ELECTRON_ELKSD64_H
diff --git a/src/devices/bus/spectrum/neogs.cpp b/src/devices/bus/spectrum/neogs.cpp
index 2c133f48899..3a8eea7cbb0 100644
--- a/src/devices/bus/spectrum/neogs.cpp
+++ b/src/devices/bus/spectrum/neogs.cpp
@@ -106,7 +106,7 @@ protected:
memory_bank_creator m_bank_ram;
memory_view m_view;
required_device_array<dac_word_interface, 2> m_dac;
- required_device<spi_sdcard_sdhc_device> m_sdcard;
+ required_device<spi_sdcard_device> m_sdcard;
output_finder<> m_neogs_led;
private:
@@ -411,6 +411,7 @@ void neogs_device::device_add_mconfig(machine_config &config)
m_maincpu->irqack_cb().set_inputline(m_maincpu, INPUT_LINE_IRQ0, CLEAR_LINE);
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
m_sdcard->spi_miso_callback().set([this](int state) { m_spi_data_in_latch <<= 1; m_spi_data_in_latch |= state; });
SPEAKER(config, "lspeaker").front_left();
diff --git a/src/devices/bus/vtech/memexp/sdloader.cpp b/src/devices/bus/vtech/memexp/sdloader.cpp
index 5992c66cb49..18420ca459b 100644
--- a/src/devices/bus/vtech/memexp/sdloader.cpp
+++ b/src/devices/bus/vtech/memexp/sdloader.cpp
@@ -21,16 +21,68 @@
#include "emu.h"
#include "sdloader.h"
+#include "machine/spi_sdcard.h"
+
#define LOG_SPI (1U << 1)
#define VERBOSE (LOG_GENERAL)
#include "logmacro.h"
+namespace {
+
//**************************************************************************
-// DEVICE DEFINITIONS
+// TYPE DEFINITIONS
//**************************************************************************
-DEFINE_DEVICE_TYPE(VTECH_SDLOADER, vtech_sdloader_device, "vtech_sdloader", "BennVenn SD Loader")
+// ======================> vtech_sdloader_device
+
+class vtech_sdloader_device : public vtech_memexp_device
+{
+public:
+ // construction/destruction
+ vtech_sdloader_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ static constexpr feature_type unemulated_features() { return feature::DISK; }
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+
+ virtual void mem_map(address_map &map) override ATTR_COLD;
+ virtual void io_map(address_map &map) override ATTR_COLD;
+
+private:
+ required_device<spi_sdcard_device> m_sdcard;
+ required_memory_bank m_dosbank;
+ memory_view m_dosview;
+ memory_bank_creator m_expbank;
+
+ TIMER_CALLBACK_MEMBER(spi_clock);
+ void spi_miso_w(int state);
+
+ void mapper_w(uint8_t data);
+ void sdcfg_w(uint8_t data);
+ uint8_t sdio_r();
+ void sdio_w(uint8_t data);
+ void mode_w(uint8_t data);
+
+ uint8_t exp_ram_r(offs_t offset);
+ void exp_ram_w(offs_t offset, uint8_t data);
+
+ emu_timer *m_spi_clock;
+ bool m_spi_clock_state;
+ bool m_spi_clock_sysclk;
+ int m_spi_clock_cycles;
+ int m_in_bit;
+ uint8_t m_in_latch;
+ uint8_t m_out_latch;
+
+ std::unique_ptr<uint8_t[]> m_ram;
+ bool m_vz300_mode;
+};
+
//-------------------------------------------------
// mem_map - memory space address map
@@ -87,6 +139,7 @@ void vtech_sdloader_device::device_add_mconfig(machine_config &config)
vtech_memexp_device::device_add_mconfig(config);
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
m_sdcard->spi_miso_callback().set(FUNC(vtech_sdloader_device::spi_miso_w));
}
@@ -279,3 +332,12 @@ void vtech_sdloader_device::exp_ram_w(offs_t offset, uint8_t data)
if (!m_vz300_mode || (m_vz300_mode && offset >= 0xb800))
reinterpret_cast<uint8_t *>(m_expbank->base())[offset & 0x7fff] = data;
}
+
+} // anonymous namespace
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(VTECH_SDLOADER, vtech_memexp_device, vtech_sdloader_device, "vtech_sdloader", "BennVenn SD Loader")
diff --git a/src/devices/bus/vtech/memexp/sdloader.h b/src/devices/bus/vtech/memexp/sdloader.h
index 3b004d4b4f0..dd16368d568 100644
--- a/src/devices/bus/vtech/memexp/sdloader.h
+++ b/src/devices/bus/vtech/memexp/sdloader.h
@@ -11,64 +11,9 @@
#pragma once
-#include "machine/spi_sdcard.h"
#include "memexp.h"
-//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-
-// ======================> vtech_sdloader_device
-
-class vtech_sdloader_device : public vtech_memexp_device
-{
-public:
- // construction/destruction
- vtech_sdloader_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- static constexpr feature_type unemulated_features() { return feature::DISK; }
-
-protected:
- virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
- virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
- virtual void device_start() override ATTR_COLD;
- virtual void device_reset() override ATTR_COLD;
-
- virtual void mem_map(address_map &map) override ATTR_COLD;
- virtual void io_map(address_map &map) override ATTR_COLD;
-
-private:
- required_device<spi_sdcard_device> m_sdcard;
- required_memory_bank m_dosbank;
- memory_view m_dosview;
- memory_bank_creator m_expbank;
-
- TIMER_CALLBACK_MEMBER(spi_clock);
- void spi_miso_w(int state);
-
- void mapper_w(uint8_t data);
- void sdcfg_w(uint8_t data);
- uint8_t sdio_r();
- void sdio_w(uint8_t data);
- void mode_w(uint8_t data);
-
- uint8_t exp_ram_r(offs_t offset);
- void exp_ram_w(offs_t offset, uint8_t data);
-
- emu_timer *m_spi_clock;
- bool m_spi_clock_state;
- bool m_spi_clock_sysclk;
- int m_spi_clock_cycles;
- int m_in_bit;
- uint8_t m_in_latch;
- uint8_t m_out_latch;
-
- std::unique_ptr<uint8_t[]> m_ram;
- bool m_vz300_mode;
-};
-
-// device type definition
-DECLARE_DEVICE_TYPE(VTECH_SDLOADER, vtech_sdloader_device)
+DECLARE_DEVICE_TYPE(VTECH_SDLOADER, vtech_memexp_device)
#endif // MAME_BUS_VTECH_MEMEXP_SDLOADER_H
diff --git a/src/devices/cpu/mcs40/mcs40.cpp b/src/devices/cpu/mcs40/mcs40.cpp
index e46ebe6c8d4..52005f3f0d5 100644
--- a/src/devices/cpu/mcs40/mcs40.cpp
+++ b/src/devices/cpu/mcs40/mcs40.cpp
@@ -510,39 +510,39 @@ inline void mcs40_cpu_device_base::set_rc(u8 val)
inline u8 mcs40_cpu_device_base::read_memory()
{
- return m_spaces[AS_RAM_MEMORY]->read_byte((u16(m_cr & 0x7U) << 8) | m_latched_rc) & 0x0fU;
+ return m_spaces[AS_RAM_MEMORY]->read_byte((u16(m_cr & 0x7U) << 8) | m_latched_rc, 0x0fU) & 0x0fU;
}
inline void mcs40_cpu_device_base::write_memory(u8 val)
{
- m_spaces[AS_RAM_MEMORY]->write_byte((u16(m_cr & 0x7U) << 8) | m_latched_rc, val & 0x0fU);
+ m_spaces[AS_RAM_MEMORY]->write_byte((u16(m_cr & 0x7U) << 8) | m_latched_rc, val & 0x0fU, 0x0fU);
}
inline u8 mcs40_cpu_device_base::read_status()
{
u16 const addr((((u16(m_cr) << 6) | (m_latched_rc >> 2)) & 0x01fcU) | (m_opa & 0x0003U));
- return m_spaces[AS_RAM_STATUS]->read_byte(addr) & 0x0fU;
+ return m_spaces[AS_RAM_STATUS]->read_byte(addr, 0x0fU) & 0x0fU;
}
inline void mcs40_cpu_device_base::write_status(u8 val)
{
u16 const addr((((u16(m_cr) << 6) | (m_latched_rc >> 2)) & 0x01fcU) | (m_opa & 0x0003U));
- m_spaces[AS_RAM_STATUS]->write_byte(addr, val & 0x0fU);
+ m_spaces[AS_RAM_STATUS]->write_byte(addr, val & 0x0fU, 0x0fU);
}
inline u8 mcs40_cpu_device_base::read_rom_port()
{
- return m_spaces[AS_ROM_PORTS]->read_byte((u16(m_cr) << 8) | m_latched_rc) & 0x0fU;
+ return m_spaces[AS_ROM_PORTS]->read_byte((u16(m_cr) << 8) | m_latched_rc, 0x0fU) & 0x0fU;
}
inline void mcs40_cpu_device_base::write_rom_port(u8 val)
{
- m_spaces[AS_ROM_PORTS]->write_byte((u16(m_cr) << 8) | m_latched_rc, val & 0x0fU);
+ m_spaces[AS_ROM_PORTS]->write_byte((u16(m_cr) << 8) | m_latched_rc, val & 0x0fU, 0x0fU);
}
inline void mcs40_cpu_device_base::write_memory_port(u8 val)
{
- m_spaces[AS_RAM_PORTS]->write_byte(((m_cr << 2) & 0x1cU) | (m_latched_rc >> 6), val & 0x0fU);
+ m_spaces[AS_RAM_PORTS]->write_byte(((m_cr << 2) & 0x1cU) | (m_latched_rc >> 6), val & 0x0fU, 0x0fU);
}
@@ -812,6 +812,10 @@ i4004_cpu_device::i4004_cpu_device(machine_config const &mconfig, char const *ta
{
}
+i4004_cpu_device::~i4004_cpu_device()
+{
+}
+
/***********************************************************************
device_execute_interface implementation
@@ -858,10 +862,9 @@ i4004_cpu_device::cycle i4004_cpu_device::do_cycle1(u8 opr, u8 opa, pmem &progra
case 0x0:
switch (opa)
{
+ default: // in practice, the 4004 treats these as aliases for NOP
case 0x0: // NOP
return cycle::OP;
- default:
- break;
}
break;
@@ -1117,6 +1120,10 @@ i4040_cpu_device::i4040_cpu_device(machine_config const &mconfig, char const *ta
{
}
+i4040_cpu_device::~i4040_cpu_device()
+{
+}
+
/***********************************************************************
device_execute_interface implementation
@@ -1156,6 +1163,8 @@ i4040_cpu_device::cycle i4040_cpu_device::do_cycle1(u8 opr, u8 opa, pmem &progra
case 0x0:
switch (opa)
{
+ case 0x0: // NOP
+ return cycle::OP;
case 0x1: // HLT
halt_decoded();
return cycle::OP;
@@ -1182,7 +1191,8 @@ i4040_cpu_device::cycle i4040_cpu_device::do_cycle1(u8 opr, u8 opa, pmem &progra
program_op = pmem::READ;
return cycle::OP;
default:
- break;
+ logerror("MCS-40: unhandled instruction OPR=%X OPA=%X\n", opr, opa);
+ return cycle::OP;
}
break;
default:
diff --git a/src/devices/cpu/mcs40/mcs40.h b/src/devices/cpu/mcs40/mcs40.h
index 2933413a1b1..80f0d1e44d8 100644
--- a/src/devices/cpu/mcs40/mcs40.h
+++ b/src/devices/cpu/mcs40/mcs40.h
@@ -254,6 +254,7 @@ public:
template <unsigned N> auto cm_ram_cb() { return mcs40_cpu_device_base::cm_ram_cb<N>(); }
i4004_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
+ virtual ~i4004_cpu_device();
protected:
using mcs40_cpu_device_base::mcs40_cpu_device_base;
@@ -282,6 +283,7 @@ public:
using mcs40_cpu_device_base::stp_ack_cb;
i4040_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
+ virtual ~i4040_cpu_device();
protected:
// device_disasm_interface implementation
diff --git a/src/devices/machine/spi_psram.cpp b/src/devices/machine/spi_psram.cpp
new file mode 100644
index 00000000000..659ae3ad32c
--- /dev/null
+++ b/src/devices/machine/spi_psram.cpp
@@ -0,0 +1,306 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/*
+ RAM with SPI/SDI/SQI/QPI interface
+
+ _____
+ _CE 1 |* | 8 VDD
+ SO/SIO[1] 2 | | 7 SIO[3]
+ SIO[2] 3 | | 6 SCLK
+ VSS 4 |_____| 5 SI/SIO[0]
+
+ _____
+ _CE 1 |* | 14 VDD
+ SO/SIO[1] 2 | | 13 SIO[3]
+ SIO[2] 3 | | 12 SCLK
+ VSS 4 | | 11 SI/SIO[0]
+ NC 5 | | 10 VBAT
+ NC 6 | | 9 NC
+ NC 7 |_____| 8 NC
+
+ Made by various manufacturers.
+
+ Example SRAM:
+ * ISS IS62WVS1288F (128 KiB)
+ * ISS IS65WVS1288F (128 KiB, automotive)
+ * Microchip 23AA02M (256 KiB)
+ * Microchip 23AA04M (512 KiB)
+ * Microchip 23LCV02M (256 KiB, battery backup)
+ * Microchip 23LCV04M (512 KiB, battery backup)
+
+ Example PSRAM:
+ * AP Memory APS1604L-SQ (2 MiB)
+ * AP Memory APS3204L-SQ (4 MiB)
+ * AP Memory APS6404L-SQ (8 MiB)
+ * AP Memory APS12804L-SQ (16 MiB)
+ * ISS IS66WVS1M8 (1 MiB)
+ * ISS IS66WVS2M8 (2 MiB)
+ * ISS IS66WVS8M8 (8 MiB)
+ * ISS IS67WVS1M8 (1 MiB, automotive)
+ * ISS IS67WVS2M8 (2 MiB, automotive)
+ * ISS IS67WVS8M8 (8 MiB, automotive)
+ * Vilsion Tech VTI7064 (8 MiB)
+
+ Reading/writing single bytes in SPI mode is compatible across device
+ families, but additional functionality is not.
+
+ Currently only SPI reads and writes are implemented in a way that's
+ compatible with all device families for small transfers.
+
+ TODO:
+ * Implement additional functionality for each device family
+ */
+#include "emu.h"
+#include "spi_psram.h"
+
+
+DEFINE_DEVICE_TYPE(SPI_PSRAM, spi_psram_device, "spi_psram", "Generic SPI RAM")
+
+
+ALLOW_SAVE_TYPE(spi_psram_device::phase)
+
+enum class spi_psram_device::phase : u8
+{
+ IDLE,
+ COMMAND,
+ ADDRESS,
+ WAIT,
+ READ,
+ WRITE
+};
+
+
+enum spi_psram_device::command : u8
+{
+ COMMAND_READ = 0x03,
+ COMMAND_FAST_READ = 0x0b, // 8 wait cycles in SPI mode, 4 wait cycles in QPI mode
+ COMMAND_FAST_READ_QUAD = 0xeb, // 6 wait cycles, always 4-bit address and data
+
+ COMMAND_WRITE = 0x02,
+ COMMAND_WRITE_QUAD = 0x38, // always 4-bit address and data
+
+ COMMAND_QPI_ENTER = 0x35,
+ COMMAND_QPI_EXIT = 0xf5,
+
+ COMMAND_SDI_ENTER = 0x3b,
+ COMMAND_SQI_ENTER = 0x38,
+ COMMAND_SDI_SQI_RESET = 0xff,
+
+ COMMAND_RESET_ENABLE = 0x66, // must be immediately followed by 0x99
+ COMMAND_RESET = 0x99, // must be immediately preceded by 0x66
+
+ COMMAND_WRAP_BOUNDARY = 0xc0, // toggle between 1024-byte wrap and 32-byte wrap
+
+ COMMAND_MR_READ = 0x05, // read mode/status register (size depends on family)
+ COMMAND_MR_WRITE = 0x01, // write mode/status register (size depends on family)
+
+ COMMAND_READ_ID = 0x9f, // returns 64-bit info
+
+ COMMAND_DEEP_PD_ENTER = 0xb9 // enter deep power-down mode
+};
+
+
+spi_psram_device::spi_psram_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, SPI_PSRAM, tag, owner, clock),
+ m_sio_cb(*this),
+ m_ram(),
+ m_size(0)
+{
+}
+
+spi_psram_device::~spi_psram_device()
+{
+}
+
+
+void spi_psram_device::ce_w(int state)
+{
+ if (state)
+ {
+ m_sio_cb(0, 0xf, 0x0);
+ m_phase = phase::IDLE;
+ }
+ else if (m_ce)
+ {
+ m_buffer = 0;
+ m_data_width = m_cmd_width;
+ m_bits = 8;
+ m_phase = phase::COMMAND;
+ }
+ m_ce = state ? 1 : 0;
+}
+
+void spi_psram_device::sclk_w(int state)
+{
+ switch (m_phase)
+ {
+ case phase::COMMAND:
+ case phase::ADDRESS:
+ case phase::WRITE:
+ if (state && !m_sclk)
+ {
+ m_buffer = (m_buffer << m_cmd_width) | (m_sio & util::make_bitmask<u8>(m_cmd_width));
+ m_bits -= m_data_width;
+ if (!m_bits)
+ {
+ if (phase::COMMAND == m_phase)
+ {
+ m_cmd = u8(m_buffer);
+ start_command();
+ }
+ else if (phase::ADDRESS == m_phase)
+ {
+ m_addr = m_buffer & (m_size - 1);
+ address_complete();
+ }
+ else
+ {
+ m_ram[m_addr] = u8(m_buffer);
+ m_buffer = 0;
+ next_address();
+ }
+ }
+ }
+ break;
+
+ case phase::READ:
+ if (!state && m_sclk)
+ {
+ if (1 == m_data_width)
+ {
+ m_sio_cb(0, BIT(m_buffer, 7) ? 0xf : 0xd, 0x2);
+ }
+ else
+ {
+ u8 const mask = make_bitmask<u8>(m_data_width);
+ u8 const sio = ((m_buffer >> (8 - m_data_width)) & mask) | (0x0f ^ mask);
+ m_sio_cb(0, sio, mask);
+ }
+ m_buffer = (m_buffer << m_data_width) & 0xff;
+ m_bits -= m_data_width;
+ if (!m_bits)
+ {
+ next_address();
+ m_buffer = m_ram[m_addr];
+ m_bits = 8;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ m_sclk = state ? 1 : 0;
+}
+
+void spi_psram_device::sio_w(offs_t offset, u8 data, u8 mem_mask)
+{
+ m_sio = data & 0xf;
+}
+
+
+void spi_psram_device::device_validity_check(validity_checker &valid) const
+{
+ if (!m_size || (m_size & (m_size - 1)) || (m_size > 0x0100'0000))
+ osd_printf_error("Unsupported size %u (must be a power of 2 not larger than 16M)\n", m_size);
+}
+
+void spi_psram_device::device_resolve_objects()
+{
+ m_wrap_mask = util::make_bitmask<u32>(10);
+ m_addr = 0;
+ m_buffer = 0;
+ m_cmd_width = 1;
+ m_data_width = 1;
+ m_bits = 0;
+
+ m_ce = 1;
+ m_sclk = 0;
+ m_sio = 0xf;
+ m_phase = phase::IDLE;
+ m_cmd = 0;
+}
+
+void spi_psram_device::device_start()
+{
+ if (!m_size || (m_size & (m_size - 1)) || (m_size > 0x0100'0000))
+ osd_printf_error("%s: Unsupported size %u (must be a power of 2 not larger than 16M)\n", tag(), m_size);
+
+ m_ram = make_unique_clear<u8 []>(m_size);
+
+ save_pointer(NAME(m_ram), m_size);
+ save_item(NAME(m_wrap_mask));
+ save_item(NAME(m_addr));
+ save_item(NAME(m_buffer));
+ save_item(NAME(m_cmd_width));
+ save_item(NAME(m_data_width));
+ save_item(NAME(m_bits));
+ save_item(NAME(m_ce));
+ save_item(NAME(m_sclk));
+ save_item(NAME(m_sio));
+ save_item(NAME(m_phase));
+ save_item(NAME(m_cmd));
+}
+
+
+void spi_psram_device::start_command()
+{
+ switch (m_cmd)
+ {
+ case COMMAND_READ:
+ // FIXME: AP Memory devices don't support this command in QPI mode
+ m_buffer = 0;
+ m_data_width = m_cmd_width;
+ m_bits = 24;
+ m_phase = phase::ADDRESS;
+ break;
+
+ case COMMAND_WRITE:
+ m_buffer = 0;
+ m_data_width = m_cmd_width;
+ m_bits = 24;
+ m_phase = phase::ADDRESS;
+ break;
+
+ default:
+ logerror("unimplemented command 0x%02x\n", m_cmd);
+ m_phase = phase::IDLE;
+ }
+}
+
+void spi_psram_device::address_complete()
+{
+ switch (m_cmd)
+ {
+ case COMMAND_READ:
+ // FIXME: wait cycles depend on mode and device family
+ m_buffer = m_ram[m_addr];
+ m_data_width = m_cmd_width;
+ m_bits = 8;
+ m_phase = phase::READ;
+ break;
+
+ case COMMAND_WRITE:
+ m_buffer = 0;
+ m_data_width = m_cmd_width;
+ m_bits = 8;
+ m_phase = phase::WRITE;
+ break;
+
+ default:
+ throw false; // if we get here, there's a bug in the code
+ }
+}
+
+inline void spi_psram_device::next_address()
+{
+ if (m_wrap_mask)
+ {
+ m_addr = (m_addr & ~m_wrap_mask) | ((m_addr + 1) & m_wrap_mask);
+ m_bits = 8;
+ }
+ else
+ {
+ m_phase = phase::IDLE;
+ }
+}
diff --git a/src/devices/machine/spi_psram.h b/src/devices/machine/spi_psram.h
new file mode 100644
index 00000000000..d2bc5923763
--- /dev/null
+++ b/src/devices/machine/spi_psram.h
@@ -0,0 +1,57 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+// RAM with SPI/SDI/SQI/QPI interface
+#ifndef MAME_MACHINE_SPI_PSRAM_H
+#define MAME_MACHINE_SPI_PSRAM_H
+
+#pragma once
+
+#include <memory>
+
+
+class spi_psram_device : public device_t
+{
+public:
+ spi_psram_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0U);
+ virtual ~spi_psram_device();
+
+ void set_size(u32 size) { m_size = size; }
+ auto sio_cb() { return m_sio_cb.bind(); }
+
+ void ce_w(int state);
+ void sclk_w(int state);
+ void sio_w(offs_t offset, u8 data, u8 mem_mask);
+ void si_w(int state) { sio_w(0, state ? 0xf : 0xe, 0x1); }
+
+protected:
+ virtual void device_validity_check(validity_checker &valid) const override ATTR_COLD;
+ virtual void device_resolve_objects() override ATTR_COLD;
+ virtual void device_start() override ATTR_COLD;
+
+ void start_command();
+ void address_complete();
+ void next_address();
+
+private:
+ enum class phase : u8;
+ enum command : u8;
+
+ devcb_write8 m_sio_cb;
+
+ std::unique_ptr<u8 []> m_ram;
+ u32 m_size;
+
+ u32 m_wrap_mask, m_addr;
+ u32 m_buffer;
+ u8 m_cmd_width, m_data_width;
+ u8 m_bits;
+
+ u8 m_ce, m_sclk, m_sio;
+ phase m_phase;
+ u8 m_cmd;
+};
+
+
+DECLARE_DEVICE_TYPE(SPI_PSRAM, spi_psram_device)
+
+#endif // MAME_MACHINE_SPI_PSRAM_H
diff --git a/src/devices/machine/spi_sdcard.cpp b/src/devices/machine/spi_sdcard.cpp
index 9aafcfe5b98..2e89c49aca6 100644
--- a/src/devices/machine/spi_sdcard.cpp
+++ b/src/devices/machine/spi_sdcard.cpp
@@ -31,6 +31,8 @@
#include "multibyte.h"
+#include <algorithm>
+
#define LOG_COMMAND (1U << 1)
#define LOG_SPI (1U << 2)
@@ -39,66 +41,275 @@
#include "logmacro.h"
-static constexpr u8 DATA_RESPONSE_OK = 0x05;
-static constexpr u8 DATA_RESPONSE_IO_ERROR = 0x0d;
+namespace {
+
+constexpr u8 DATA_RESPONSE_OK = 0x05;
+constexpr u8 DATA_RESPONSE_IO_ERROR = 0x0d;
+
+enum {
+ CSD_STRUCTURE_V10 = 0x0,
+ CSD_STRUCTURE_V20 = 0x1,
+
+ TAAC_UNIT_1NS = 0x00,
+ TAAC_UNIT_10NS = 0x01,
+ TAAC_UNIT_100NS = 0x02,
+ TAAC_UNIT_1US = 0x03,
+ TAAC_UNIT_10US = 0x04,
+ TAAC_UNIT_100US = 0x05,
+ TAAC_UNIT_1MS = 0x06,
+ TAAC_UNIT_10MS = 0x07,
+
+ TAAC_VALUE_1_0 = 0x08,
+ TAAC_VALUE_1_2 = 0x10,
+ TAAC_VALUE_1_3 = 0x18,
+ TAAC_VALUE_1_5 = 0x20,
+ TAAC_VALUE_2_0 = 0x28,
+ TAAC_VALUE_2_5 = 0x30,
+ TAAC_VALUE_3_0 = 0x38,
+ TAAC_VALUE_3_5 = 0x40,
+ TAAC_VALUE_4_0 = 0x48,
+ TAAC_VALUE_4_5 = 0x50,
+ TAAC_VALUE_5_0 = 0x58,
+ TAAC_VALUE_5_5 = 0x60,
+ TAAC_VALUE_6_0 = 0x68,
+ TAAC_VALUE_7_0 = 0x70,
+ TAAC_VALUE_8_0 = 0x78,
+
+ TRAN_SPEED_UNIT_100K = 0x00,
+ TRAN_SPEED_UNIT_1M = 0x01,
+ TRAN_SPEED_UNIT_10M = 0x02,
+ TRAN_SPEED_UNIT_100M = 0x03,
+
+ TRAN_SPEED_VALUE_1_0 = 0x08,
+ TRAN_SPEED_VALUE_1_2 = 0x10,
+ TRAN_SPEED_VALUE_1_3 = 0x18,
+ TRAN_SPEED_VALUE_1_5 = 0x20,
+ TRAN_SPEED_VALUE_2_0 = 0x28,
+ TRAN_SPEED_VALUE_2_5 = 0x30,
+ TRAN_SPEED_VALUE_3_0 = 0x38,
+ TRAN_SPEED_VALUE_3_5 = 0x40,
+ TRAN_SPEED_VALUE_4_0 = 0x48,
+ TRAN_SPEED_VALUE_4_5 = 0x50,
+ TRAN_SPEED_VALUE_5_0 = 0x58,
+ TRAN_SPEED_VALUE_5_5 = 0x60,
+ TRAN_SPEED_VALUE_6_0 = 0x68,
+ TRAN_SPEED_VALUE_7_0 = 0x70,
+ TRAN_SPEED_VALUE_8_0 = 0x78,
+
+ VDD_CURR_MIN_0_5MA = 0x00,
+ VDD_CURR_MIN_1MA = 0x01,
+ VDD_CURR_MIN_5MA = 0x02,
+ VDD_CURR_MIN_10MA = 0x03,
+ VDD_CURR_MIN_25MA = 0x04,
+ VDD_CURR_MIN_35MA = 0x05,
+ VDD_CURR_MIN_60MA = 0x06,
+ VDD_CURR_MIN_100MA = 0x07,
+
+ VDD_CURR_MAX_1MA = 0x00,
+ VDD_CURR_MAX_5MA = 0x01,
+ VDD_CURR_MAX_10MA = 0x02,
+ VDD_CURR_MAX_25MA = 0x03,
+ VDD_CURR_MAX_35MA = 0x04,
+ VDD_CURR_MAX_45MA = 0x05,
+ VDD_CURR_MAX_80MA = 0x06,
+ VDD_CURR_MAX_200MA = 0x07
+};
+
+} // anonymous namespace
+
+enum spi_sdcard_device::sd_state : u8
+{
+ //REF Table 4-1:Overview of Card States vs. Operation Mode
+ SD_STATE_IDLE = 0,
+ SD_STATE_READY,
+ SD_STATE_IDENT,
+ SD_STATE_STBY,
+ SD_STATE_TRAN,
+ SD_STATE_DATA,
+ SD_STATE_DATA_MULTI, // synthetical state for this implementation
+ SD_STATE_RCV,
+ SD_STATE_PRG,
+ SD_STATE_DIS,
+ SD_STATE_INA,
+
+ //FIXME Existing states which must be revisited
+ SD_STATE_WRITE_WAITFE,
+ SD_STATE_WRITE_DATA
+};
+
+ALLOW_SAVE_TYPE(spi_sdcard_device::sd_state);
-DEFINE_DEVICE_TYPE(SPI_SDCARD, spi_sdcard_sdhc_device, "spi_sdhccard", "SDHC Card (SPI Interface)")
-DEFINE_DEVICE_TYPE(SPI_SDCARDV2, spi_sdcard_sdv2_device, "spi_sdv2card", "SDV2 Card (SPI Interface)")
+
+DEFINE_DEVICE_TYPE(SPI_SDCARD, spi_sdcard_device, "spi_sdcard", "SD Card (SPI interface)")
+
+spi_sdcard_device::spi_sdcard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ spi_sdcard_device(mconfig, SPI_SDCARD, tag, owner, clock)
+{
+}
spi_sdcard_device::spi_sdcard_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, type, tag, owner, clock),
write_miso(*this),
m_image(*this, "image"),
+ m_preferred_type(SD_TYPE_V2),
+ m_ignore_stop_bit(false),
+ m_blksize(512),
+ m_type(SD_TYPE_V2),
m_state(SD_STATE_IDLE),
m_ss(0), m_in_bit(0), m_clk_state(0),
m_in_latch(0), m_out_latch(0xff), m_cur_bit(0),
- m_out_count(0), m_out_ptr(0), m_write_ptr(0), m_blksize(512), m_blknext(0),
+ m_out_count(0), m_out_ptr(0), m_write_ptr(0), m_blknext(0),
m_bACMD(false)
{
+ std::fill(std::begin(m_csd), std::end(m_csd), 0);
}
-spi_sdcard_sdv2_device::spi_sdcard_sdv2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- spi_sdcard_device(mconfig, SPI_SDCARDV2, tag, owner, clock)
-{
- m_type = SD_TYPE_V2;
-}
-
-spi_sdcard_sdhc_device::spi_sdcard_sdhc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- spi_sdcard_device(mconfig, SPI_SDCARD, tag, owner, clock)
+spi_sdcard_device::~spi_sdcard_device()
{
- m_type = SD_TYPE_HC;
}
-ALLOW_SAVE_TYPE(spi_sdcard_device::sd_state);
-ALLOW_SAVE_TYPE(spi_sdcard_device::sd_type);
-
void spi_sdcard_device::device_start()
{
save_item(NAME(m_state));
- save_item(NAME(m_in_latch));
- save_item(NAME(m_out_latch));
- save_item(NAME(m_out_ptr));
- save_item(NAME(m_out_count));
+ save_item(NAME(m_data));
+ save_item(NAME(m_cmd));
save_item(NAME(m_ss));
save_item(NAME(m_in_bit));
save_item(NAME(m_clk_state));
+ save_item(NAME(m_in_latch));
+ save_item(NAME(m_out_latch));
save_item(NAME(m_cur_bit));
+ save_item(NAME(m_out_count));
+ save_item(NAME(m_out_ptr));
save_item(NAME(m_write_ptr));
- save_item(NAME(m_blksize));
save_item(NAME(m_blknext));
- save_item(NAME(m_type));
- save_item(NAME(m_cmd));
- save_item(NAME(m_data));
save_item(NAME(m_bACMD));
}
-void spi_sdcard_device::device_reset()
+std::error_condition spi_sdcard_device::image_loaded(device_image_interface &image)
+{
+ // need block size and total blocks to create CSD
+ auto const info = m_image->get_info();
+ uint64_t const total_blocks = uint64_t(info.cylinders) * info.heads * info.sectors;
+ if (!total_blocks)
+ {
+ osd_printf_error("%s: SD card cannot mount a zero-block image\n", tag());
+ return image_error::INVALIDIMAGE;
+ }
+
+ // ensure block size can be expressed in the CSD
+ if ((info.sectorbytes & (info.sectorbytes - 1)) || !info.sectorbytes || (512 > info.sectorbytes) || (2048 < info.sectorbytes))
+ {
+ osd_printf_error("%s: SD card cannot use sector size %u (must be a power of 2 from 512 to 2048)\n", tag());
+ return image_error::INVALIDIMAGE;
+ }
+ u8 block_size_exp = 0;
+ for (auto i = info.sectorbytes; !BIT(i, 0); i >>= 1)
+ ++block_size_exp;
+
+ // see how we can express the total block count
+ uint64_t total_mant = total_blocks;
+ uint8_t total_exp = 0;
+ while (!BIT(total_mant, 0))
+ {
+ total_mant >>= 1;
+ ++total_exp;
+ }
+ bool const sd_ok = (2 <= total_exp) && ((1 << 12) >= (total_mant << ((9 < total_exp) ? (total_exp - 9) : 0)));
+ bool const sdhc_ok = (512 == info.sectorbytes) && (10 <= total_exp) && ((uint32_t(1) << 16) >= (total_mant << (total_exp - 10)));
+ if (!sd_ok && !sdhc_ok)
+ {
+ osd_printf_error("%s: image size %u blocks of %u bytes is not supported by SD or SDHC\n", tag(), total_blocks, info.sectorbytes);
+ return image_error::INVALIDIMAGE;
+ }
+
+ m_blksize = info.sectorbytes;
+
+ // set up common CSD fields
+ m_csd[0] = 0x00; // 127: CSD_STRUCTURE:2 (00b) 0:6
+ m_csd[1] = 0x00; // 119: TAAC:8
+ m_csd[2] = 0x00; // 111: NSAC:8
+ m_csd[3] = TRAN_SPEED_UNIT_10M | TRAN_SPEED_VALUE_2_5; // 103: TRAN_SPEED:8 (32h for 25MHz or 5Ah for 50MHz)
+ m_csd[4] = 0x5b; // 95: CCC:12 (01x110110101b)
+ m_csd[5] = 0x50; // .. READ_BL_LN:4
+ m_csd[5] |= block_size_exp;
+ m_csd[6] = 0x80; // 79: READ_BL_PARTIAL:1 WRITE_BLK_MISALIGN:1 READ_BLK_MISALIGN:1 DSR_IMP:1 0:2 C_SIZE:12
+ m_csd[7] = 0x00; // ..
+ m_csd[8] = 0x00; // .. VDD_R_CURR_MIN:3 VDD_R_CURR_MAX:3
+ m_csd[9] = 0x00; // 55: VDD_W_CURR_MIN:3 VDD_W_CURR_MAX:3 C_SIZE_MUL:3
+ m_csd[10] = 0x3f; // .. ERASE_BLK_EN:1 SECTOR_SIZE:7
+ m_csd[11] = 0x80; // .. WP_GRP_SIZE:7
+ m_csd[12] = 0x04; // 31: WP_GRP_ENABLE:1 0:2 R2W_FACTOR:3 WRITE_BL_LEN:4
+ m_csd[12] |= BIT(block_size_exp, 2, 2);
+ m_csd[13] = 0x00; // .. WRITE_BL_PARTIAL:1 0:5
+ m_csd[13] |= BIT(block_size_exp, 0, 2) << 6;
+ m_csd[14] = 0x00; // 15: FILE_FORMAT_GRP:1 COPY:1 PERM_WRITE_PROTECT:1 TMP_WRITE_PROTECT:1 FILE_FORMAT:2 WP_UPC:1 0:1
+ m_csd[15] = 0x01; // 7: CRC7 1:1
+
+ if (sdhc_ok && ((SD_TYPE_HC == m_preferred_type) || !sd_ok))
+ {
+ uint32_t const c_size = (total_blocks >> 10) - 1;
+ osd_printf_verbose(
+ "%s: mounted as SDHC, %u blocks of %u bytes, device size ((%u + 1) << 10) * (1 << %u)\n",
+ tag(),
+ total_blocks, info.sectorbytes,
+ c_size, block_size_exp);
+
+ m_type = SD_TYPE_HC;
+
+ // set up CSD Version 2.0
+ m_csd[0] |= CSD_STRUCTURE_V20 << 6; // 127: CSD_STRUCTURE:2 (00b) 0:6
+ m_csd[1] = TAAC_UNIT_1MS | TAAC_VALUE_1_0; // 119: TAAC:8
+
+ m_csd[7] |= BIT(c_size, 16, 6); // .. C_SIZE:22
+ m_csd[8] |= BIT(c_size, 8, 8); // ..
+ m_csd[9] |= BIT(c_size, 0, 8); // ..
+ }
+ else
+ {
+ uint8_t const c_size_mult = std::min<uint8_t>(total_exp, 9) - 2;
+ uint16_t const c_size = (total_blocks >> (c_size_mult + 2)) - 1;
+ osd_printf_verbose(
+ "%s: mounted as SD, %u blocks of %u bytes, device size ((%u + 1) << (%u + 2)) * (1 << %u)\n",
+ tag(),
+ total_blocks, info.sectorbytes,
+ c_size, c_size_mult, block_size_exp);
+
+ m_type = SD_TYPE_V2;
+
+ // set up CSD Version 1.0
+ m_csd[0] |= CSD_STRUCTURE_V10 << 6; // 127: CSD_STRUCTURE:2 (00b) 0:6
+ m_csd[1] = TAAC_UNIT_1MS | TAAC_VALUE_1_5; // 119: TAAC:8
+
+ m_csd[6] |= BIT(c_size, 10, 2); // 79: READ_BL_PARTIAL:1 WRITE_BLK_MISALIGN:1 READ_BLK_MISALIGN:1 DSR_IMP:1 0:2 C_SIZE:12
+ m_csd[7] |= BIT(c_size, 2, 8); // ..
+ m_csd[8] |= BIT(c_size, 0, 2) << 6; // .. VDD_R_CURR_MIN:3 VDD_R_CURR_MAX:3
+ m_csd[8] |= VDD_CURR_MIN_100MA << 3;
+ m_csd[8] |= VDD_CURR_MAX_80MA;
+ m_csd[9] |= VDD_CURR_MIN_100MA << 5; // 55: VDD_W_CURR_MIN:3 VDD_W_CURR_MAX:3 C_SIZE_MUL:3
+ m_csd[9] |= VDD_CURR_MAX_80MA << 2;
+ m_csd[9] |= BIT(c_size_mult, 1, 2);
+ m_csd[10] |= BIT(c_size_mult, 0, 1) << 7; // .. ERASE_BLK_EN:1 SECTOR_SIZE:7
+ m_csd[11] |= 0x3f; // .. WP_GRP_SIZE:7
+ }
+
+ // TODO: calculate CRC7
+
+ LOG("Generated CSD %016x%016x\n", get_u64be(&m_csd[0]), get_u64be(&m_csd[8]));
+
+ return std::error_condition();
+}
+
+void spi_sdcard_device::image_unloaded(device_image_interface &image)
{
+ std::fill(std::begin(m_csd), std::end(m_csd), 0);
}
void spi_sdcard_device::device_add_mconfig(machine_config &config)
{
- HARDDISK(config, m_image).set_interface("spi_sdcard");
+ HARDDISK(config, m_image).set_interface("sdcard");
+ m_image->set_device_load(FUNC(spi_sdcard_device::image_loaded));
+ m_image->set_device_unload(FUNC(spi_sdcard_device::image_unloaded));
}
void spi_sdcard_device::send_data(u16 count, sd_state new_state)
@@ -217,7 +428,7 @@ void spi_sdcard_device::shift_out()
void spi_sdcard_device::do_command()
{
- if (((m_cmd[0] & 0xc0) == 0x40) && (m_cmd[5] & 1))
+ if (((m_cmd[0] & 0xc0) == 0x40) && ((m_cmd[5] & 1) || m_ignore_stop_bit))
{
LOGMASKED(LOG_COMMAND, "SDCARD: cmd %02d %02x %02x %02x %02x %02x\n", m_cmd[0] & 0x3f, m_cmd[1], m_cmd[2], m_cmd[3], m_cmd[4], m_cmd[5]);
bool clean_cmd = true;
@@ -254,40 +465,9 @@ void spi_sdcard_device::do_command()
m_data[0] = 0x00;
m_data[1] = 0xff;
m_data[2] = 0xfe;
+ std::copy(std::begin(m_csd), std::end(m_csd), &m_data[3]);
- //if (m_type == SD_TYPE_V2) // CSD Version 1.0
- {
- u8 block_len = 9;
- for (auto i = m_blksize >> 10; i; i >>= 1, ++block_len);
-
- m_data[3] = 0x00; // 127: CSD_STRUCTURE:2 (00b) 0:6
- m_data[4] = 0x0e; // 119: TAAC:8
- m_data[5] = 0x00; // 111: NSAC:8
- m_data[6] = 0x32; // 103: TRAN_SPEED:8 (32h or 5Ah)
- m_data[7] = 0x5b; // 95: CCC:12 (01x110110101b)
- m_data[8] = 0x50; // .. READ_BL_LN:4
- m_data[8] |= block_len;
- m_data[9] = 0x83; // 79: READ_BL_PARTIAL:1 (1b) WRITE_BLK_MISALIGN:1 READ_BLK_MISALIGN:1 DSR_IMP:1 0:2 C_SIZE:12
- m_data[10] = 0xff; // ..
- m_data[11] = 0xed; // .. VDD_R_CURR_MIN:3 VDD_R_CURR_MAX:3
- m_data[12] = 0xb7; // 55: VDD_W_CURR_MIN:3 VDD_W_CURR_MAX:3 C_SIZE_MUL:3
- m_data[13] = 0xbf; // .. ERASE_BLK_EN:1 SECTOR_SIZE:7
- m_data[14] = 0xbf; // .. WP_GRP_SIZE:7
- m_data[15] = 0x04; // 31: WP_GRP_ENABLE:1 0:2 R2W_FACTOR:3 WRITE_BL_LEN:4
- m_data[15] |= (block_len >> 2);
- m_data[16] = 0x00; /// .. WRITE_BL_PARTIAL:1 0:5
- m_data[16] |= (block_len & 3) << 6;
- m_data[17] = 0x00; // 15: FILE_FORMAT_GRP:1 COPY:1 PERM_WRITE_PROTECT:1 TMP_WRITE_PROTECT:1 FILE_FORMAT:2 WP_UPC:1 0:1
- m_data[18] = 0x01; // 7: CRC7 1:1
- }
- /*
- else // SD_TYPE_HC: CSD Version 2.0
- {
- m_data[3] = 0x40;
- }
- */
-
- send_data(3 + 16, SD_STATE_STBY);
+ send_data(3 + std::size(m_csd), SD_STATE_STBY);
break;
case 10: // CMD10 - SEND_CID
diff --git a/src/devices/machine/spi_sdcard.h b/src/devices/machine/spi_sdcard.h
index d8d4e698969..a6ec8607f07 100644
--- a/src/devices/machine/spi_sdcard.h
+++ b/src/devices/machine/spi_sdcard.h
@@ -10,6 +10,13 @@
class spi_sdcard_device : public device_t
{
public:
+ spi_sdcard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ virtual ~spi_sdcard_device();
+
+ void set_prefer_sd() { m_preferred_type = SD_TYPE_V2; }
+ void set_prefer_sdhc() { m_preferred_type = SD_TYPE_HC; }
+ void set_ignore_stop_bit(bool ignore) { m_ignore_stop_bit = ignore; }
+
// SPI 4-wire interface
auto spi_miso_callback() { return write_miso.bind(); }
void spi_clock_w(int state);
@@ -21,47 +28,28 @@ public:
devcb_write_line write_miso;
protected:
- enum sd_type : u8
- {
- SD_TYPE_V2 = 0,
- SD_TYPE_HC
- };
-
spi_sdcard_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void device_start() override ATTR_COLD;
- virtual void device_reset() override ATTR_COLD;
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
required_device<harddisk_image_device> m_image;
- sd_type m_type;
-
private:
- enum sd_state : u8
+ enum sd_type : u8
{
- //REF Table 4-1:Overview of Card States vs. Operation Mode
- SD_STATE_IDLE = 0,
- SD_STATE_READY,
- SD_STATE_IDENT,
- SD_STATE_STBY,
- SD_STATE_TRAN,
- SD_STATE_DATA,
- SD_STATE_DATA_MULTI, // synthetical state for this implementation
- SD_STATE_RCV,
- SD_STATE_PRG,
- SD_STATE_DIS,
- SD_STATE_INA,
-
- //FIXME Existing states which must be revisited
- SD_STATE_WRITE_WAITFE,
- SD_STATE_WRITE_DATA
+ SD_TYPE_V2,
+ SD_TYPE_HC
};
- sd_state m_state;
+
+ enum sd_state : u8;
// MMFS for Acorn machines expect dummy byte before response
static constexpr int SPI_DELAY_RESPONSE = 1;
+ std::error_condition image_loaded(device_image_interface &image);
+ void image_unloaded(device_image_interface &image);
+
void send_data(u16 count, sd_state new_state);
void do_command();
void change_state(sd_state new_state);
@@ -69,28 +57,25 @@ private:
void latch_in();
void shift_out();
- u8 m_data[520], m_cmd[6];
+ // configuration
+ sd_type m_preferred_type;
+ bool m_ignore_stop_bit;
+
+ // mounted image info
+ u16 m_blksize;
+ sd_type m_type;
+ u8 m_csd[16];
- int m_ss, m_in_bit, m_clk_state;
+ // live state
+ sd_state m_state;
+ u8 m_data[520], m_cmd[6];
+ u8 m_ss, m_in_bit, m_clk_state;
u8 m_in_latch, m_out_latch, m_cur_bit;
- u16 m_out_count, m_out_ptr, m_write_ptr, m_blksize;
+ u16 m_out_count, m_out_ptr, m_write_ptr;
u32 m_blknext;
bool m_bACMD;
};
-class spi_sdcard_sdhc_device : public spi_sdcard_device
-{
-public:
- spi_sdcard_sdhc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-};
-
-class spi_sdcard_sdv2_device : public spi_sdcard_device
-{
-public:
- spi_sdcard_sdv2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-};
-
-DECLARE_DEVICE_TYPE(SPI_SDCARD, spi_sdcard_sdhc_device)
-DECLARE_DEVICE_TYPE(SPI_SDCARDV2, spi_sdcard_sdv2_device)
+DECLARE_DEVICE_TYPE(SPI_SDCARD, spi_sdcard_device)
#endif // MAME_MACHINE_SPI_SDCARD_H
diff --git a/src/mame/sinclair/chloe.cpp b/src/mame/sinclair/chloe.cpp
index 5fd9dc932df..7f88fcebd59 100644
--- a/src/mame/sinclair/chloe.cpp
+++ b/src/mame/sinclair/chloe.cpp
@@ -105,7 +105,7 @@ private:
required_device<address_map_bank_device> m_regs_map;
required_device<device_palette_interface> m_palette;
required_device<screen_ula_plus_device> m_ula;
- required_device<spi_sdcard_sdhc_device> m_sdcard;
+ required_device<spi_sdcard_device> m_sdcard;
required_ioport_array<8> m_io_line;
required_ioport_array<3> m_io_mouse;
required_device_array<ay8912_device, 2> m_ay;
@@ -921,6 +921,7 @@ void chloe_state::chloe(machine_config &config)
*/
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
m_sdcard->spi_miso_callback().set(FUNC(chloe_state::spi_miso_w));
subdevice<gfxdecode_device>("gfxdecode")->set_info(gfx_chloe);
diff --git a/src/mame/sinclair/pentevo.cpp b/src/mame/sinclair/pentevo.cpp
index 4f2f52109c6..5df592796ff 100644
--- a/src/mame/sinclair/pentevo.cpp
+++ b/src/mame/sinclair/pentevo.cpp
@@ -121,7 +121,7 @@ private:
memory_view m_io_dos_view;
required_device<glukrs_device> m_glukrs;
- required_device<spi_sdcard_sdhc_device> m_sdcard;
+ required_device<spi_sdcard_device> m_sdcard;
required_device<at_keyboard_device> m_keyboard;
required_ioport_array<3> m_io_mouse;
required_device_array<ym2149_device, 2> m_ay;
@@ -765,6 +765,7 @@ void pentevo_state::pentevo(machine_config &config)
GLUKRS(config, m_glukrs);
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
m_sdcard->spi_miso_callback().set(FUNC(pentevo_state::spi_miso_w));
SPEAKER(config, "lspeaker").front_left();
diff --git a/src/mame/sinclair/specnext.cpp b/src/mame/sinclair/specnext.cpp
index f9891fd4608..f5fc1c1b2e1 100644
--- a/src/mame/sinclair/specnext.cpp
+++ b/src/mame/sinclair/specnext.cpp
@@ -296,7 +296,7 @@ private:
required_device<specnext_ctc_device> m_ctc;
required_device<specnext_dma_device> m_dma;
required_device<i2cmem_device> m_i2cmem;
- required_device<spi_sdcard_sdhc_device> m_sdcard;
+ required_device<spi_sdcard_device> m_sdcard;
required_device_array<ym2149_device, 3> m_ay;
required_device_array<dac_byte_interface, 4> m_dac;
required_device<device_palette_interface> m_palette;
@@ -3467,6 +3467,7 @@ void specnext_state::tbblue(machine_config &config)
I2C_24C01(config, m_i2cmem).set_address(0xd0); // RTC + DEFAULT_ALL_0; confitm size
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
m_sdcard->spi_miso_callback().set(FUNC(specnext_state::spi_miso_w));
SPEAKER(config, "lspeaker").front_left();
diff --git a/src/mame/sinclair/tsconf.cpp b/src/mame/sinclair/tsconf.cpp
index d06debc7539..feae471d8d9 100644
--- a/src/mame/sinclair/tsconf.cpp
+++ b/src/mame/sinclair/tsconf.cpp
@@ -294,6 +294,7 @@ void tsconf_state::tsconf(machine_config &config)
BETA_DISK(config, m_beta, 0);
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
m_sdcard->spi_miso_callback().set(FUNC(tsconf_state::tsconf_spi_miso_w));
SPEAKER(config, "lspeaker").front_left();
diff --git a/src/mame/sinclair/tsconf.h b/src/mame/sinclair/tsconf.h
index ac8b2f984aa..37dfe65b808 100644
--- a/src/mame/sinclair/tsconf.h
+++ b/src/mame/sinclair/tsconf.h
@@ -220,7 +220,7 @@ private:
required_device<beta_disk_device> m_beta;
required_device<tsconfdma_device> m_dma;
- required_device<spi_sdcard_sdhc_device> m_sdcard;
+ required_device<spi_sdcard_device> m_sdcard;
u8 m_zctl_di = 0;
u8 m_zctl_cs = 0;
diff --git a/src/mame/tvgames/gpm4530a_lexibook_jg7420.cpp b/src/mame/tvgames/gpm4530a_lexibook_jg7420.cpp
index fc6064b82af..d142ee5b29e 100644
--- a/src/mame/tvgames/gpm4530a_lexibook_jg7420.cpp
+++ b/src/mame/tvgames/gpm4530a_lexibook_jg7420.cpp
@@ -33,7 +33,7 @@ protected:
required_device<cpu_device> m_maincpu;
required_device<screen_device> m_screen;
- required_device<spi_sdcard_sdhc_device> m_sdcard;
+ required_device<spi_sdcard_device> m_sdcard;
uint32_t screen_update_gpm4530a_lexibook(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
@@ -74,6 +74,7 @@ void gpm4530a_lexibook_state::gpm4530a_lexibook(machine_config &config)
m_screen->set_screen_update(FUNC(gpm4530a_lexibook_state::screen_update_gpm4530a_lexibook));
SPI_SDCARD(config, m_sdcard, 0);
+ m_sdcard->set_prefer_sdhc();
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();