From c23a22d77be83ff1dbaff36f1c9f7acf0d47dde5 Mon Sep 17 00:00:00 2001 From: fulivi Date: Sat, 17 Aug 2024 16:57:24 +0200 Subject: [PATCH] HP98X6: added support for option ROMs (#12661) --- hash/hp98x6_rom.xml | 46 ++++++++++++++++++ src/mame/hp/hp98x6.cpp | 22 ++++++++- src/mame/hp/hp98x6_optrom.cpp | 92 +++++++++++++++++++++++++++++++++++ src/mame/hp/hp98x6_optrom.h | 46 ++++++++++++++++++ 4 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 hash/hp98x6_rom.xml create mode 100644 src/mame/hp/hp98x6_optrom.cpp create mode 100644 src/mame/hp/hp98x6_optrom.h diff --git a/hash/hp98x6_rom.xml b/hash/hp98x6_rom.xml new file mode 100644 index 0000000000000..1f76cda4bf43f --- /dev/null +++ b/hash/hp98x6_rom.xml @@ -0,0 +1,46 @@ + + + + + + + BASIC 4.0 + 1985 + Hewlett-Packard + + + + + + + + + + BASIC 5.1 + 1988 + Hewlett-Packard + + + + + + + + + + SSS HPL+II + 1992 + Structured Software Systems + + + + + + + + diff --git a/src/mame/hp/hp98x6.cpp b/src/mame/hp/hp98x6.cpp index 62131e52d42d1..c1f04569d50cb 100644 --- a/src/mame/hp/hp98x6.cpp +++ b/src/mame/hp/hp98x6.cpp @@ -22,6 +22,7 @@ // | Knob | * | * | * | * | // | Beeper | * | * | * | * | // | ID PROM | * | * | * | * | +// | Option ROMs | * | * | * | * | // | B/W 80x25 text video w/ attributes | * | | * | | // | B/W 50x25 text video w/ attributes | | * | | | // | B/W 400x300 graphic video | * | * | | | @@ -37,7 +38,6 @@ // // What's not in for all the models: // - Expansion cards -// - Option ROMs // // Main references: // - Olivier De Smet's standalone emulator: @@ -47,6 +47,7 @@ #include "emu.h" +#include "hp98x6_optrom.h" #include "hp98x6_upi.h" #include "bus/ieee488/ieee488.h" @@ -63,6 +64,7 @@ #include "emupal.h" #include "screen.h" +#include "softlist_dev.h" // Debugging #define LOG_FDC_MASK (LOG_GENERAL << 1) @@ -137,6 +139,7 @@ class hp98x6_base_state : public driver_device , m_upi(*this, "upi") , m_hpib(*this, "hpib") , m_chargen(*this, "chargen") + , m_rom_drawers(*this, "drawer%u", 0U) { } @@ -161,6 +164,8 @@ class hp98x6_base_state : public driver_device // Character generator required_region_ptr m_chargen; + required_device_array m_rom_drawers; + bool m_hsync_en; bool m_graphic_en; bool m_hpib_irq; @@ -176,7 +181,13 @@ void hp98x6_base_state::machine_start() save_item(NAME(m_hpib_dma_en)); save_item(NAME(m_upi_irq7)); - m_cpu->space(AS_PROGRAM).install_ram(0x1000000 - m_ram->size(), 0xffffff, m_ram->pointer()); + auto space = &m_cpu->space(AS_PROGRAM); + + space->install_ram(0x1000000 - m_ram->size(), 0xffffff, m_ram->pointer()); + + for (auto& finder : m_rom_drawers) { + finder->install_handlers(space); + } } void hp98x6_base_state::machine_reset() @@ -228,6 +239,13 @@ void hp98x6_base_state::hp98x6_base(machine_config &config, unsigned dot_clock, ieee.ren_callback().set(m_hpib , FUNC(tms9914_device::ren_w)); IEEE488_SLOT(config, "ieee_dev", 0, hp_ieee488_devices, nullptr); IEEE488_SLOT(config, "ieee_rem", 0, remote488_devices, nullptr); + + // Optional ROM slots + for (auto& finder : m_rom_drawers) { + HP98X6_OPTROM(config, finder); + } + + SOFTWARE_LIST(config, "optrom_list").set_original("hp98x6_rom"); } void hp98x6_base_state::cpu_mem_map(address_map &map) diff --git a/src/mame/hp/hp98x6_optrom.cpp b/src/mame/hp/hp98x6_optrom.cpp new file mode 100644 index 0000000000000..6bc6ac0638561 --- /dev/null +++ b/src/mame/hp/hp98x6_optrom.cpp @@ -0,0 +1,92 @@ +// license:BSD-3-Clause +// copyright-holders: F. Ulivi +/********************************************************************* + + hp98x6_optrom.cpp + + Optional ROMs for HP98x6 systems + +*********************************************************************/ + +#include "emu.h" +#include "hp98x6_optrom.h" +#include "softlist.h" + +// Debugging +#define VERBOSE 0 +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(HP98X6_OPTROM, hp98x6_optrom_device, "hp98x6_optrom", "HP98x6 optional ROM") + +struct optrom_region { + offs_t m_start; + const char *m_tag; +}; + +constexpr std::array region_tab = + {{ + { 0x100000, "rom100000" }, + { 0x80000, "rom80000" } + }}; + +// +--------------------+ +// |hp98x6_optrom_device| +// +--------------------+ +hp98x6_optrom_device::hp98x6_optrom_device(machine_config const &mconfig, char const *tag, device_t *owner) + : hp98x6_optrom_device(mconfig, tag, owner, (uint32_t)0) +{ +} + +hp98x6_optrom_device::hp98x6_optrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, HP98X6_OPTROM, tag, owner, clock) + , device_rom_image_interface(mconfig, *this) + , m_space_r(nullptr) +{ +} + +hp98x6_optrom_device::~hp98x6_optrom_device() +{ +} + +void hp98x6_optrom_device::install_handlers(address_space *space_r) +{ + m_space_r = space_r; + + for (const struct optrom_region& reg : region_tab) { + uint8_t *ptr = get_software_region(reg.m_tag); + if (ptr != nullptr) { + auto len = get_software_region_length(reg.m_tag); + LOG("%s loaded, %u long\n", reg.m_tag, len); + space_r->install_rom(reg.m_start , reg.m_start + len - 1 , ptr); + } + } +} + +void hp98x6_optrom_device::device_start() +{ +} + +std::pair hp98x6_optrom_device::call_load() +{ + LOG("hp98x6_optrom: call_load\n"); + if (!loaded_through_softlist()) { + return std::make_pair(image_error::UNSUPPORTED, "Option ROMs must be loaded from software list"); + } + + return std::make_pair(std::error_condition(), std::string()); +} + +void hp98x6_optrom_device::call_unload() +{ + LOG("hp98x6_optrom: call_unload\n"); + if (m_space_r != nullptr) { + for (const struct optrom_region& reg : region_tab) { + auto len = get_software_region_length(reg.m_tag); + if (len != 0) { + m_space_r->unmap_read(reg.m_start , reg.m_start + len - 1); + LOG("%s unloaded\n" , reg.m_tag); + } + } + } + machine().schedule_soft_reset(); +} diff --git a/src/mame/hp/hp98x6_optrom.h b/src/mame/hp/hp98x6_optrom.h new file mode 100644 index 0000000000000..44541403bd0c6 --- /dev/null +++ b/src/mame/hp/hp98x6_optrom.h @@ -0,0 +1,46 @@ +// license:BSD-3-Clause +// copyright-holders: F. Ulivi +/********************************************************************* + + hp98x6_optrom.h + + Optional ROMs for HP98x6 systems + +*********************************************************************/ +#ifndef MAME_HP_HP98X6_OPTROM_H +#define MAME_HP_HP98X6_OPTROM_H + +#pragma once + +#include "imagedev/cartrom.h" + +class hp98x6_optrom_device : public device_t, + public device_rom_image_interface +{ +public: + // construction/destruction + hp98x6_optrom_device(machine_config const &mconfig, char const *tag, device_t *owner); + hp98x6_optrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual ~hp98x6_optrom_device(); + + void install_handlers(address_space *space_r); + +protected: + // device_t implementation + virtual void device_start() override; + + // device_image_interface implementation + virtual std::pair call_load() override; + virtual void call_unload() override; + + virtual bool is_reset_on_load() const noexcept override { return true; } + virtual const char *image_interface() const noexcept override { return "hp98x6_rom"; } + virtual const char *file_extensions() const noexcept override { return "bin"; } + + address_space *m_space_r; +}; + +// device type definition +DECLARE_DEVICE_TYPE(HP98X6_OPTROM, hp98x6_optrom_device) + +#endif /* MAME_HP_HP98X6_OPTROM_H */