HP optional ROMs: address issue #5839 (#5873)

* hp80: refactored optional ROM device as requested in issue #5839

* hp9825: refactored optional ROM device as requested in issue #5839

* hp9845: refactored optional ROM device as requested in issue #5839
This commit is contained in:
fulivi 2019-11-08 03:42:09 +01:00 committed by Vas Crabb
parent 143385e2f2
commit c2a6ebd366
15 changed files with 349 additions and 577 deletions

View File

@ -3876,30 +3876,6 @@ if (BUSES["SVI_SLOT"]~=null) then
}
end
---------------------------------------------------
--
--@src/devices/bus/hp_optroms/hp_optrom.h,BUSES["HP_OPTROM"] = true
---------------------------------------------------
if (BUSES["HP_OPTROM"]~=null) then
files {
MAME_DIR .. "src/devices/bus/hp_optroms/hp_optrom.cpp",
MAME_DIR .. "src/devices/bus/hp_optroms/hp_optrom.h",
}
end
---------------------------------------------------
--
--@src/devices/bus/hp80_optroms/hp80_optrom.h,BUSES["HP80_OPTROM"] = true
---------------------------------------------------
if (BUSES["HP80_OPTROM"]~=null) then
files {
MAME_DIR .. "src/devices/bus/hp80_optroms/hp80_optrom.cpp",
MAME_DIR .. "src/devices/bus/hp80_optroms/hp80_optrom.h",
}
end
---------------------------------------------------
--
--@src/devices/bus/hp80_io/hp80_io.h,BUSES["HP80_IO"] = true
@ -3914,18 +3890,6 @@ if (BUSES["HP80_IO"]~=null) then
}
end
---------------------------------------------------
--
--@src/devices/bus/hp9825_optroms/hp9825_optrom.h,BUSES["HP9825_OPTROM"] = true
---------------------------------------------------
if (BUSES["HP9825_OPTROM"]~=null) then
files {
MAME_DIR .. "src/devices/bus/hp9825_optroms/hp9825_optrom.cpp",
MAME_DIR .. "src/devices/bus/hp9825_optroms/hp9825_optrom.h",
}
end
---------------------------------------------------
--
--@src/devices/bus/hp9845_io/hp9845_io.h,BUSES["HP9845_IO"] = true

View File

@ -808,10 +808,7 @@ BUSES["IQ151"] = true
BUSES["ISA"] = true
BUSES["ISBX"] = true
BUSES["JAKKS_GAMEKEY"] = true
BUSES["HP_OPTROM"] = true
BUSES["HP80_OPTROM"] = true
BUSES["HP80_IO"] = true
BUSES["HP9825_OPTROM"] = true
BUSES["HP9845_IO"] = true
BUSES["KC"] = true
BUSES["LPCI"] = true
@ -2402,8 +2399,14 @@ files {
MAME_DIR .. "src/mame/machine/hp48.cpp",
MAME_DIR .. "src/mame/machine/hp48_port.cpp",
MAME_DIR .. "src/mame/machine/hp48_port.h",
MAME_DIR .. "src/mame/machine/hp80_optrom.cpp",
MAME_DIR .. "src/mame/machine/hp80_optrom.h",
MAME_DIR .. "src/mame/machine/hp9825_optrom.cpp",
MAME_DIR .. "src/mame/machine/hp9825_optrom.h",
MAME_DIR .. "src/mame/machine/hp9825_tape.cpp",
MAME_DIR .. "src/mame/machine/hp9825_tape.h",
MAME_DIR .. "src/mame/machine/hp9845_optrom.cpp",
MAME_DIR .. "src/mame/machine/hp9845_optrom.h",
MAME_DIR .. "src/mame/machine/hp9845_printer.cpp",
MAME_DIR .. "src/mame/machine/hp9845_printer.h",
MAME_DIR .. "src/mame/machine/hp98x5_io_sys.cpp",

View File

@ -1,125 +0,0 @@
// license:BSD-3-Clause
// copyright-holders: F. Ulivi
/*********************************************************************
hp80_optrom.cpp
Optional ROMs for HP80 systems
*********************************************************************/
#include "emu.h"
#include "hp80_optrom.h"
#include "softlist.h"
// Debugging
#define VERBOSE 1
#include "logmacro.h"
DEFINE_DEVICE_TYPE(HP80_OPTROM_CART, hp80_optrom_cart_device, "hp80_optrom_cart", "HP80 optional ROM cartridge")
DEFINE_DEVICE_TYPE(HP80_OPTROM_SLOT, hp80_optrom_slot_device, "hp80_optrom_slot", "HP80 optional ROM slot")
// +----------------------------+
// |device_hp80_optrom_interface|
// +----------------------------+
device_hp80_optrom_interface::device_hp80_optrom_interface(const machine_config &config, device_t &device) :
device_interface(device, "hp80optrom")
{
}
// +-----------------------+
// |hp80_optrom_cart_device|
// +-----------------------+
hp80_optrom_cart_device::hp80_optrom_cart_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_hp80_optrom_interface(mconfig, *this)
{
}
hp80_optrom_cart_device::hp80_optrom_cart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
hp80_optrom_cart_device(mconfig, HP80_OPTROM_CART, tag, owner, clock)
{
}
// +-----------------------+
// |hp80_optrom_slot_device|
// +-----------------------+
hp80_optrom_slot_device::hp80_optrom_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, HP80_OPTROM_SLOT, tag, owner, clock),
device_image_interface(mconfig, *this),
device_single_card_slot_interface<device_hp80_optrom_interface>(mconfig, *this),
m_cart(nullptr),
m_select_code(0)
{
}
hp80_optrom_slot_device::~hp80_optrom_slot_device()
{
}
void hp80_optrom_slot_device::install_read_handler(address_space& space)
{
if (loaded_through_softlist()) {
offs_t start = (offs_t)m_select_code * HP80_OPTROM_SIZE;
space.install_rom(start , start + HP80_OPTROM_SIZE - 1 , get_software_region("rom"));
}
}
void hp80_optrom_slot_device::device_start()
{
m_cart = get_card_device();
}
image_init_result hp80_optrom_slot_device::call_load()
{
LOG("hp80_optrom: call_load\n");
if (m_cart == nullptr || !loaded_through_softlist()) {
LOG("hp80_optrom: must be loaded from sw list\n");
return image_init_result::FAIL;
}
const char *sc_feature = get_feature("sc");
if (sc_feature == nullptr) {
LOG("hp80_optrom: no 'sc' feature\n");
return image_init_result::FAIL;
}
unsigned sc;
if (sc_feature[ 0 ] != '0' || sc_feature[ 1 ] != 'x' || sscanf(&sc_feature[ 2 ] , "%x" , &sc) != 1) {
LOG("hp80_optrom: can't parse 'sc' feature\n");
return image_init_result::FAIL;
}
// Valid SC values: 0x01..0xff
if (sc < 1 || sc > 0xff) {
LOG("hp80_optrom: illegal select code (%x)\n" , sc);
return image_init_result::FAIL;
}
auto length = get_software_region_length("rom");
if (length != HP80_OPTROM_SIZE) {
LOG("hp80_optrom: illegal region length (%x)\n" , length);
return image_init_result::FAIL;
}
LOG("hp80_optrom: loaded SC=0x%02x\n" , sc);
m_select_code = sc;
return image_init_result::PASS;
}
void hp80_optrom_slot_device::call_unload()
{
LOG("hp80_optrom: call_unload\n");
machine().schedule_soft_reset();
}
std::string hp80_optrom_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
{
return software_get_default_slot("rom");
}
void hp80_optrom_slot_devices(device_slot_interface &device)
{
device.option_add_internal("rom", HP80_OPTROM_CART);
}

View File

@ -1,91 +0,0 @@
// license:BSD-3-Clause
// copyright-holders: F. Ulivi
/*********************************************************************
hp80_optrom.h
Optional ROMs for HP80 systems
*********************************************************************/
#ifndef MAME_BUS_HP80_OPTROMS_HP80_OPTROM_H
#define MAME_BUS_HP80_OPTROMS_HP80_OPTROM_H
#pragma once
#include "softlist_dev.h"
// Size of optional ROMs (8k)
static constexpr offs_t HP80_OPTROM_SIZE = 0x2000;
void hp80_optrom_slot_devices(device_slot_interface &device);
class device_hp80_optrom_interface : public device_interface
{
protected:
device_hp80_optrom_interface(const machine_config &mconfig, device_t &device);
};
class hp80_optrom_cart_device : public device_t, public device_hp80_optrom_interface
{
public:
// construction/destruction
hp80_optrom_cart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
hp80_optrom_cart_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 { }
};
class hp80_optrom_slot_device : public device_t,
public device_image_interface,
public device_single_card_slot_interface<device_hp80_optrom_interface>
{
public:
// construction/destruction
hp80_optrom_slot_device(machine_config const &mconfig, char const *tag, device_t *owner)
: hp80_optrom_slot_device(mconfig, tag, owner, (uint32_t)0)
{
option_reset();
hp80_optrom_slot_devices(*this);
set_default_option(nullptr);
set_fixed(false);
}
hp80_optrom_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~hp80_optrom_slot_device();
void install_read_handler(address_space& space);
protected:
// device-level overrides
virtual void device_start() override;
// image-level overrides
virtual image_init_result call_load() override;
virtual void call_unload() override;
virtual const software_list_loader &get_software_list_loader() const override { return rom_software_list_loader::instance(); }
virtual iodevice_t image_type() const override { return IO_ROM; }
virtual bool is_readable() const override { return true; }
virtual bool is_writeable() const override { return false; }
virtual bool is_creatable() const override { return false; }
virtual bool must_be_loaded() const override { return false; }
virtual bool is_reset_on_load() const override { return true; }
virtual const char *image_interface() const override { return "hp80_rom"; }
virtual const char *file_extensions() const override { return "bin"; }
// slot interface overrides
virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override;
device_hp80_optrom_interface *m_cart;
uint8_t m_select_code;
};
// device type definition
DECLARE_DEVICE_TYPE(HP80_OPTROM_SLOT, hp80_optrom_slot_device)
DECLARE_DEVICE_TYPE(HP80_OPTROM_CART, hp80_optrom_cart_device)
#endif // MAME_BUS_HP80_OPTROMS_HP80_OPTROM_H

View File

@ -1,139 +0,0 @@
// license:BSD-3-Clause
// copyright-holders: F. Ulivi
/*********************************************************************
hp_optrom.cpp
Optional ROMs for HP9845 systems
*********************************************************************/
#include "emu.h"
#include "hp_optrom.h"
#include "softlist.h"
#include "cpu/hphybrid/hphybrid.h"
DEFINE_DEVICE_TYPE(HP_OPTROM_CART, hp_optrom_cart_device, "hp_optrom_cart", "HP9845 optional ROM cartridge")
DEFINE_DEVICE_TYPE(HP_OPTROM_SLOT, hp_optrom_slot_device, "hp_optrom_slot", "HP9845 optional ROM slot")
// +--------------------------+
// |device_hp_optrom_interface|
// +--------------------------+
device_hp_optrom_interface::device_hp_optrom_interface(const machine_config &config, device_t &device) :
device_interface(device, "hpoptrom")
{
}
// +---------------------+
// |hp_optrom_cart_device|
// +---------------------+
hp_optrom_cart_device::hp_optrom_cart_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_hp_optrom_interface(mconfig, *this)
{
}
hp_optrom_cart_device::hp_optrom_cart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
hp_optrom_cart_device(mconfig, HP_OPTROM_CART, tag, owner, clock)
{
}
// +---------------------+
// |hp_optrom_slot_device|
// +---------------------+
hp_optrom_slot_device::hp_optrom_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, HP_OPTROM_SLOT, tag, owner, clock),
device_image_interface(mconfig, *this),
device_single_card_slot_interface<device_hp_optrom_interface>(mconfig, *this),
m_cart(nullptr),
m_base_addr(0),
m_end_addr(0)
{
option_reset();
option_add_internal("rom", HP_OPTROM_CART);
set_default_option(nullptr);
set_fixed(false);
}
hp_optrom_slot_device::~hp_optrom_slot_device()
{
}
void hp_optrom_slot_device::device_start()
{
m_cart = get_card_device();
}
image_init_result hp_optrom_slot_device::call_load()
{
logerror("hp_optrom: call_load\n");
if (m_cart == nullptr || !loaded_through_softlist()) {
logerror("hp_optrom: must be loaded from sw list\n");
return image_init_result::FAIL;
}
const char *base_feature = get_feature("base");
if (base_feature == nullptr) {
logerror("hp_optrom: no 'base' feature\n");
return image_init_result::FAIL;
}
offs_t base_addr;
if (base_feature[ 0 ] != '0' || base_feature[ 1 ] != 'x' || sscanf(&base_feature[ 2 ] , "%x" , &base_addr) != 1) {
logerror("hp_optrom: can't parse 'base' feature\n");
return image_init_result::FAIL;
}
// Valid BSC values for ROMs on LPU drawer: 0x07 0x0b .... 0x3b
// Valid BSC values for ROMs on PPU drawer: 0x09 0x0d .... 0x3d
// (BSC is field in bits 16..21 of base address)
// Bit 15 of base address must be 0
// Base address must be multiple of 0x1000
if ((base_addr & ~0x3f7000UL) != 0 || ((base_addr & 0x30000) != 0x10000 && (base_addr & 0x30000) != 0x30000) || base_addr < 0x70000) {
logerror("hp_optrom: illegal base address (%x)\n" , base_addr);
return image_init_result::FAIL;
}
auto length = get_software_region_length("rom") / 2;
if (length < 0x1000 || length > 0x8000 || (length & 0xfff) != 0 || ((base_addr & 0x7000) + length) > 0x8000) {
logerror("hp_optrom: illegal region length (%x)\n" , length);
return image_init_result::FAIL;
}
offs_t end_addr = base_addr + length - 1;
logerror("hp_optrom: base_addr = %06x end_addr = %06x\n" , base_addr , end_addr);
m_content.resize(length * 2);
uint8_t *buffer = m_content.data();
memcpy(buffer , get_software_region("rom") , length * 2);
// Install ROM in address space of every CPU
for (hp_hybrid_cpu_device& cpu : device_interface_iterator<hp_hybrid_cpu_device>(machine().root_device())) {
logerror("hp_optrom: install in %s AS\n" , cpu.tag());
cpu.space(AS_PROGRAM).install_rom(base_addr , end_addr , buffer);
}
m_base_addr = base_addr;
m_end_addr = end_addr;
return image_init_result::PASS;
}
void hp_optrom_slot_device::call_unload()
{
logerror("hp_optrom: call_unload\n");
if (m_cart != nullptr && m_base_addr != 0 && m_end_addr != 0) {
for (hp_hybrid_cpu_device& cpu : device_interface_iterator<hp_hybrid_cpu_device>(machine().root_device())) {
cpu.space(AS_PROGRAM).unmap_read(m_base_addr , m_end_addr);
}
m_content.resize(0);
m_base_addr = 0;
m_end_addr = 0;
}
}
std::string hp_optrom_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
{
return software_get_default_slot("rom");
}

View File

@ -1,78 +0,0 @@
// license:BSD-3-Clause
// copyright-holders: F. Ulivi
/*********************************************************************
hp_optrom.h
Optional ROMs for HP9845 systems
*********************************************************************/
#ifndef MAME_BUS_HP_OPTROMS_HP_OPTROM_H
#define MAME_BUS_HP_OPTROMS_HP_OPTROM_H
#pragma once
#include "softlist_dev.h"
class device_hp_optrom_interface : public device_interface
{
protected:
device_hp_optrom_interface(const machine_config &mconfig, device_t &device);
};
class hp_optrom_cart_device : public device_t, public device_hp_optrom_interface
{
public:
// construction/destruction
hp_optrom_cart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
hp_optrom_cart_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 { }
};
class hp_optrom_slot_device : public device_t,
public device_image_interface,
public device_single_card_slot_interface<device_hp_optrom_interface>
{
public:
// construction/destruction
hp_optrom_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~hp_optrom_slot_device();
protected:
// device-level overrides
virtual void device_start() override;
// image-level overrides
virtual image_init_result call_load() override;
virtual void call_unload() override;
virtual const software_list_loader &get_software_list_loader() const override { return rom_software_list_loader::instance(); }
virtual iodevice_t image_type() const override { return IO_ROM; }
virtual bool is_readable() const override { return true; }
virtual bool is_writeable() const override { return false; }
virtual bool is_creatable() const override { return false; }
virtual bool must_be_loaded() const override { return false; }
virtual bool is_reset_on_load() const override { return true; }
virtual const char *image_interface() const override { return "hp9845b_rom"; }
virtual const char *file_extensions() const override { return "bin"; }
// slot interface overrides
virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override;
device_hp_optrom_interface *m_cart;
std::vector<uint8_t> m_content;
offs_t m_base_addr;
offs_t m_end_addr;
};
// device type definition
DECLARE_DEVICE_TYPE(HP_OPTROM_SLOT, hp_optrom_slot_device)
DECLARE_DEVICE_TYPE(HP_OPTROM_CART, hp_optrom_cart_device)
#endif // MAME_BUS_HP_OPTROMS_HP_OPTROM_H

View File

@ -17,7 +17,7 @@
#include "sound/dac.h"
#include "sound/volt_reg.h"
#include "machine/1ma6.h"
#include "bus/hp80_optroms/hp80_optrom.h"
#include "machine/hp80_optrom.h"
#include "softlist.h"
#include "machine/bankdev.h"
#include "bus/hp80_io/hp80_io.h"
@ -184,7 +184,7 @@ private:
required_ioport m_io_key1;
required_ioport m_io_key2;
required_ioport m_io_modkeys;
required_device_array<hp80_optrom_slot_device , 6> m_rom_drawers;
required_device_array<hp80_optrom_device , 6> m_rom_drawers;
required_device<address_map_bank_device> m_rombank;
required_device_array<hp80_io_slot_device , IOP_COUNT> m_io_slots;
required_device<bitbanger_device> m_prt_graph_out;
@ -1365,12 +1365,12 @@ void hp85_state::hp85(machine_config &config)
HP_1MA6(config, "tape", 0);
// Optional ROMs
HP80_OPTROM_SLOT(config, m_rom_drawers[0]);
HP80_OPTROM_SLOT(config, m_rom_drawers[1]);
HP80_OPTROM_SLOT(config, m_rom_drawers[2]);
HP80_OPTROM_SLOT(config, m_rom_drawers[3]);
HP80_OPTROM_SLOT(config, m_rom_drawers[4]);
HP80_OPTROM_SLOT(config, m_rom_drawers[5]);
HP80_OPTROM(config, m_rom_drawers[0]);
HP80_OPTROM(config, m_rom_drawers[1]);
HP80_OPTROM(config, m_rom_drawers[2]);
HP80_OPTROM(config, m_rom_drawers[3]);
HP80_OPTROM(config, m_rom_drawers[4]);
HP80_OPTROM(config, m_rom_drawers[5]);
// I/O slots
HP80_IO_SLOT(config, m_io_slots[0]).set_slot_no(0);

View File

@ -43,7 +43,7 @@
#include "machine/timer.h"
#include "machine/hp9825_tape.h"
#include "machine/hp98x5_io_sys.h"
#include "bus/hp9825_optroms/hp9825_optrom.h"
#include "machine/hp9825_optrom.h"
#include "bus/hp9845_io/hp9845_io.h"
#include "imagedev/bitbngr.h"
#include "speaker.h"
@ -128,7 +128,7 @@ protected:
virtual void machine_reset() override;
required_device<hp_09825_67907_cpu_device> m_cpu;
required_device_array<hp9825_optrom_slot_device , 4> m_rom_drawers;
required_device_array<hp9825_optrom_device , 4> m_rom_drawers;
private:
required_device<hp98x5_io_sys_device> m_io_sys;
@ -681,7 +681,7 @@ void hp9825_state::hp9825_base(machine_config &config)
// Optional ROM slots
for (auto& finder : m_rom_drawers) {
HP9825_OPTROM_SLOT(config , finder);
HP9825_OPTROM(config , finder);
}
config.set_default_layout(layout_hp9825);

View File

@ -38,7 +38,7 @@
#include "emu.h"
#include "includes/hp9845.h"
#include "bus/hp_optroms/hp_optrom.h"
#include "machine/hp9845_optrom.h"
#include "bus/hp9845_io/hp9845_io.h"
#include "machine/timer.h"
@ -3701,14 +3701,14 @@ void hp9845_base_state::hp9845_base(machine_config &config)
// right-hand side and left-hand side drawers, respectively.
// Here we do away with the distinction between LPU & PPU ROMs: in the end they
// are visible to both CPUs at the same addresses.
HP_OPTROM_SLOT(config, "drawer1", 0);
HP_OPTROM_SLOT(config, "drawer2", 0);
HP_OPTROM_SLOT(config, "drawer3", 0);
HP_OPTROM_SLOT(config, "drawer4", 0);
HP_OPTROM_SLOT(config, "drawer5", 0);
HP_OPTROM_SLOT(config, "drawer6", 0);
HP_OPTROM_SLOT(config, "drawer7", 0);
HP_OPTROM_SLOT(config, "drawer8", 0);
HP9845_OPTROM(config, "drawer1", 0);
HP9845_OPTROM(config, "drawer2", 0);
HP9845_OPTROM(config, "drawer3", 0);
HP9845_OPTROM(config, "drawer4", 0);
HP9845_OPTROM(config, "drawer5", 0);
HP9845_OPTROM(config, "drawer6", 0);
HP9845_OPTROM(config, "drawer7", 0);
HP9845_OPTROM(config, "drawer8", 0);
// I/O slots
for (unsigned slot = 0; slot < 4; slot++) {

View File

@ -0,0 +1,89 @@
// license:BSD-3-Clause
// copyright-holders: F. Ulivi
/*********************************************************************
hp80_optrom.cpp
Optional ROMs for HP80 systems
*********************************************************************/
#include "emu.h"
#include "hp80_optrom.h"
#include "softlist.h"
// Debugging
#define VERBOSE 1
#include "logmacro.h"
DEFINE_DEVICE_TYPE(HP80_OPTROM, hp80_optrom_device, "hp80_optrom", "HP80 optional ROM")
// +------------------+
// |hp80_optrom_device|
// +------------------+
hp80_optrom_device::hp80_optrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, HP80_OPTROM, tag, owner, clock),
device_image_interface(mconfig, *this),
m_select_code(0)
{
}
hp80_optrom_device::~hp80_optrom_device()
{
}
void hp80_optrom_device::install_read_handler(address_space& space)
{
if (loaded_through_softlist()) {
offs_t start = (offs_t)m_select_code * HP80_OPTROM_SIZE;
space.install_rom(start , start + HP80_OPTROM_SIZE - 1 , get_software_region("rom"));
}
}
void hp80_optrom_device::device_start()
{
}
image_init_result hp80_optrom_device::call_load()
{
LOG("hp80_optrom: call_load\n");
if (!loaded_through_softlist()) {
LOG("hp80_optrom: must be loaded from sw list\n");
return image_init_result::FAIL;
}
const char *sc_feature = get_feature("sc");
if (sc_feature == nullptr) {
LOG("hp80_optrom: no 'sc' feature\n");
return image_init_result::FAIL;
}
unsigned sc;
if (sc_feature[ 0 ] != '0' || sc_feature[ 1 ] != 'x' || sscanf(&sc_feature[ 2 ] , "%x" , &sc) != 1) {
LOG("hp80_optrom: can't parse 'sc' feature\n");
return image_init_result::FAIL;
}
// Valid SC values: 0x01..0xff
if (sc < 1 || sc > 0xff) {
LOG("hp80_optrom: illegal select code (%x)\n" , sc);
return image_init_result::FAIL;
}
auto length = get_software_region_length("rom");
if (length != HP80_OPTROM_SIZE) {
LOG("hp80_optrom: illegal region length (%x)\n" , length);
return image_init_result::FAIL;
}
LOG("hp80_optrom: loaded SC=0x%02x\n" , sc);
m_select_code = sc;
return image_init_result::PASS;
}
void hp80_optrom_device::call_unload()
{
LOG("hp80_optrom: call_unload\n");
machine().schedule_soft_reset();
}

View File

@ -0,0 +1,60 @@
// license:BSD-3-Clause
// copyright-holders: F. Ulivi
/*********************************************************************
hp80_optrom.h
Optional ROMs for HP80 systems
*********************************************************************/
#ifndef MAME_MACHINE_HP80_OPTROM_H
#define MAME_MACHINE_HP80_OPTROM_H
#pragma once
#include "softlist_dev.h"
// Size of optional ROMs (8k)
static constexpr offs_t HP80_OPTROM_SIZE = 0x2000;
class hp80_optrom_device : public device_t,
public device_image_interface
{
public:
// construction/destruction
hp80_optrom_device(machine_config const &mconfig, char const *tag, device_t *owner)
: hp80_optrom_device(mconfig, tag, owner, (uint32_t)0)
{
}
hp80_optrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~hp80_optrom_device();
void install_read_handler(address_space& space);
protected:
// device-level overrides
virtual void device_start() override;
// image-level overrides
virtual image_init_result call_load() override;
virtual void call_unload() override;
virtual const software_list_loader &get_software_list_loader() const override { return rom_software_list_loader::instance(); }
virtual iodevice_t image_type() const override { return IO_ROM; }
virtual bool is_readable() const override { return true; }
virtual bool is_writeable() const override { return false; }
virtual bool is_creatable() const override { return false; }
virtual bool must_be_loaded() const override { return false; }
virtual bool is_reset_on_load() const override { return true; }
virtual const char *image_interface() const override { return "hp80_rom"; }
virtual const char *file_extensions() const override { return "bin"; }
uint8_t m_select_code;
};
// device type definition
DECLARE_DEVICE_TYPE(HP80_OPTROM, hp80_optrom_device)
#endif // MAME_MACHINE_HP80_OPTROM_H

View File

@ -16,8 +16,7 @@
//#define VERBOSE 1
#include "logmacro.h"
DEFINE_DEVICE_TYPE(HP9825_OPTROM_CART, hp9825_optrom_cart_device, "hp9825_optrom_cart", "HP9825 optional ROM cartridge")
DEFINE_DEVICE_TYPE(HP9825_OPTROM_SLOT, hp9825_optrom_slot_device, "hp9825_optrom_slot", "HP9825 optional ROM slot")
DEFINE_DEVICE_TYPE(HP9825_OPTROM, hp9825_optrom_device, "hp9825_optrom", "HP9825 optional ROM")
struct optrom_region {
offs_t m_start;
@ -37,57 +36,29 @@ constexpr std::array<struct optrom_region , 8> region_tab =
{ 0x5c00 ,0x2000 , "rom5c00" }
}};
// +------------------------------+
// |device_hp9825_optrom_interface|
// +------------------------------+
device_hp9825_optrom_interface::device_hp9825_optrom_interface(const machine_config &mconfig, device_t &device)
: device_interface(device, "hp9825optrom")
// +--------------------+
// |hp9825_optrom_device|
// +--------------------+
hp9825_optrom_device::hp9825_optrom_device(machine_config const &mconfig, char const *tag, device_t *owner)
: hp9825_optrom_device(mconfig, tag, owner, (uint32_t)0)
{
}
// +-------------------------+
// |hp9825_optrom_cart_device|
// +-------------------------+
hp9825_optrom_cart_device::hp9825_optrom_cart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: hp9825_optrom_cart_device(mconfig , HP9825_OPTROM_CART , tag , owner , clock)
{
}
hp9825_optrom_cart_device::hp9825_optrom_cart_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_hp9825_optrom_interface(mconfig, *this)
{
}
// +-------------------------+
// |hp9825_optrom_slot_device|
// +-------------------------+
hp9825_optrom_slot_device::hp9825_optrom_slot_device(machine_config const &mconfig, char const *tag, device_t *owner)
: hp9825_optrom_slot_device(mconfig, tag, owner, (uint32_t)0)
{
}
hp9825_optrom_slot_device::hp9825_optrom_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, HP9825_OPTROM_SLOT, tag, owner, clock)
hp9825_optrom_device::hp9825_optrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, HP9825_OPTROM, tag, owner, clock)
, device_image_interface(mconfig, *this)
, device_single_card_slot_interface<device_hp9825_optrom_interface>(mconfig, *this)
, m_cart(nullptr)
, m_rom_limit(0xffffU)
, m_loaded_regions(0)
, m_space_r(nullptr)
, m_bank(*this , "rombank")
{
option_reset();
option_add_internal("rom", HP9825_OPTROM_CART);
set_default_option(nullptr);
set_fixed(false);
}
hp9825_optrom_slot_device::~hp9825_optrom_slot_device()
hp9825_optrom_device::~hp9825_optrom_device()
{
}
void hp9825_optrom_slot_device::install_rw_handlers(address_space *space_r , address_space *space_w)
void hp9825_optrom_device::install_rw_handlers(address_space *space_r , address_space *space_w)
{
LOG("limit=%04x\n" , m_rom_limit);
m_loaded_regions = 0;
@ -121,20 +92,19 @@ void hp9825_optrom_slot_device::install_rw_handlers(address_space *space_r , add
}
}
void hp9825_optrom_slot_device::device_add_mconfig(machine_config &config)
void hp9825_optrom_device::device_add_mconfig(machine_config &config)
{
ADDRESS_MAP_BANK(config, m_bank).set_options(ENDIANNESS_BIG, 16, 13, 0x400).set_shift(-1);
}
void hp9825_optrom_slot_device::device_start()
void hp9825_optrom_device::device_start()
{
m_cart = get_card_device();
}
image_init_result hp9825_optrom_slot_device::call_load()
image_init_result hp9825_optrom_device::call_load()
{
LOG("hp9825_optrom: call_load\n");
if (m_cart == nullptr || !loaded_through_softlist()) {
if (!loaded_through_softlist()) {
LOG("hp9825_optrom: must be loaded from sw list\n");
return image_init_result::FAIL;
}
@ -156,7 +126,7 @@ image_init_result hp9825_optrom_slot_device::call_load()
return image_init_result::PASS;
}
void hp9825_optrom_slot_device::call_unload()
void hp9825_optrom_device::call_unload()
{
LOG("hp9825_optrom: call_unload\n");
if (m_space_r != nullptr && m_loaded_regions) {
@ -179,9 +149,3 @@ void hp9825_optrom_slot_device::call_unload()
}
machine().schedule_soft_reset();
}
std::string hp9825_optrom_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
{
return software_get_default_slot("rom");
}

View File

@ -7,42 +7,22 @@
Optional ROMs for HP9825 systems
*********************************************************************/
#ifndef MAME_BUS_HP9825_OPTROMS_HP9825_OPTROM_H
#define MAME_BUS_HP9825_OPTROMS_HP9825_OPTROM_H
#ifndef MAME_MACHINE_HP9825_OPTROM_H
#define MAME_MACHINE_HP9825_OPTROM_H
#pragma once
#include "machine/bankdev.h"
#include "softlist_dev.h"
class device_hp9825_optrom_interface : public device_interface
{
public:
device_hp9825_optrom_interface(const machine_config &mconfig, device_t &device);
};
class hp9825_optrom_cart_device : public device_t, public device_hp9825_optrom_interface
class hp9825_optrom_device : public device_t,
public device_image_interface
{
public:
// construction/destruction
hp9825_optrom_cart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
hp9825_optrom_cart_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 { }
};
class hp9825_optrom_slot_device : public device_t,
public device_image_interface,
public device_single_card_slot_interface<device_hp9825_optrom_interface>
{
public:
// construction/destruction
hp9825_optrom_slot_device(machine_config const &mconfig, char const *tag, device_t *owner);
hp9825_optrom_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~hp9825_optrom_slot_device();
hp9825_optrom_device(machine_config const &mconfig, char const *tag, device_t *owner);
hp9825_optrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~hp9825_optrom_device();
void set_rom_limit(offs_t rom_limit) { m_rom_limit = rom_limit; }
@ -67,10 +47,6 @@ protected:
virtual const char *image_interface() const override { return "hp9825_rom"; }
virtual const char *file_extensions() const override { return "bin"; }
// slot interface overrides
virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override;
device_hp9825_optrom_interface *m_cart;
offs_t m_rom_limit;
unsigned m_loaded_regions;
address_space *m_space_r;
@ -78,7 +54,6 @@ protected:
};
// device type definition
DECLARE_DEVICE_TYPE(HP9825_OPTROM_SLOT, hp9825_optrom_slot_device)
DECLARE_DEVICE_TYPE(HP9825_OPTROM_CART, hp9825_optrom_cart_device)
DECLARE_DEVICE_TYPE(HP9825_OPTROM, hp9825_optrom_device)
#endif /* MAME_BUS_HP9825_OPTROMS_HP9825_OPTROM_H */
#endif /* MAME_MACHINE_HP9825_OPTROM_H */

View File

@ -0,0 +1,99 @@
// license:BSD-3-Clause
// copyright-holders: F. Ulivi
/*********************************************************************
hp9845_optrom.cpp
Optional ROMs for HP9845 systems
*********************************************************************/
#include "emu.h"
#include "hp9845_optrom.h"
#include "softlist.h"
#include "cpu/hphybrid/hphybrid.h"
DEFINE_DEVICE_TYPE(HP9845_OPTROM, hp9845_optrom_device, "hp9845_optrom", "HP9845 optional ROM")
// +--------------------+
// |hp9845_optrom_device|
// +--------------------+
hp9845_optrom_device::hp9845_optrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, HP9845_OPTROM, tag, owner, clock),
device_image_interface(mconfig, *this),
m_base_addr(0),
m_end_addr(0)
{
}
hp9845_optrom_device::~hp9845_optrom_device()
{
}
void hp9845_optrom_device::device_start()
{
}
image_init_result hp9845_optrom_device::call_load()
{
logerror("hp9845_optrom: call_load\n");
if (!loaded_through_softlist()) {
logerror("hp9845_optrom: must be loaded from sw list\n");
return image_init_result::FAIL;
}
const char *base_feature = get_feature("base");
if (base_feature == nullptr) {
logerror("hp9845_optrom: no 'base' feature\n");
return image_init_result::FAIL;
}
offs_t base_addr;
if (base_feature[ 0 ] != '0' || base_feature[ 1 ] != 'x' || sscanf(&base_feature[ 2 ] , "%x" , &base_addr) != 1) {
logerror("hp9845_optrom: can't parse 'base' feature\n");
return image_init_result::FAIL;
}
// Valid BSC values for ROMs on LPU drawer: 0x07 0x0b .... 0x3b
// Valid BSC values for ROMs on PPU drawer: 0x09 0x0d .... 0x3d
// (BSC is field in bits 16..21 of base address)
// Bit 15 of base address must be 0
// Base address must be multiple of 0x1000
if ((base_addr & ~0x3f7000UL) != 0 || ((base_addr & 0x30000) != 0x10000 && (base_addr & 0x30000) != 0x30000) || base_addr < 0x70000) {
logerror("hp9845_optrom: illegal base address (%x)\n" , base_addr);
return image_init_result::FAIL;
}
auto length = get_software_region_length("rom") / 2;
if (length < 0x1000 || length > 0x8000 || (length & 0xfff) != 0 || ((base_addr & 0x7000) + length) > 0x8000) {
logerror("hp9845_optrom: illegal region length (%x)\n" , length);
return image_init_result::FAIL;
}
offs_t end_addr = base_addr + length - 1;
logerror("hp9845_optrom: base_addr = %06x end_addr = %06x\n" , base_addr , end_addr);
// Install ROM in address space of every CPU
for (hp_hybrid_cpu_device& cpu : device_interface_iterator<hp_hybrid_cpu_device>(machine().root_device())) {
logerror("hp9845_optrom: install in %s AS\n" , cpu.tag());
cpu.space(AS_PROGRAM).install_rom(base_addr , end_addr , get_software_region("rom"));
}
m_base_addr = base_addr;
m_end_addr = end_addr;
return image_init_result::PASS;
}
void hp9845_optrom_device::call_unload()
{
logerror("hp9845_optrom: call_unload\n");
if (m_base_addr != 0 && m_end_addr != 0) {
for (hp_hybrid_cpu_device& cpu : device_interface_iterator<hp_hybrid_cpu_device>(machine().root_device())) {
cpu.space(AS_PROGRAM).unmap_read(m_base_addr , m_end_addr);
}
m_base_addr = 0;
m_end_addr = 0;
}
}

View File

@ -0,0 +1,51 @@
// license:BSD-3-Clause
// copyright-holders: F. Ulivi
/*********************************************************************
hp9845_optrom.h
Optional ROMs for HP9845 systems
*********************************************************************/
#ifndef MAME_MACHINE_HP9845_OPTROM_H
#define MAME_MACHINE_HP9845_OPTROM_H
#pragma once
#include "softlist_dev.h"
class hp9845_optrom_device : public device_t,
public device_image_interface
{
public:
// construction/destruction
hp9845_optrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~hp9845_optrom_device();
protected:
// device-level overrides
virtual void device_start() override;
// image-level overrides
virtual image_init_result call_load() override;
virtual void call_unload() override;
virtual const software_list_loader &get_software_list_loader() const override { return rom_software_list_loader::instance(); }
virtual iodevice_t image_type() const override { return IO_ROM; }
virtual bool is_readable() const override { return true; }
virtual bool is_writeable() const override { return false; }
virtual bool is_creatable() const override { return false; }
virtual bool must_be_loaded() const override { return false; }
virtual bool is_reset_on_load() const override { return true; }
virtual const char *image_interface() const override { return "hp9845b_rom"; }
virtual const char *file_extensions() const override { return "bin"; }
offs_t m_base_addr;
offs_t m_end_addr;
};
// device type definition
DECLARE_DEVICE_TYPE(HP9845_OPTROM, hp9845_optrom_device)
#endif // MAME_MACHINE_HP9845_OPTROM_H