From 1ee0573df3547214af20c2953543bb46b073e694 Mon Sep 17 00:00:00 2001 From: wilbertpol Date: Wed, 6 Nov 2024 15:13:47 +0000 Subject: [PATCH] Various Super Cassette Vision updates (#12933) scv.xml: Promote starspdr to partially supported. devices/sound/upd1771.cpp: Reset m_state when resetting state in pcm_write (fixes hanging sound in some games). bus/scv/rom;cpp: Move implementations to anonymous namespace. bus/scv/slot.cpp: Let cartridges install themselves. epoch/scv.cpp: - Tweak scv_pal video timings to get closer to 50Hz refresh rate. - Block graphic color 0 is transparent (fixes Ton Ton Ball background). - Update comments. --- hash/scv.xml | 4 +- src/devices/bus/scv/rom.cpp | 312 ++++++++------- src/devices/bus/scv/rom.h | 149 +------ src/devices/bus/scv/slot.cpp | 153 ++----- src/devices/bus/scv/slot.h | 85 ++-- src/devices/sound/upd1771.cpp | 3 +- src/mame/epoch/scv.cpp | 728 +++++++++++++++------------------- 7 files changed, 579 insertions(+), 855 deletions(-) diff --git a/hash/scv.xml b/hash/scv.xml index d151ffe7bf5..bd7d69afc34 100644 --- a/hash/scv.xml +++ b/hash/scv.xml @@ -363,11 +363,11 @@ Information found at http://www.rhod.fr/yeno_epoch.html - + Star Speeder 1985 Epoch - Game does not start. + uPD1771 adpcm playback is not supported. diff --git a/src/devices/bus/scv/rom.cpp b/src/devices/bus/scv/rom.cpp index 8be6a020752..d430b6de04a 100644 --- a/src/devices/bus/scv/rom.cpp +++ b/src/devices/bus/scv/rom.cpp @@ -13,191 +13,231 @@ #include "rom.h" -//------------------------------------------------- -// scv_rom_device - constructor -//------------------------------------------------- +namespace { -DEFINE_DEVICE_TYPE(SCV_ROM8K, scv_rom8_device, "scv_rom8", "SCV 8K Carts") -DEFINE_DEVICE_TYPE(SCV_ROM16K, scv_rom16_device, "scv_rom16", "SCV 16K Carts") -DEFINE_DEVICE_TYPE(SCV_ROM32K, scv_rom32_device, "scv_rom32", "SCV 32K Carts") -DEFINE_DEVICE_TYPE(SCV_ROM32K_RAM8K, scv_rom32ram8_device, "scv_rom32_ram8", "SCV 32K + RAM 8K Carts") -DEFINE_DEVICE_TYPE(SCV_ROM64K, scv_rom64_device, "scv_rom64", "SCV 64K Carts") -DEFINE_DEVICE_TYPE(SCV_ROM128K, scv_rom128_device, "scv_rom128", "SCV 128K Carts") -DEFINE_DEVICE_TYPE(SCV_ROM128K_RAM4K, scv_rom128ram4_device, "scv_rom128_ram4", "SCV 128K + RAM 4K Carts") - - -scv_rom8_device::scv_rom8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, type, tag, owner, clock), device_scv_cart_interface(mconfig, *this) +class scv_rom8_device : public device_t, + public device_scv_cart_interface { -} +public: + scv_rom8_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : scv_rom8_device(mconfig, SCV_ROM8K, tag, owner, clock) + { } -scv_rom8_device::scv_rom8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : scv_rom8_device(mconfig, SCV_ROM8K, tag, owner, clock) -{ -} + virtual void install_memory_handlers(address_space *space) override; -scv_rom16_device::scv_rom16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : scv_rom8_device(mconfig, SCV_ROM16K, tag, owner, clock) -{ -} +protected: + scv_rom8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock), device_scv_cart_interface(mconfig, *this) + { } -scv_rom32_device::scv_rom32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : scv_rom8_device(mconfig, SCV_ROM32K, tag, owner, clock) -{ -} + virtual void device_start() override { } + virtual void device_reset() override { } -scv_rom32ram8_device::scv_rom32ram8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : scv_rom8_device(mconfig, SCV_ROM32K_RAM8K, tag, owner, clock), m_ram_enabled(0) -{ -} + static constexpr u16 CARTRIDGE_ADDRESS_END = 0xff7f; +}; -scv_rom64_device::scv_rom64_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : scv_rom8_device(mconfig, SCV_ROM64K, tag, owner, clock), m_bank_base(0) -{ -} - -scv_rom128_device::scv_rom128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : scv_rom8_device(mconfig, SCV_ROM128K, tag, owner, clock), m_bank_base(0) -{ -} - -scv_rom128ram4_device::scv_rom128ram4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : scv_rom8_device(mconfig, SCV_ROM128K_RAM4K, tag, owner, clock), m_bank_base(0), m_ram_enabled(0) +void scv_rom8_device::install_memory_handlers(address_space *space) { + space->install_rom(0x8000, 0x9fff, cart_rom_region()->base()); + space->install_rom(0xa000, 0xbfff, cart_rom_region()->base()); + space->install_rom(0xc000, 0xdfff, cart_rom_region()->base()); + space->install_rom(0xe000, CARTRIDGE_ADDRESS_END, cart_rom_region()->base()); } -//------------------------------------------------- -// mapper specific start/reset -//------------------------------------------------- -void scv_rom32ram8_device::device_start() +class scv_rom16_device : public scv_rom8_device { - save_item(NAME(m_ram_enabled)); +public: + scv_rom16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : scv_rom8_device(mconfig, SCV_ROM16K, tag, owner, clock) + { } + + virtual void install_memory_handlers(address_space *space) override; +}; + +void scv_rom16_device::install_memory_handlers(address_space *space) +{ + space->install_rom(0x8000, 0xbfff, cart_rom_region()->base()); + space->install_rom(0xc000, CARTRIDGE_ADDRESS_END, cart_rom_region()->base()); } + + +class scv_rom32_device : public scv_rom8_device +{ +public: + scv_rom32_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : scv_rom8_device(mconfig, SCV_ROM32K, tag, owner, clock) + { } + + virtual void install_memory_handlers(address_space *space) override; +}; + +void scv_rom32_device::install_memory_handlers(address_space *space) +{ + space->install_rom(0x8000, CARTRIDGE_ADDRESS_END, cart_rom_region()->base()); +} + + + +class scv_rom32ram8_device : public scv_rom8_device +{ +public: + scv_rom32ram8_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : scv_rom8_device(mconfig, SCV_ROM32K_RAM8K, tag, owner, clock) + , m_view(*this, "view") + { } + + virtual void install_memory_handlers(address_space *space) override; + virtual void write_bank(uint8_t data) override; + +protected: + virtual void device_reset() override ATTR_COLD; + +private: + memory_view m_view; +}; + void scv_rom32ram8_device::device_reset() { - m_ram_enabled = 1; + m_view.select(1); } - -void scv_rom64_device::device_start() +void scv_rom32ram8_device::install_memory_handlers(address_space *space) { - save_item(NAME(m_bank_base)); -} - -void scv_rom64_device::device_reset() -{ - m_bank_base = 0; -} - - -void scv_rom128_device::device_start() -{ - save_item(NAME(m_bank_base)); -} - -void scv_rom128_device::device_reset() -{ - m_bank_base = 0; -} - - -void scv_rom128ram4_device::device_start() -{ - save_item(NAME(m_bank_base)); - save_item(NAME(m_ram_enabled)); -} - -void scv_rom128ram4_device::device_reset() -{ - m_bank_base = 0; - m_ram_enabled = 1; -} - - - -/*------------------------------------------------- - mapper specific handlers - -------------------------------------------------*/ - -uint8_t scv_rom8_device::read_cart(offs_t offset) -{ - return m_rom[offset & 0x1fff]; -} - - -uint8_t scv_rom16_device::read_cart(offs_t offset) -{ - return m_rom[offset & 0x3fff]; -} - - -uint8_t scv_rom32_device::read_cart(offs_t offset) -{ - return m_rom[offset]; -} - - -uint8_t scv_rom32ram8_device::read_cart(offs_t offset) -{ - if (m_ram_enabled && offset >= 0x6000) - return m_ram[offset & 0x1fff]; - - return m_rom[offset]; -} - -void scv_rom32ram8_device::write_cart(offs_t offset, uint8_t data) -{ - if (m_ram_enabled && offset >= 0x6000) - m_ram[offset & 0x1fff] = data; + space->install_rom(0x8000, CARTRIDGE_ADDRESS_END, cart_rom_region()->base()); + space->install_view(0xe000, CARTRIDGE_ADDRESS_END, m_view); + m_view[0]; + m_view[1].install_ram(0xe000, CARTRIDGE_ADDRESS_END, cart_ram_region()->base()); } void scv_rom32ram8_device::write_bank(uint8_t data) { - m_ram_enabled = BIT(data, 5); + m_view.select(BIT(data, 5)); } -uint8_t scv_rom64_device::read_cart(offs_t offset) + +class scv_rom64_device : public scv_rom8_device { - return m_rom[offset + (m_bank_base * 0x8000)]; +public: + scv_rom64_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : scv_rom8_device(mconfig, SCV_ROM64K, tag, owner, clock) + , m_bank(*this, "bank") + { } + + virtual void install_memory_handlers(address_space *space) override; + virtual void write_bank(uint8_t data) override; + +protected: + virtual void device_reset() override ATTR_COLD; + +private: + memory_bank_creator m_bank; +}; + +void scv_rom64_device::device_reset() +{ + m_bank->set_entry(0); +} + +void scv_rom64_device::install_memory_handlers(address_space *space) +{ + m_bank->configure_entries(0, 2, cart_rom_region()->base(), 0x8000); + space->install_read_bank(0x8000, CARTRIDGE_ADDRESS_END, m_bank); } void scv_rom64_device::write_bank(uint8_t data) { - m_bank_base = BIT(data, 5); + m_bank->set_entry(BIT(data, 5)); } -uint8_t scv_rom128_device::read_cart(offs_t offset) + +class scv_rom128_device : public scv_rom8_device { - return m_rom[offset + (m_bank_base * 0x8000)]; +public: + scv_rom128_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : scv_rom8_device(mconfig, SCV_ROM128K, tag, owner, clock) + , m_bank(*this, "bank") + { } + + virtual void install_memory_handlers(address_space *space) override; + virtual void write_bank(uint8_t data) override; + +protected: + virtual void device_reset() override ATTR_COLD; + +private: + memory_bank_creator m_bank; +}; + +void scv_rom128_device::device_reset() +{ + m_bank->set_entry(0); +} + +void scv_rom128_device::install_memory_handlers(address_space *space) +{ + m_bank->configure_entries(0, 4, cart_rom_region()->base(), 0x8000); + space->install_read_bank(0x8000, CARTRIDGE_ADDRESS_END, m_bank); } void scv_rom128_device::write_bank(uint8_t data) { - m_bank_base = (data >> 5) & 0x03; + m_bank->set_entry((data >> 5) & 0x03); } -uint8_t scv_rom128ram4_device::read_cart(offs_t offset) -{ - if (m_ram_enabled && offset >= 0x7000) - return m_ram[offset & 0xfff]; - return m_rom[offset + (m_bank_base * 0x8000)]; +class scv_rom128ram4_device : public scv_rom8_device +{ +public: + scv_rom128ram4_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : scv_rom8_device(mconfig, SCV_ROM128K_RAM4K, tag, owner, clock) + , m_bank(*this, "bank") + , m_view(*this, "view") + { } + + virtual void install_memory_handlers(address_space *space) override; + virtual void write_bank(uint8_t data) override; + +protected: + virtual void device_reset() override ATTR_COLD; + +private: + memory_bank_creator m_bank; + memory_view m_view; +}; + +void scv_rom128ram4_device::device_reset() +{ + m_bank->set_entry(0); + m_view.select(0); } -void scv_rom128ram4_device::write_cart(offs_t offset, uint8_t data) +void scv_rom128ram4_device::install_memory_handlers(address_space *space) { - if (m_ram_enabled && offset >= 0x7000) - m_ram[offset & 0xfff] = data; + m_bank->configure_entries(0, 4, cart_rom_region()->base(), 0x8000); + space->install_read_bank(0x8000, CARTRIDGE_ADDRESS_END, m_bank); + space->install_view(0xf000, CARTRIDGE_ADDRESS_END, m_view); + m_view[0]; + m_view[1].install_ram(0xf000, CARTRIDGE_ADDRESS_END, cart_ram_region()->base()); } void scv_rom128ram4_device::write_bank(uint8_t data) { - m_bank_base = (data >> 5) & 0x03; - m_ram_enabled = BIT(data, 6); + m_bank->set_entry((data >> 5) & 0x03); + m_view.select(BIT(data, 6)); } + +} // anonymous namespace + +DEFINE_DEVICE_TYPE_PRIVATE(SCV_ROM8K, device_scv_cart_interface, scv_rom8_device, "scv_rom8", "SCV 8K Cartridge") +DEFINE_DEVICE_TYPE_PRIVATE(SCV_ROM16K, device_scv_cart_interface, scv_rom16_device, "scv_rom16", "SCV 16K Cartridge") +DEFINE_DEVICE_TYPE_PRIVATE(SCV_ROM32K, device_scv_cart_interface, scv_rom32_device, "scv_rom32", "SCV 32K Cartridge") +DEFINE_DEVICE_TYPE_PRIVATE(SCV_ROM32K_RAM8K, device_scv_cart_interface, scv_rom32ram8_device, "scv_rom32_ram8", "SCV 32K + RAM 8K Cartridge") +DEFINE_DEVICE_TYPE_PRIVATE(SCV_ROM64K, device_scv_cart_interface, scv_rom64_device, "scv_rom64", "SCV 64K Cartridge") +DEFINE_DEVICE_TYPE_PRIVATE(SCV_ROM128K, device_scv_cart_interface, scv_rom128_device, "scv_rom128", "SCV 128K Cartridge") +DEFINE_DEVICE_TYPE_PRIVATE(SCV_ROM128K_RAM4K, device_scv_cart_interface, scv_rom128ram4_device, "scv_rom128_ram4", "SCV 128K + RAM 4K Cartridge") diff --git a/src/devices/bus/scv/rom.h b/src/devices/bus/scv/rom.h index 775453cafc9..20f0cefbf23 100644 --- a/src/devices/bus/scv/rom.h +++ b/src/devices/bus/scv/rom.h @@ -8,148 +8,13 @@ #include "slot.h" -// ======================> scv_rom8_device - -class scv_rom8_device : public device_t, - public device_scv_cart_interface -{ -public: - // construction/destruction - scv_rom8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - // reading and writing - virtual uint8_t read_cart(offs_t offset) override; - -protected: - scv_rom8_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 { } - virtual void device_reset() override { } -}; - -// ======================> scv_rom16_device - -class scv_rom16_device : public scv_rom8_device -{ -public: - // construction/destruction - scv_rom16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - // reading and writing - virtual uint8_t read_cart(offs_t offset) override; -}; - - -// ======================> scv_rom32_device - -class scv_rom32_device : public scv_rom8_device -{ -public: - // construction/destruction - scv_rom32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - // reading and writing - virtual uint8_t read_cart(offs_t offset) override; -}; - - -// ======================> scv_rom32ram8_device - -class scv_rom32ram8_device : public scv_rom8_device -{ -public: - // construction/destruction - scv_rom32ram8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - // reading and writing - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - virtual void write_bank(uint8_t data) override; - -protected: - // device-level overrides - virtual void device_start() override ATTR_COLD; - virtual void device_reset() override ATTR_COLD; - -private: - uint8_t m_ram_enabled; -}; - - -// ======================> scv_rom64_device - -class scv_rom64_device : public scv_rom8_device -{ -public: - // construction/destruction - scv_rom64_device(const machine_config &mconfig, 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; - - // reading and writing - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_bank(uint8_t data) override; - -private: - uint8_t m_bank_base; -}; - - -// ======================> scv_rom128_device - -class scv_rom128_device : public scv_rom8_device -{ -public: - // construction/destruction - scv_rom128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - // reading and writing - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_bank(uint8_t data) override; - -protected: - // device-level overrides - virtual void device_start() override ATTR_COLD; - virtual void device_reset() override ATTR_COLD; - -private: - uint8_t m_bank_base; -}; - - -// ======================> scv_rom128ram4_device - -class scv_rom128ram4_device : public scv_rom8_device -{ -public: - // construction/destruction - scv_rom128ram4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - // reading and writing - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - virtual void write_bank(uint8_t data) override; - -protected: - // device-level overrides - virtual void device_start() override ATTR_COLD; - virtual void device_reset() override ATTR_COLD; - -private: - uint8_t m_bank_base, m_ram_enabled; -}; - - // device type definition -DECLARE_DEVICE_TYPE(SCV_ROM8K, scv_rom8_device) -DECLARE_DEVICE_TYPE(SCV_ROM16K, scv_rom16_device) -DECLARE_DEVICE_TYPE(SCV_ROM32K, scv_rom32_device) -DECLARE_DEVICE_TYPE(SCV_ROM32K_RAM8K, scv_rom32ram8_device) -DECLARE_DEVICE_TYPE(SCV_ROM64K, scv_rom64_device) -DECLARE_DEVICE_TYPE(SCV_ROM128K, scv_rom128_device) -DECLARE_DEVICE_TYPE(SCV_ROM128K_RAM4K, scv_rom128ram4_device) +DECLARE_DEVICE_TYPE(SCV_ROM8K, device_scv_cart_interface) +DECLARE_DEVICE_TYPE(SCV_ROM16K, device_scv_cart_interface) +DECLARE_DEVICE_TYPE(SCV_ROM32K, device_scv_cart_interface) +DECLARE_DEVICE_TYPE(SCV_ROM32K_RAM8K, device_scv_cart_interface) +DECLARE_DEVICE_TYPE(SCV_ROM64K, device_scv_cart_interface) +DECLARE_DEVICE_TYPE(SCV_ROM128K, device_scv_cart_interface) +DECLARE_DEVICE_TYPE(SCV_ROM128K_RAM4K, device_scv_cart_interface) #endif // MAME_BUS_SCV_ROM_H diff --git a/src/devices/bus/scv/slot.cpp b/src/devices/bus/scv/slot.cpp index b6ef651cdf5..fe813fa141d 100644 --- a/src/devices/bus/scv/slot.cpp +++ b/src/devices/bus/scv/slot.cpp @@ -10,87 +10,66 @@ #include "emu.h" #include "slot.h" -//************************************************************************** -// GLOBAL VARIABLES -//************************************************************************** DEFINE_DEVICE_TYPE(SCV_CART_SLOT, scv_cart_slot_device, "scv_cart_slot", "SCV Cartridge Slot") + +enum +{ + SCV_8K = 0, + SCV_16K, + SCV_32K, + SCV_32K_RAM, + SCV_64K, + SCV_128K, + SCV_128K_RAM +}; + //************************************************************************** // SCV cartridges Interface //************************************************************************** -//------------------------------------------------- -// device_scv_cart_interface - constructor -//------------------------------------------------- - device_scv_cart_interface::device_scv_cart_interface(const machine_config &mconfig, device_t &device) : device_interface(device, "scvcart"), - m_rom(nullptr), - m_rom_size(0) + m_slot(dynamic_cast(device.owner())) { } -//------------------------------------------------- -// ~device_scv_cart_interface - destructor -//------------------------------------------------- - device_scv_cart_interface::~device_scv_cart_interface() { } -//------------------------------------------------- -// rom_alloc - alloc the space for the cart -//------------------------------------------------- -void device_scv_cart_interface::rom_alloc(uint32_t size) +void device_scv_cart_interface::savestate_ram() { - if (m_rom == nullptr) + if (cart_ram_region()) { - m_rom = device().machine().memory().region_alloc(device().subtag("^cart:rom"), size, 1, ENDIANNESS_LITTLE)->base(); - m_rom_size = size; + u8 *rambase(&cart_ram_region()->as_u8()); + device().save_pointer(NAME(rambase), cart_ram_region()->bytes()); } } -//------------------------------------------------- -// ram_alloc - alloc the space for the ram -//------------------------------------------------- - -void device_scv_cart_interface::ram_alloc(uint32_t size) -{ - m_ram.resize(size); -} - - //************************************************************************** // LIVE DEVICE //************************************************************************** -//------------------------------------------------- -// scv_cart_slot_device - constructor -//------------------------------------------------- -scv_cart_slot_device::scv_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +scv_cart_slot_device::scv_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, SCV_CART_SLOT, tag, owner, clock), device_cartrom_image_interface(mconfig, *this), device_single_card_slot_interface(mconfig, *this), - m_type(SCV_8K), m_cart(nullptr) + m_type(SCV_8K), + m_cart(nullptr), + m_address_space(*this, finder_base::DUMMY_TAG, -1, 8) { } -//------------------------------------------------- -// scv_cart_slot_device - destructor -//------------------------------------------------- - scv_cart_slot_device::~scv_cart_slot_device() { } -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- void scv_cart_slot_device::device_start() { @@ -128,7 +107,7 @@ static int scv_get_pcb_id(const char *slot) return elem.pcb_id; } - return 0; + return slot_list[0].pcb_id; } static const char *scv_get_slot(int type) @@ -139,37 +118,32 @@ static const char *scv_get_slot(int type) return elem.slot_option; } - return "rom8k"; + return slot_list[0].slot_option; } -/*------------------------------------------------- - call load - -------------------------------------------------*/ - std::pair scv_cart_slot_device::call_load() { if (m_cart) { - uint32_t const len = !loaded_through_softlist() ? length() : get_software_region_length("rom"); - bool const has_ram = loaded_through_softlist() && get_software_region("ram"); + const u32 len = loaded_through_softlist() ? get_software_region_length("rom") : length(); + const bool has_ram = loaded_through_softlist() && get_software_region("ram"); if (len > 0x20000) return std::make_pair(image_error::INVALIDLENGTH, "Unsupported cartridge size (must be no more than 128K)"); - m_cart->rom_alloc(len); - if (has_ram) - m_cart->ram_alloc(get_software_region_length("ram")); - - uint8_t *const ROM = m_cart->get_rom_base(); - if (!loaded_through_softlist()) - fread(ROM, len); - else - memcpy(ROM, get_software_region("rom"), len); + { + u32 length_aligned = 0x2000; + while (length_aligned < len) + length_aligned *= 2; - if (!loaded_through_softlist()) - m_type = get_cart_type(ROM, len); + memory_region *const romregion = machine().memory().region_alloc(subtag("rom"), length_aligned, 1, ENDIANNESS_LITTLE); + if (fread(romregion->base(), len) != len) + return std::make_pair(image_error::UNSPECIFIED, "Unable to fully read file"); + + m_type = get_cart_type(len); + } else { const char *pcb_name = get_feature("slot"); @@ -184,23 +158,19 @@ std::pair scv_cart_slot_device::call_load() if (m_type == SCV_128K && has_ram) m_type = SCV_128K_RAM; - //printf("Type: %s\n", scv_get_slot(m_type)); + m_cart->install_memory_handlers(m_address_space.target()); + m_cart->savestate_ram(); } return std::make_pair(std::error_condition(), std::string()); } -/*------------------------------------------------- - get_cart_type - code to detect NVRAM type from - fullpath - -------------------------------------------------*/ - -int scv_cart_slot_device::get_cart_type(const uint8_t *ROM, uint32_t len) +int scv_cart_slot_device::get_cart_type(u32 len) { int type = SCV_8K; - // TO DO: is there any way to identify carts with RAM?!? + // TODO: is there any way to identify carts with RAM?!? switch (len) { case 0x2000: @@ -224,59 +194,24 @@ int scv_cart_slot_device::get_cart_type(const uint8_t *ROM, uint32_t len) } -/*------------------------------------------------- - get default card software - -------------------------------------------------*/ - std::string scv_cart_slot_device::get_default_card_software(get_default_card_software_hook &hook) const { if (hook.image_file()) { - uint64_t len; + u64 len = 0; hook.image_file()->length(len); // FIXME: check error return, guard against excessively large files - std::vector rom(len); - read(*hook.image_file(), &rom[0], len); // FIXME: check error return or read returning short - - int const type = get_cart_type(&rom[0], len); - char const *const slot_string = scv_get_slot(type); - - //printf("type: %s\n", slot_string); + const int type = get_cart_type(len); + const char *const slot_string = scv_get_slot(type); return std::string(slot_string); } - return software_get_default_slot("rom8k"); -} - -/*------------------------------------------------- - read - -------------------------------------------------*/ - -uint8_t scv_cart_slot_device::read_cart(offs_t offset) -{ - if (m_cart) - return m_cart->read_cart(offset); - else - return 0xff; -} - -/*------------------------------------------------- - write - -------------------------------------------------*/ - -void scv_cart_slot_device::write_cart(offs_t offset, uint8_t data) -{ - if (m_cart) - m_cart->write_cart(offset, data); + return software_get_default_slot(slot_list[0].slot_option); } -/*------------------------------------------------- - write_bank - -------------------------------------------------*/ - -void scv_cart_slot_device::write_bank(uint8_t data) +void scv_cart_slot_device::write_bank(u8 data) { if (m_cart) m_cart->write_bank(data); diff --git a/src/devices/bus/scv/slot.h b/src/devices/bus/scv/slot.h index 8744156af27..f1d385d95b4 100644 --- a/src/devices/bus/scv/slot.h +++ b/src/devices/bus/scv/slot.h @@ -8,54 +8,7 @@ #include "imagedev/cartrom.h" -/*************************************************************************** - TYPE DEFINITIONS - ***************************************************************************/ - - -/* PCB */ -enum -{ - SCV_8K = 0, - SCV_16K, - SCV_32K, - SCV_32K_RAM, - SCV_64K, - SCV_128K, - SCV_128K_RAM -}; - - -// ======================> device_scv_cart_interface - -class device_scv_cart_interface : public device_interface -{ -public: - // construction/destruction - virtual ~device_scv_cart_interface(); - - // reading and writing - virtual uint8_t read_cart(offs_t offset) { return 0xff; } - virtual void write_cart(offs_t offset, uint8_t data) { } - virtual void write_bank(uint8_t data) { } - - void rom_alloc(uint32_t size); - void ram_alloc(uint32_t size); - uint8_t* get_rom_base() { return m_rom; } - uint8_t* get_ram_base() { return &m_ram[0]; } - uint32_t get_rom_size() { return m_rom_size; } - uint32_t get_ram_size() { return m_ram.size(); } - - void save_ram() { device().save_item(NAME(m_ram)); } - -protected: - device_scv_cart_interface(const machine_config &mconfig, device_t &device); - - // internal state - uint8_t *m_rom; - uint32_t m_rom_size; - std::vector m_ram; -}; +class device_scv_cart_interface; // ======================> scv_cart_slot_device @@ -76,9 +29,11 @@ public: set_fixed(false); } - scv_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + scv_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); virtual ~scv_cart_slot_device(); + template void set_address_space(T &&tag, int no) { m_address_space.set_tag(std::forward(tag), no); } + // device_image_interface implementation virtual std::pair call_load() override; virtual void call_unload() override { } @@ -91,14 +46,10 @@ public: virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override; int get_type() { return m_type; } - static int get_cart_type(const uint8_t *ROM, uint32_t len); - - void save_ram() { if (m_cart && m_cart->get_ram_size()) m_cart->save_ram(); } + static int get_cart_type(u32 len); // reading and writing - uint8_t read_cart(offs_t offset); - void write_cart(offs_t offset, uint8_t data); - void write_bank(uint8_t data); + void write_bank(u8 data); protected: // device_t implementation @@ -106,9 +57,33 @@ protected: int m_type; device_scv_cart_interface *m_cart; + optional_address_space m_address_space; }; +// ======================> device_scv_cart_interface + +class device_scv_cart_interface : public device_interface +{ +public: + // construction/destruction + virtual ~device_scv_cart_interface(); + + virtual void install_memory_handlers(address_space *space) { } + virtual void write_bank(u8 data) { } + + void savestate_ram(); + +protected: + device_scv_cart_interface(const machine_config &mconfig, device_t &device); + + memory_region *cart_rom_region() { return m_slot ? m_slot->memregion("rom") : nullptr; } + memory_region *cart_ram_region() { return m_slot ? m_slot->memregion("ram") : nullptr; } + +private: + scv_cart_slot_device *const m_slot; +}; + // device type definition DECLARE_DEVICE_TYPE(SCV_CART_SLOT, scv_cart_slot_device) diff --git a/src/devices/sound/upd1771.cpp b/src/devices/sound/upd1771.cpp index b08ced8779f..71f50b4e794 100644 --- a/src/devices/sound/upd1771.cpp +++ b/src/devices/sound/upd1771.cpp @@ -287,7 +287,7 @@ void upd1771c_device::device_reset() m_pc3 = 0; m_t_tpos = 0; m_t_ppos = 0; - m_state = 0; + m_state = STATE_SILENCE; m_nw_tpos = 0; memset(m_n_value, 0x00, sizeof(m_n_value)); memset(m_n_ppos, 0x00, sizeof(m_n_ppos)); @@ -475,6 +475,7 @@ void upd1771c_device::pcm_write(int state) logerror("upd1771_pc3 change!: state = %d\n", state); m_index = 0; m_packet[0] = 0; + m_state = STATE_SILENCE; } m_pc3 = state; diff --git a/src/mame/epoch/scv.cpp b/src/mame/epoch/scv.cpp index 1ac87f401e2..7efb0c5c1cf 100644 --- a/src/mame/epoch/scv.cpp +++ b/src/mame/epoch/scv.cpp @@ -4,6 +4,11 @@ Driver for Epoch Super Cassette Vision +TODO: +- adpcm playback by upd1771, needed for star speeder. +- verify video clock in European units. +- verify raw video parameters. + ***************************************************************************/ #include "emu.h" @@ -44,28 +49,27 @@ protected: TIMER_CALLBACK_MEMBER(vblank_update); private: - void porta_w(uint8_t data); - uint8_t portb_r(); - uint8_t portc_r(); - void portc_w(uint8_t data); - void upd1771_ack_w(int state); void scv_palette(palette_device &palette) const; - uint32_t screen_update_scv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + u32 screen_update_scv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void plot_sprite_part(bitmap_ind16 &bitmap, uint8_t x, uint8_t y, uint8_t pat, uint8_t col, uint8_t screen_sprite_start_line); - void draw_sprite(bitmap_ind16 &bitmap, uint8_t x, uint8_t y, uint8_t tile_idx, uint8_t col, uint8_t left, uint8_t right, uint8_t top, uint8_t bottom, uint8_t clip_y, uint8_t screen_sprite_start_line); - void draw_text(bitmap_ind16 &bitmap, uint8_t x, uint8_t y, uint8_t *char_data, uint8_t fg, uint8_t bg); - void draw_semi_graph(bitmap_ind16 &bitmap, uint8_t x, uint8_t y, uint8_t data, uint8_t fg); - void draw_block_graph(bitmap_ind16 &bitmap, uint8_t x, uint8_t y, uint8_t col); + void draw_sprite_part(bitmap_ind16 &bitmap, u8 x, u8 y, u8 pat, u8 col, u8 screen_sprite_start_line); + void draw_sprite(bitmap_ind16 &bitmap, u8 x, u8 y, u8 tile_idx, u8 col, bool left, bool right, bool top, bool bottom, u8 clip_y, u8 screen_sprite_start_line); + void draw_sprites(bitmap_ind16 &bitmap); + void draw_text(bitmap_ind16 &bitmap, u8 x, u8 y, u8 *char_data, u8 fg, uint8_t bg); + void draw_semi_graph(bitmap_ind16 &bitmap, u8 x, u8 y, u8 data, u8 fg); + void draw_block_graph(bitmap_ind16 &bitmap, u8 x, u8 y, u8 col); void scv_mem(address_map &map) ATTR_COLD; - uint8_t m_porta; - uint8_t m_portc; + static const u8 s_spr_2col_lut0[16]; + static const u8 s_spr_2col_lut1[16]; + + u8 m_porta; + u8 m_portc; emu_timer *m_vb_timer; - required_shared_ptr m_videoram; - required_device m_maincpu; + required_shared_ptr m_videoram; + required_device m_maincpu; required_device m_screen; required_device m_upd1771c; required_device m_cart; @@ -75,142 +79,108 @@ private: }; +const u8 scv_state::s_spr_2col_lut0[16] = {0, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 1, 1}; +const u8 scv_state::s_spr_2col_lut1[16] = {0, 1, 8, 11, 2, 3, 10, 9, 4, 5, 12, 13, 6, 7, 14, 15}; + + void scv_state::scv_mem(address_map &map) { map(0x0000, 0x0fff).rom(); // BIOS - map(0x2000, 0x3403).ram().share("videoram"); // VRAM + 4 registers + map(0x2000, 0x3403).ram().share(m_videoram); // VRAM + 4 registers map(0x3600, 0x3600).w(m_upd1771c, FUNC(upd1771c_device::write)); - map(0x8000, 0xff7f).rw(m_cart, FUNC(scv_cart_slot_device::read_cart), FUNC(scv_cart_slot_device::write_cart)); // cartridge + // 8000 - ff7f - Cartridge + // ff80 - ffff - CPU internal RAM } -static INPUT_PORTS_START( scv ) - PORT_START( "PA.0" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_8WAY - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_8WAY - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) +static INPUT_PORTS_START(scv) + PORT_START("PA.0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_PLAYER(1) PORT_8WAY + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_PLAYER(1) PORT_8WAY + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_PLAYER(2) PORT_8WAY + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_PLAYER(2) PORT_8WAY + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(2) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_START( "PA.1" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_8WAY - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_8WAY - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_START("PA.1" ) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_PLAYER(1) PORT_8WAY + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_PLAYER(1) PORT_8WAY + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(1) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_PLAYER(2) PORT_8WAY + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_PLAYER(2) PORT_8WAY + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(2) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_START( "PA.2" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("0") PORT_CODE(KEYCODE_0_PAD) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("1") PORT_CODE(KEYCODE_1_PAD) + PORT_START("PA.2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("0") PORT_CODE(KEYCODE_0_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("1") PORT_CODE(KEYCODE_1_PAD) - PORT_START( "PA.3" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("2") PORT_CODE(KEYCODE_2_PAD) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("3") PORT_CODE(KEYCODE_3_PAD) + PORT_START("PA.3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("2") PORT_CODE(KEYCODE_2_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("3") PORT_CODE(KEYCODE_3_PAD) - PORT_START( "PA.4" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("4") PORT_CODE(KEYCODE_4_PAD) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("5") PORT_CODE(KEYCODE_5_PAD) + PORT_START("PA.4") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("4") PORT_CODE(KEYCODE_4_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("5") PORT_CODE(KEYCODE_5_PAD) - PORT_START( "PA.5" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("6") PORT_CODE(KEYCODE_6_PAD) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("7") PORT_CODE(KEYCODE_7_PAD) + PORT_START("PA.5") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("6") PORT_CODE(KEYCODE_6_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("7") PORT_CODE(KEYCODE_7_PAD) - PORT_START( "PA.6" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("8") PORT_CODE(KEYCODE_8_PAD) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("9") PORT_CODE(KEYCODE_9_PAD) + PORT_START("PA.6") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("8") PORT_CODE(KEYCODE_8_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("9") PORT_CODE(KEYCODE_9_PAD) - PORT_START( "PA.7" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("Cl") PORT_CODE(KEYCODE_MINUS_PAD) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("En") PORT_CODE(KEYCODE_PLUS_PAD) + PORT_START("PA.7") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Cl") PORT_CODE(KEYCODE_MINUS_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("En") PORT_CODE(KEYCODE_PLUS_PAD) - PORT_START( "PC0" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME(DEF_STR(Pause)) PORT_CODE(KEYCODE_O) + PORT_START("PC0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME(DEF_STR(Pause)) PORT_CODE(KEYCODE_O) INPUT_PORTS_END -void scv_state::porta_w(uint8_t data) -{ - m_porta = data; -} - - -uint8_t scv_state::portb_r() -{ - uint8_t data = 0xff; - - for (int i = 0; i < 8; i++) - { - if (!BIT(m_porta, i)) - data &= m_pa[i]->read(); - } - - return data; -} - - -uint8_t scv_state::portc_r() -{ - uint8_t data = m_portc; - - data = (data & 0xfe) | (m_pc0->read() & 0x01); - - return data; -} - - -void scv_state::portc_w(uint8_t data) -{ - //logerror("%04x: scv_portc_w: data = 0x%02x\n", m_maincpu->pc(), data ); - m_portc = data; - m_cart->write_bank(m_portc); - m_upd1771c->pcm_write(m_portc & 0x08); -} - - void scv_state::scv_palette(palette_device &palette) const { /* @@ -263,11 +233,11 @@ void scv_state::scv_palette(palette_device &palette) const } -TIMER_CALLBACK_MEMBER( scv_state::vblank_update ) +TIMER_CALLBACK_MEMBER(scv_state::vblank_update) { int vpos = m_screen->vpos(); - switch ( vpos ) + switch (vpos) { case 240: m_maincpu->set_input_line(UPD7810_INTF2, ASSERT_LINE); @@ -281,316 +251,241 @@ TIMER_CALLBACK_MEMBER( scv_state::vblank_update ) } -inline void scv_state::plot_sprite_part( bitmap_ind16 &bitmap, uint8_t x, uint8_t y, uint8_t pat, uint8_t col, uint8_t screen_sprite_start_line ) +void scv_state::draw_sprite_part(bitmap_ind16 &bitmap, u8 x, u8 y, u8 pat, u8 col, u8 screen_sprite_start_line) { if ((x >= 4) && ((y + 2) >= screen_sprite_start_line)) { x -= 4; - if (pat & 0x08) + if (BIT(pat, 3)) bitmap.pix(y + 2, x) = col; - if (pat & 0x04 && x < 255 ) + if (BIT(pat, 2) && x < 255) bitmap.pix(y + 2, x + 1) = col; - if (pat & 0x02 && x < 254) + if (BIT(pat, 1) && x < 254) bitmap.pix(y + 2, x + 2) = col; - if (pat & 0x01 && x < 253) + if (BIT(pat, 0) && x < 253) bitmap.pix(y + 2, x + 3) = col; } } -inline void scv_state::draw_sprite( bitmap_ind16 &bitmap, uint8_t x, uint8_t y, uint8_t tile_idx, uint8_t col, uint8_t left, uint8_t right, uint8_t top, uint8_t bottom, uint8_t clip_y, uint8_t screen_sprite_start_line ) +void scv_state::draw_sprite(bitmap_ind16 &bitmap, u8 x, u8 y, u8 tile_idx, u8 col, bool left, bool right, bool top, bool bottom, u8 clip_y, u8 screen_sprite_start_line) { y += clip_y * 2; for (int j = clip_y * 4; j < 32; j += 4, y += 2) { - uint8_t const pat0 = m_videoram[tile_idx * 32 + j + 0]; - uint8_t const pat1 = m_videoram[tile_idx * 32 + j + 1]; - uint8_t const pat2 = m_videoram[tile_idx * 32 + j + 2]; - uint8_t const pat3 = m_videoram[tile_idx * 32 + j + 3]; - if ((top && (j < 16)) || (bottom && (j >= 16))) { if (left) { - plot_sprite_part(bitmap, x , y, pat0 >> 4, col, screen_sprite_start_line); - plot_sprite_part(bitmap, x + 4, y, pat1 >> 4, col, screen_sprite_start_line); - } - if (right) - { - plot_sprite_part(bitmap, x + 8, y, pat2 >> 4, col, screen_sprite_start_line); - plot_sprite_part(bitmap, x + 12, y, pat3 >> 4, col, screen_sprite_start_line); - } + const u8 pat0 = m_videoram[tile_idx * 32 + j + 0]; + const u8 pat1 = m_videoram[tile_idx * 32 + j + 1]; - if (left) - { - plot_sprite_part(bitmap, x , y + 1, pat0 & 0x0f, col, screen_sprite_start_line); - plot_sprite_part(bitmap, x + 4, y + 1, pat1 & 0x0f, col, screen_sprite_start_line); + draw_sprite_part(bitmap, x , y, pat0 >> 4, col, screen_sprite_start_line); + draw_sprite_part(bitmap, x + 4, y, pat1 >> 4, col, screen_sprite_start_line); + draw_sprite_part(bitmap, x , y + 1, pat0 & 0x0f, col, screen_sprite_start_line); + draw_sprite_part(bitmap, x + 4, y + 1, pat1 & 0x0f, col, screen_sprite_start_line); } if (right) { - plot_sprite_part(bitmap, x + 8, y + 1, pat2 & 0x0f, col, screen_sprite_start_line); - plot_sprite_part(bitmap, x + 12, y + 1, pat3 & 0x0f, col, screen_sprite_start_line); + const u8 pat2 = m_videoram[tile_idx * 32 + j + 2]; + const u8 pat3 = m_videoram[tile_idx * 32 + j + 3]; + + draw_sprite_part(bitmap, x + 8, y, pat2 >> 4, col, screen_sprite_start_line); + draw_sprite_part(bitmap, x + 12, y, pat3 >> 4, col, screen_sprite_start_line); + draw_sprite_part(bitmap, x + 8, y + 1, pat2 & 0x0f, col, screen_sprite_start_line); + draw_sprite_part(bitmap, x + 12, y + 1, pat3 & 0x0f, col, screen_sprite_start_line); } } } } -inline void scv_state::draw_text( bitmap_ind16 &bitmap, uint8_t x, uint8_t y, uint8_t *char_data, uint8_t fg, uint8_t bg ) +void scv_state::draw_sprites(bitmap_ind16 &bitmap) { - for ( int i = 0; i < 8; i++ ) + const u8 screen_start_sprite_line = (((m_videoram[0x1400] & 0xf7) == 0x17) && ((m_videoram[0x1402] & 0xef) == 0x4f)) ? 21 + 32 : 0; + + for (int i = 0; i < 128; i++) { - uint8_t const d = char_data[i]; + u8 spr_y = m_videoram[0x1200 + i * 4] & 0xfe; + u8 y_32 = BIT(m_videoram[0x1200 + i * 4], 0); // Xx32 sprite + u8 clip = m_videoram[0x1201 + i * 4] >> 4; + u8 col = m_videoram[0x1201 + i * 4] & 0x0f; + u8 spr_x = m_videoram[0x1202 + i * 4] & 0xfe; + u8 x_32 = BIT(m_videoram[0x1202 + i * 4], 0); // 32xX sprite + u8 tile_idx = m_videoram[0x1203 + i * 4] & 0x7f; + const bool half = BIT(m_videoram[0x1203 + i * 4], 7); + bool left = true; + bool right = true; + bool top = true; + bool bottom = true; - bitmap.pix(y + i, x + 0 ) = ( d & 0x80 ) ? fg : bg; - bitmap.pix(y + i, x + 1 ) = ( d & 0x40 ) ? fg : bg; - bitmap.pix(y + i, x + 2 ) = ( d & 0x20 ) ? fg : bg; - bitmap.pix(y + i, x + 3 ) = ( d & 0x10 ) ? fg : bg; - bitmap.pix(y + i, x + 4 ) = ( d & 0x08 ) ? fg : bg; - bitmap.pix(y + i, x + 5 ) = ( d & 0x04 ) ? fg : bg; - bitmap.pix(y + i, x + 6 ) = ( d & 0x02 ) ? fg : bg; - bitmap.pix(y + i, x + 7 ) = ( d & 0x01 ) ? fg : bg; - } + if (!col || !spr_y) + continue; - for ( int i = 8; i < 16; i++ ) - { - bitmap.pix(y + i, x + 0 ) = bg; - bitmap.pix(y + i, x + 1 ) = bg; - bitmap.pix(y + i, x + 2 ) = bg; - bitmap.pix(y + i, x + 3 ) = bg; - bitmap.pix(y + i, x + 4 ) = bg; - bitmap.pix(y + i, x + 5 ) = bg; - bitmap.pix(y + i, x + 6 ) = bg; - bitmap.pix(y + i, x + 7 ) = bg; - } - -} - - -inline void scv_state::draw_semi_graph( bitmap_ind16 &bitmap, uint8_t x, uint8_t y, uint8_t data, uint8_t fg ) -{ - if ( ! data ) - return; - - for ( int i = 0; i < 4; i++ ) - { - bitmap.pix(y + i, x + 0) = fg; - bitmap.pix(y + i, x + 1) = fg; - bitmap.pix(y + i, x + 2) = fg; - bitmap.pix(y + i, x + 3) = fg; - } -} - - -inline void scv_state::draw_block_graph( bitmap_ind16 &bitmap, uint8_t x, uint8_t y, uint8_t col ) -{ - for ( int i = 0; i < 8; i++ ) - { - bitmap.pix(y + i, x + 0) = col; - bitmap.pix(y + i, x + 1) = col; - bitmap.pix(y + i, x + 2) = col; - bitmap.pix(y + i, x + 3) = col; - bitmap.pix(y + i, x + 4) = col; - bitmap.pix(y + i, x + 5) = col; - bitmap.pix(y + i, x + 6) = col; - bitmap.pix(y + i, x + 7) = col; - } -} - - -uint32_t scv_state::screen_update_scv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - int x, y; - uint8_t fg = m_videoram[0x1403] >> 4; - uint8_t bg = m_videoram[0x1403] & 0x0f; - uint8_t gr_fg = m_videoram[0x1401] >> 4; - uint8_t gr_bg = m_videoram[0x1401] & 0x0f; - int clip_x = ( m_videoram[0x1402] & 0x0f ) * 2; - int clip_y = m_videoram[0x1402] >> 4; - - /* Clear the screen */ - bitmap.fill(gr_bg , cliprect); - - /* Draw background */ - for ( y = 0; y < 16; y++ ) - { - int text_y = 0; - - if ( y < clip_y ) + if (half) { - text_y = ( m_videoram[0x1400] & 0x80 ) ? 0 : 1; + if (BIT(tile_idx, 6)) + { + if (y_32) + { + spr_y -= 8; + top = false; + y_32 = 0; + } + else + bottom = false; + } + if (x_32) + { + spr_x -= 8; + left = false; + x_32 = 0; + } + else + right = false; + } + + if (BIT(m_videoram[0x1400], 5) && BIT(i, 5)) + { + // 2 color sprite handling + draw_sprite(bitmap, spr_x, spr_y, tile_idx, col, left, right, top, bottom, clip, screen_start_sprite_line); + if (x_32 || y_32) + { + col = BIT(i, 4) ? s_spr_2col_lut1[col] : s_spr_2col_lut0[col]; + tile_idx ^= (8 * x_32 + y_32); + + draw_sprite(bitmap, spr_x, spr_y, tile_idx, col, left, right, top, bottom, clip, screen_start_sprite_line); + } } else { - text_y = ( m_videoram[0x1400] & 0x80 ) ? 1 : 0; - } + // regular sprite handling + draw_sprite(bitmap, spr_x, spr_y, tile_idx, col, left, right, top, bottom, clip, screen_start_sprite_line); + if (x_32) + draw_sprite(bitmap, spr_x + 16, spr_y, tile_idx | 8, col, 1, 1, top, bottom, clip, screen_start_sprite_line); - for ( x = 0; x < 32; x++ ) - { - int text_x = 0; - uint8_t d = m_videoram[ 0x1000 + y * 32 + x ]; - - if ( x < clip_x ) + if (y_32) { - text_x = ( m_videoram[0x1400] & 0x40 ) ? 0 : 1; - } - else - { - text_x = ( m_videoram[0x1400] & 0x40 ) ? 1 : 0; - } - - if ( text_x && text_y ) - { - /* Text mode */ - uint8_t *char_data = m_charrom->base() + ( d & 0x7f ) * 8; - draw_text( bitmap, x * 8, y * 16, char_data, fg, bg ); - } - else - { - switch ( m_videoram[0x1400] & 0x03 ) - { - case 0x01: /* Semi graphics mode */ - draw_semi_graph( bitmap, x * 8 , y * 16 , d & 0x80, gr_fg ); - draw_semi_graph( bitmap, x * 8 + 4, y * 16 , d & 0x40, gr_fg ); - draw_semi_graph( bitmap, x * 8 , y * 16 + 4, d & 0x20, gr_fg ); - draw_semi_graph( bitmap, x * 8 + 4, y * 16 + 4, d & 0x10, gr_fg ); - draw_semi_graph( bitmap, x * 8 , y * 16 + 8, d & 0x08, gr_fg ); - draw_semi_graph( bitmap, x * 8 + 4, y * 16 + 8, d & 0x04, gr_fg ); - draw_semi_graph( bitmap, x * 8 , y * 16 + 12, d & 0x02, gr_fg ); - draw_semi_graph( bitmap, x * 8 + 4, y * 16 + 12, d & 0x01, gr_fg ); - break; - - case 0x03: /* Block graphics mode */ - draw_block_graph( bitmap, x * 8, y * 16 , d >> 4 ); - draw_block_graph( bitmap, x * 8, y * 16 + 8, d & 0x0f ); - break; - - default: /* Otherwise draw nothing? */ - break; - } + clip = BIT(clip, 3) ? (clip & 0x07) : 0; + draw_sprite(bitmap, spr_x, spr_y + 16, tile_idx | 1, col, left, right, 1, 1, clip, screen_start_sprite_line); + if (x_32) + draw_sprite(bitmap, spr_x + 16, spr_y + 16, tile_idx | 9, col, 1, 1, 1, 1, clip, screen_start_sprite_line); } } } +} - /* Draw sprites if enabled */ - if ( m_videoram[0x1400] & 0x10 ) + +void scv_state::draw_text(bitmap_ind16 &bitmap, u8 x, u8 y, u8 *char_data, u8 fg, u8 bg) +{ + for (int i = 0; i < 8; i++) { - uint8_t screen_start_sprite_line = ( ( ( m_videoram[0x1400] & 0xf7 ) == 0x17 ) && ( ( m_videoram[0x1402] & 0xef ) == 0x4f ) ) ? 21 + 32 : 0 ; - int i; + const u8 d = char_data[i]; - for ( i = 0; i < 128; i++ ) + for (int j = 0; j < 8; j++) + bitmap.pix(y + i, x + j) = (BIT(d, 7 - j)) ? fg : bg; + } + + for (int i = 8; i < 16; i++) + for (int j = 0; j < 8; j++) + bitmap.pix(y + i, x + j) = bg; +} + + +void scv_state::draw_semi_graph(bitmap_ind16 &bitmap, u8 x, u8 y, u8 data, u8 fg) +{ + if (!data) + return; + + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + bitmap.pix(y + i, x + j) = fg; +} + + +void scv_state::draw_block_graph(bitmap_ind16 &bitmap, u8 x, u8 y, u8 col) +{ + if (!col) + return; + + for (int i = 0; i < 8; i++) + for (int j = 0; j < 8; j++) + bitmap.pix(y + i, x + j) = col; +} + + +u32 scv_state::screen_update_scv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + const u8 fg = m_videoram[0x1403] >> 4; + const u8 bg = m_videoram[0x1403] & 0x0f; + const u8 gr_fg = m_videoram[0x1401] >> 4; + const u8 gr_bg = m_videoram[0x1401] & 0x0f; + const int clip_x = (m_videoram[0x1402] & 0x0f) * 2; + const int clip_y = m_videoram[0x1402] >> 4; + + // Clear the screen + bitmap.fill(gr_bg, cliprect); + + // Draw background + for (int y = 0; y < 16; y++) + { + const bool text_y = (y < clip_y) ? !BIT(m_videoram[0x1400], 7) : BIT(m_videoram[0x1400], 7); + + for (int x = 0; x < 32; x++) { - uint8_t spr_y = m_videoram[ 0x1200 + i * 4 ] & 0xfe; - uint8_t y_32 = m_videoram[ 0x1200 + i * 4 ] & 0x01; /* Xx32 sprite */ - uint8_t clip = m_videoram[ 0x1201 + i * 4 ] >> 4; - uint8_t col = m_videoram[ 0x1201 + i * 4 ] & 0x0f; - uint8_t spr_x = m_videoram[ 0x1202 + i * 4 ] & 0xfe; - uint8_t x_32 = m_videoram[ 0x1202 + i * 4 ] & 0x01; /* 32xX sprite */ - uint8_t tile_idx = m_videoram[ 0x1203 + i * 4 ] & 0x7f; - uint8_t half = m_videoram[ 0x1203 + i * 4] & 0x80; - uint8_t left = 1; - uint8_t right = 1; - uint8_t top = 1; - uint8_t bottom = 1; + const bool text_x = (x < clip_x) ? !BIT(m_videoram[0x1400], 6) : BIT(m_videoram[0x1400], 6); + const u8 d = m_videoram[0x1000 + y * 32 + x]; - if ( !col ) + if (text_x && text_y) { - continue; - } - - if ( !spr_y ) - { - continue; - } - - if ( half ) - { - if ( tile_idx & 0x40 ) - { - if ( y_32 ) - { - spr_y -= 8; - top = 0; - bottom = 1; - y_32 = 0; - } - else - { - top = 1; - bottom = 0; - } - } - if ( x_32 ) - { - spr_x -= 8; - left = 0; - right = 1; - x_32 = 0; - } - else - { - left = 1; - right = 0; - } - } - - /* Check if 2 color sprites are enabled */ - if ( ( m_videoram[0x1400] & 0x20 ) && ( i & 0x20 ) ) - { - /* 2 color sprite handling */ - draw_sprite( bitmap, spr_x, spr_y, tile_idx, col, left, right, top, bottom, clip, screen_start_sprite_line ); - if ( x_32 || y_32 ) - { - static const uint8_t spr_2col_lut0[16] = { 0, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 1, 1 }; - static const uint8_t spr_2col_lut1[16] = { 0, 1, 8, 11, 2, 3, 10, 9, 4, 5, 12, 13, 6, 7, 14, 15 }; - - draw_sprite( bitmap, spr_x, spr_y, tile_idx ^ ( 8 * x_32 + y_32 ), ( i & 0x40 ) ? spr_2col_lut1[col] : spr_2col_lut0[col], left, right, top, bottom, clip, screen_start_sprite_line ); - } + // Text mode + uint8_t *char_data = m_charrom->base() + (d & 0x7f) * 8; + draw_text(bitmap, x * 8, y * 16, char_data, fg, bg); } else { - /* regular sprite handling */ - draw_sprite( bitmap, spr_x, spr_y, tile_idx, col, left, right, top, bottom, clip, screen_start_sprite_line ); - if ( x_32 ) + switch (m_videoram[0x1400] & 0x03) { - draw_sprite( bitmap, spr_x + 16, spr_y, tile_idx | 8, col, 1, 1, top, bottom, clip, screen_start_sprite_line ); - } + case 0x01: // Semi graphics mode + draw_semi_graph(bitmap, x * 8 , y * 16 , d & 0x80, gr_fg); + draw_semi_graph(bitmap, x * 8 + 4, y * 16 , d & 0x40, gr_fg); + draw_semi_graph(bitmap, x * 8 , y * 16 + 4, d & 0x20, gr_fg); + draw_semi_graph(bitmap, x * 8 + 4, y * 16 + 4, d & 0x10, gr_fg); + draw_semi_graph(bitmap, x * 8 , y * 16 + 8, d & 0x08, gr_fg); + draw_semi_graph(bitmap, x * 8 + 4, y * 16 + 8, d & 0x04, gr_fg); + draw_semi_graph(bitmap, x * 8 , y * 16 + 12, d & 0x02, gr_fg); + draw_semi_graph(bitmap, x * 8 + 4, y * 16 + 12, d & 0x01, gr_fg); + break; - if ( y_32 ) - { - clip = ( clip & 0x08 ) ? ( clip & 0x07 ) : 0; - draw_sprite( bitmap, spr_x, spr_y + 16, tile_idx | 1, col, left, right, 1, 1, clip, screen_start_sprite_line ); - if ( x_32 ) - { - draw_sprite( bitmap, spr_x + 16, spr_y + 16, tile_idx | 9, col, 1, 1, 1, 1, clip, screen_start_sprite_line ); - } + case 0x03: // Block graphics mode + draw_block_graph(bitmap, x * 8, y * 16 , d >> 4); + draw_block_graph(bitmap, x * 8, y * 16 + 8, d & 0x0f); + break; + + default: // Otherwise draw nothing? + break; } } } } + if (BIT(m_videoram[0x1400], 4)) + draw_sprites(bitmap); + return 0; } -void scv_state::upd1771_ack_w(int state) -{ - m_maincpu->set_input_line(UPD7810_INTF1, (state) ? ASSERT_LINE : CLEAR_LINE); -} - void scv_state::machine_start() { m_vb_timer = timer_alloc(FUNC(scv_state::vblank_update), this); save_item(NAME(m_porta)); save_item(NAME(m_portc)); - if (m_cart->exists()) - m_cart->save_ram(); - } @@ -600,22 +495,22 @@ void scv_state::machine_reset() } -/* F4 Character Displayer */ +// F4 Character Displayer static const gfx_layout scv_charlayout = { - 8, 8, /* 8 x 8 characters */ - 128, /* 128 characters */ - 1, /* 1 bits per pixel */ - { 0 }, /* no bitplanes */ - /* x offsets */ - { 0, 1, 2, 3, 4, 5, 6, 7 }, - /* y offsets */ - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 8*8 /* every char takes 8 bytes */ + 8, 8, // 8 x 8 characters + 128, // 128 characters + 1, // 1 bits per pixel + {0}, // no bitplanes + // x offsets + {0, 1, 2, 3, 4, 5, 6, 7}, + // y offsets + {0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8}, + 8*8 // every char takes 8 bytes }; -static GFXDECODE_START( gfx_scv ) - GFXDECODE_ENTRY( "charrom", 0x0000, scv_charlayout, 0, 8 ) +static GFXDECODE_START(gfx_scv) + GFXDECODE_ENTRY("charrom", 0x0000, scv_charlayout, 0, 8) GFXDECODE_END @@ -632,31 +527,46 @@ static void scv_cart(device_slot_interface &device) void scv_state::scv(machine_config &config) { - upd7801_device &upd(UPD7801(config, m_maincpu, 4_MHz_XTAL)); - upd.set_addrmap(AS_PROGRAM, &scv_state::scv_mem); - upd.pa_out_cb().set(FUNC(scv_state::porta_w)); - upd.pb_in_cb().set(FUNC(scv_state::portb_r)); - upd.pc_in_cb().set(FUNC(scv_state::portc_r)); - upd.pc_out_cb().set(FUNC(scv_state::portc_w)); + UPD7801(config, m_maincpu, 4_MHz_XTAL); + m_maincpu->set_addrmap(AS_PROGRAM, &scv_state::scv_mem); + m_maincpu->pa_out_cb().set([this] (u8 data) { m_porta = data; }); + m_maincpu->pb_in_cb().set([this] () { + u8 data = 0xff; - /* Video chip is EPOCH TV-1 */ + for (int i = 0; i < 8; i++) + if (!BIT(m_porta, i)) + data &= m_pa[i]->read(); + + return data; + }); + m_maincpu->pc_in_cb().set([this] () { + return (m_pc0->read() & 0x01); + }); + m_maincpu->pc_out_cb().set([this] (u8 data) { + m_portc = data; + m_cart->write_bank(m_portc); // Only bits 5 & 6 are exposed to the cartridge? + m_upd1771c->pcm_write(BIT(m_portc, 3)); + }); + + // Video chip is EPOCH TV-1 SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_raw(XTAL(14'318'181)/2, 456, 24, 24+192, 262, 23, 23+222); // TODO: Verify + m_screen->set_raw(XTAL(14'318'181)/2, 456, 24, 24+192, 262, 23, 23+222); // Clock verified. TODO: Verify rest of the parameters m_screen->set_screen_update(FUNC(scv_state::screen_update_scv)); m_screen->set_palette("palette"); GFXDECODE(config, "gfxdecode", "palette", gfx_scv); PALETTE(config, "palette", FUNC(scv_state::scv_palette), 16); - /* Sound is generated by UPD1771C clocked at XTAL(6'000'000) */ + // Sound is generated by UPD1771C clocked at XTAL(6'000'000) SPEAKER(config, "mono").front_center(); UPD1771C(config, m_upd1771c, 6_MHz_XTAL); - m_upd1771c->ack_handler().set(FUNC(scv_state::upd1771_ack_w)); + m_upd1771c->ack_handler().set([this] (int state) { m_maincpu->set_input_line(UPD7810_INTF1, (state) ? ASSERT_LINE : CLEAR_LINE); }); m_upd1771c->add_route(ALL_OUTPUTS, "mono", 1.00); SCV_CART_SLOT(config, m_cart, scv_cart, nullptr); + m_cart->set_address_space(m_maincpu, AS_PROGRAM); - /* Software lists */ + // Software lists SOFTWARE_LIST(config, "cart_list").set_original("scv"); } @@ -665,34 +575,32 @@ void scv_state::scv_pal(machine_config &config) { scv(config); - m_maincpu->set_clock(3780000); - // Video chip is EPOCH TV-1A - m_screen->set_raw(13.4_MHz_XTAL/2, 456, 24, 24+192, 342, 23, 23+222); // TODO: Verify + m_screen->set_raw(13.4_MHz_XTAL/2, 456, 24, 24+192, 294, 23, 23+222); // TODO: Verify clock and video parameters } -/* The same bios is used in both the NTSC and PAL versions of the console */ -ROM_START( scv ) - ROM_REGION( 0x1000, "maincpu", 0 ) - ROM_LOAD( "upd7801g.s01", 0, 0x1000, CRC(7ac06182) SHA1(6e89d1227581c76441a53d605f9e324185f1da33) ) +// The same bios is used in both the NTSC and PAL versions of the console +ROM_START(scv) + ROM_REGION(0x1000, "maincpu", 0) + ROM_LOAD("upd7801g.s01", 0, 0x1000, CRC(7ac06182) SHA1(6e89d1227581c76441a53d605f9e324185f1da33)) - ROM_REGION( 0x400, "charrom", 0 ) - ROM_LOAD( "epochtv.chr", 0, 0x400, BAD_DUMP CRC(db521533) SHA1(40b4e44838c35191f115437a14f200f052e71509) ) + ROM_REGION(0x400, "charrom", 0) + ROM_LOAD("epochtv.chr.s02", 0, 0x400, BAD_DUMP CRC(db521533) SHA1(40b4e44838c35191f115437a14f200f052e71509)) ROM_END -ROM_START( scv_pal ) - ROM_REGION( 0x1000, "maincpu", 0 ) - ROM_LOAD( "upd7801g.s01", 0, 0x1000, CRC(7ac06182) SHA1(6e89d1227581c76441a53d605f9e324185f1da33) ) +ROM_START(scv_pal) + ROM_REGION(0x1000, "maincpu", 0) + ROM_LOAD("upd7801g.s01", 0, 0x1000, CRC(7ac06182) SHA1(6e89d1227581c76441a53d605f9e324185f1da33)) - ROM_REGION( 0x400, "charrom", 0 ) - ROM_LOAD( "epochtv.chr", 0, 0x400, BAD_DUMP CRC(db521533) SHA1(40b4e44838c35191f115437a14f200f052e71509) ) + ROM_REGION(0x400, "charrom", 0) + ROM_LOAD("epochtv.chr.s02", 0, 0x400, BAD_DUMP CRC(db521533) SHA1(40b4e44838c35191f115437a14f200f052e71509)) ROM_END } // anonymous namespace -/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -CONS( 1984, scv, 0, 0, scv, scv, scv_state, empty_init, "Epoch", "Super Cassette Vision", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -CONS( 198?, scv_pal, scv, 0, scv_pal, scv, scv_state, empty_init, "Yeno", "Super Cassette Vision (PAL)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ +CONS(1984, scv, 0, 0, scv, scv, scv_state, empty_init, "Epoch", "Super Cassette Vision", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE) +CONS(198?, scv_pal, scv, 0, scv_pal, scv, scv_state, empty_init, "Yeno", "Super Cassette Vision (PAL)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE)