From f40c98743eeb988c3d877162f0468a1669b44ecd Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Tue, 1 Oct 2024 02:20:33 +1000 Subject: -machine/spi_sdcard.cpp: Generate appropriate CSD for mounted image. * The Linux/4004 firmware gets very upset if the CSD looks like an SDHC Card but the card acts like an SD Card or vice versa. -machine/spi_psram.cpp: Added SPI ram device compatible with SPI SRAM and Pseudo-SRAM chips for small transfers. Additional functionality will be added as use cases arise. -cpu/mcs40: Don't log messages about NOP aliases for the 4004 (the Linux/4004 firmware uses these for instrumentation points). --- scripts/src/machine.lua | 11 + src/devices/bus/a2bus/a2sd.cpp | 68 +++++- src/devices/bus/a2bus/a2sd.h | 49 +---- src/devices/bus/bbc/cart/mastersd.cpp | 68 +++++- src/devices/bus/bbc/cart/mastersd.h | 67 +----- src/devices/bus/bbc/userport/sdcard.cpp | 65 +++++- src/devices/bus/bbc/userport/sdcard.h | 58 +---- src/devices/bus/electron/cart/elksdp1.cpp | 48 +++- src/devices/bus/electron/cart/elksdp1.h | 46 +--- src/devices/bus/electron/elksd128.cpp | 58 ++++- src/devices/bus/electron/elksd128.h | 58 +---- src/devices/bus/electron/elksd64.cpp | 44 +++- src/devices/bus/electron/elksd64.h | 44 +--- src/devices/bus/spectrum/neogs.cpp | 3 +- src/devices/bus/vtech/memexp/sdloader.cpp | 66 +++++- src/devices/bus/vtech/memexp/sdloader.h | 57 +---- src/devices/cpu/mcs40/mcs40.cpp | 30 ++- src/devices/cpu/mcs40/mcs40.h | 2 + src/devices/machine/spi_psram.cpp | 306 ++++++++++++++++++++++++++ src/devices/machine/spi_psram.h | 57 +++++ src/devices/machine/spi_sdcard.cpp | 302 ++++++++++++++++++++----- src/devices/machine/spi_sdcard.h | 73 +++--- src/mame/sinclair/chloe.cpp | 3 +- src/mame/sinclair/pentevo.cpp | 3 +- src/mame/sinclair/specnext.cpp | 3 +- src/mame/sinclair/tsconf.cpp | 1 + src/mame/sinclair/tsconf.h | 2 +- src/mame/tvgames/gpm4530a_lexibook_jg7420.cpp | 3 +- 28 files changed, 1093 insertions(+), 502 deletions(-) create mode 100644 src/devices/machine/spi_psram.cpp create mode 100644 src/devices/machine/spi_psram.h 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 @@ -4571,6 +4571,17 @@ if (MACHINES["SMARTMEDIA"]~=null) then } 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 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 m_flash; + required_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 m_flash; - required_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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 m_sdcard; + + uint8_t m_romsel; + uint8_t m_status; + + std::unique_ptr 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 m_sdcard; - - uint8_t m_romsel; - uint8_t m_status; - - std::unique_ptr 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 m_dac; - required_device m_sdcard; + required_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 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 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(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 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 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 auto cm_ram_cb() { return mcs40_cpu_device_base::cm_ram_cb(); } 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(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(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(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(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 + + +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 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 + #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(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 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 m_regs_map; required_device m_palette; required_device m_ula; - required_device m_sdcard; + required_device m_sdcard; required_ioport_array<8> m_io_line; required_ioport_array<3> m_io_mouse; required_device_array 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")->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 m_glukrs; - required_device m_sdcard; + required_device m_sdcard; required_device m_keyboard; required_ioport_array<3> m_io_mouse; required_device_array 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 m_ctc; required_device m_dma; required_device m_i2cmem; - required_device m_sdcard; + required_device m_sdcard; required_device_array m_ay; required_device_array m_dac; required_device 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 m_beta; required_device m_dma; - required_device m_sdcard; + required_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 m_maincpu; required_device m_screen; - required_device m_sdcard; + required_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(); -- cgit v1.2.3