summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author fulivi <fulivi@users.noreply.github.com>2017-08-29 13:45:36 +0200
committer Vas Crabb <cuavas@users.noreply.github.com>2017-08-29 21:45:36 +1000
commit05c792eee734173854895445b8c779c6caca0786 (patch)
tree2301e26579f5d9efa57c0af3547de2050c6e221b
parent126ad62e7d38f7f44f334255886ed0ba620ecf41 (diff)
hp85: support of opt. ROMs (#2604)
* hp85: added support for optional ROM cartridges. Started optional ROM sw list (not finished). * hp85: refactored mapping of opt. ROMs according to cuavas' comments
-rw-r--r--hash/hp85_rom.xml70
-rw-r--r--scripts/src/bus.lua11
-rw-r--r--scripts/target/mame/mess.lua1
-rw-r--r--src/devices/bus/hp80_optroms/hp80_optrom.cpp116
-rw-r--r--src/devices/bus/hp80_optroms/hp80_optrom.h77
-rw-r--r--src/mame/drivers/hp80.cpp68
6 files changed, 324 insertions, 19 deletions
diff --git a/hash/hp85_rom.xml b/hash/hp85_rom.xml
new file mode 100644
index 00000000000..30b15057383
--- /dev/null
+++ b/hash/hp85_rom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<!DOCTYPE softwarelist SYSTEM "softwarelist.dtd">
+
+<softwarelist name="hp85_rom" description="HP-85 Option ROMs">
+ <software name="service">
+ <description>Service ROM</description>
+ <year>198?</year>
+ <publisher>Hewlett-Packard</publisher>
+ <info name="serial" value="00085-60952"/>
+
+ <part name="rom" interface="hp80_rom">
+ <feature name="sc" value="0xe0"/>
+ <dataarea name="rom" size="0x2000">
+ <rom name="rom340.bin" size="0x2000" crc="41441333" sha1="6e166b7b0723da126021e2b2cd572660931e066d" offset="0"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="service_fix">
+ <description>Service ROM (fixed)</description>
+ <year>198?</year>
+ <publisher>Hewlett-Packard</publisher>
+ <info name="serial" value="00085-60952"/>
+
+ <part name="rom" interface="hp80_rom">
+ <feature name="sc" value="0xe0"/>
+ <dataarea name="rom" size="0x2000">
+ <rom name="rom340_fixed.bin" size="0x2000" crc="3ebdd60a" sha1="efa3d3cc9e593f6fe74b1189ea4c2dd0660ae698" offset="0"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="assembler">
+ <description>Assembler ROM</description>
+ <year>1980</year>
+ <publisher>Hewlett-Packard</publisher>
+ <info name="serial" value="00085-15007"/>
+
+ <part name="rom" interface="hp80_rom">
+ <feature name="sc" value="0x28"/>
+ <dataarea name="rom" size="0x2000">
+ <rom name="rom050.bin" size="0x2000" crc="9827cc3c" sha1="018d6a8df68a839b4e192da957f38a5db20f8bfc" offset="0"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="matrix">
+ <description>Matrix ROM</description>
+ <year>1979</year>
+ <publisher>Hewlett-Packard</publisher>
+ <info name="serial" value="00085-15004"/>
+
+ <part name="rom" interface="hp80_rom">
+ <feature name="sc" value="0xB0"/>
+ <dataarea name="rom" size="0x2000">
+ <rom name="rom260.bin" size="0x2000" crc="70f83074" sha1="3ef192ecff71b967ba747bea8df483e0596988b1" offset="0"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="io">
+ <description>I/O ROM</description>
+ <year>1979</year>
+ <publisher>Hewlett-Packard</publisher>
+ <info name="serial" value="00085-15003"/>
+
+ <part name="rom" interface="hp80_rom">
+ <feature name="sc" value="0xC0"/>
+ <dataarea name="rom" size="0x2000">
+ <rom name="rom300.bin" size="0x2000" crc="6f904a4c" sha1="6f90899fa983e2fd63088ce516c35d07e5942f2b" offset="0"/>
+ </dataarea>
+ </part>
+ </software>
+</softwarelist>
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index 74658c3bff7..16cf53eee9d 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -3090,6 +3090,17 @@ 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",
+ }
+end
+
+---------------------------------------------------
+--
--@src/devices/bus/hp9845_io/hp9845_io.h,BUSES["HP9845_IO"] = true
---------------------------------------------------
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index df4b9081394..188d91ab023 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -678,6 +678,7 @@ BUSES["IQ151"] = true
BUSES["ISA"] = true
BUSES["ISBX"] = true
BUSES["HP_OPTROM"] = true
+BUSES["HP80_OPTROM"] = true
BUSES["HP9845_IO"] = true
BUSES["KC"] = true
BUSES["LPCI"] = true
diff --git a/src/devices/bus/hp80_optroms/hp80_optrom.cpp b/src/devices/bus/hp80_optroms/hp80_optrom.cpp
new file mode 100644
index 00000000000..2797e37b69d
--- /dev/null
+++ b/src/devices/bus/hp80_optroms/hp80_optrom.cpp
@@ -0,0 +1,116 @@
+// 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")
+
+// +-----------------------+
+// |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_slot_card_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_slot_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 = dynamic_cast<hp80_optrom_cart_device *>(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");
+}
+
+SLOT_INTERFACE_START(hp80_optrom_slot_device)
+ SLOT_INTERFACE_INTERNAL("rom", HP80_OPTROM_CART)
+SLOT_INTERFACE_END
diff --git a/src/devices/bus/hp80_optroms/hp80_optrom.h b/src/devices/bus/hp80_optroms/hp80_optrom.h
new file mode 100644
index 00000000000..2fd43456264
--- /dev/null
+++ b/src/devices/bus/hp80_optroms/hp80_optrom.h
@@ -0,0 +1,77 @@
+// 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;
+
+class hp80_optrom_cart_device : public device_t,
+ public device_slot_card_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_slot_interface
+{
+public:
+ // construction/destruction
+ 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;
+
+ hp80_optrom_cart_device *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)
+
+SLOT_INTERFACE_EXTERN(hp80_optrom_slot_device);
+
+#endif // MAME_BUS_HP80_OPTROMS_HP80_OPTROM_H
diff --git a/src/mame/drivers/hp80.cpp b/src/mame/drivers/hp80.cpp
index 5438720d12f..fd03e1688ca 100644
--- a/src/mame/drivers/hp80.cpp
+++ b/src/mame/drivers/hp80.cpp
@@ -15,6 +15,9 @@
#include "sound/dac.h"
#include "sound/volt_reg.h"
#include "machine/1ma6.h"
+#include "bus/hp80_optroms/hp80_optrom.h"
+#include "softlist.h"
+#include "machine/bankdev.h"
// Debugging
#define VERBOSE 1
@@ -114,12 +117,12 @@ protected:
required_device<timer_device> m_clk_busy_timer;
required_device<beep_device> m_beep;
required_device<dac_1bit_device> m_dac;
- required_region_ptr<uint8_t> m_rom00;
- required_memory_bank m_rombank;
required_ioport m_io_key0;
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<address_map_bank_device> m_rombank;
// Character generator
required_region_ptr<uint8_t> m_chargen;
@@ -132,7 +135,6 @@ protected:
uint8_t m_crt_ctl;
uint8_t m_crt_read_byte;
uint8_t m_crt_write_byte;
- uint8_t m_empty_bank[ 0x2000 ];
bool m_global_int_en;
uint16_t m_int_req;
uint16_t m_int_serv;
@@ -183,12 +185,12 @@ hp85_state::hp85_state(const machine_config &mconfig, device_type type, const ch
m_clk_busy_timer(*this , "clk_busy_timer"),
m_beep(*this , "beeper"),
m_dac(*this , "dac"),
- m_rom00(*this , "rom00"),
- m_rombank(*this , "rombank"),
m_io_key0(*this , "KEY0"),
m_io_key1(*this , "KEY1"),
m_io_key2(*this , "KEY2"),
m_io_modkeys(*this, "MODKEYS"),
+ m_rom_drawers(*this , "drawer%u" , 1),
+ m_rombank(*this , "rombank"),
m_chargen(*this , "chargen")
{
}
@@ -197,14 +199,6 @@ void hp85_state::machine_start()
{
machine().first_screen()->register_screen_bitmap(m_bitmap);
m_video_mem.resize(VIDEO_MEM_SIZE);
-
- // ROM in bank 0 is always present (it's part of system ROMs)
- m_rombank->configure_entry(0 , m_rom00);
-
- memset(&m_empty_bank[ 0 ] , 0xff , sizeof(m_empty_bank));
-
- // All other entries in rombank (01-FF) not present for now
- m_rombank->configure_entries(1 , 255 , m_empty_bank , 0);
}
void hp85_state::machine_reset()
@@ -215,9 +209,6 @@ void hp85_state::machine_reset()
m_crt_ctl = BIT_MASK(CRT_CTL_POWERDN_BIT) | BIT_MASK(CRT_CTL_WIPEOUT_BIT);
m_crt_read_byte = 0;
m_crt_write_byte = 0;
- // Clear RSELEC
- m_rombank->set_entry(0xff);
-
m_int_req = 0;
m_int_serv = 0;
m_top_pending = NO_IRQ;
@@ -243,6 +234,16 @@ void hp85_state::machine_reset()
m_timer_idx = 0;
m_clk_busy = false;
update_irl();
+
+ // Load optional ROMs (if any)
+ // All entries in rombanks [01..FF] initially not present
+ m_rombank->space(AS_PROGRAM).unmap_read(HP80_OPTROM_SIZE * 1 , HP80_OPTROM_SIZE * 0x100 - 1);
+ for (auto& draw : m_rom_drawers) {
+ LOG("Loading opt ROM in drawer %s\n" , draw->tag());
+ draw->install_read_handler(m_rombank->space(AS_PROGRAM));
+ }
+ // Clear RSELEC
+ m_rombank->set_bank(0xff);
}
uint32_t hp85_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
@@ -534,7 +535,7 @@ WRITE8_MEMBER(hp85_state::clkdat_w)
WRITE8_MEMBER(hp85_state::rselec_w)
{
- m_rombank->set_entry(data);
+ m_rombank->set_bank(data);
}
// Outer index: key position [0..79] = r * 8 + c
@@ -1011,7 +1012,7 @@ INPUT_PORTS_END
static ADDRESS_MAP_START(cpu_mem_map , AS_PROGRAM , 8 , hp85_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000 , 0x5fff) AM_ROM
- AM_RANGE(0x6000 , 0x7fff) AM_ROMBANK("rombank")
+ AM_RANGE(0x6000 , 0x7fff) AM_DEVICE("rombank" , address_map_bank_device , amap8)
AM_RANGE(0x8000 , 0xbfff) AM_RAM
AM_RANGE(0xff00 , 0xff00) AM_WRITE(ginten_w)
AM_RANGE(0xff01 , 0xff01) AM_WRITE(gintdis_w)
@@ -1024,11 +1025,24 @@ static ADDRESS_MAP_START(cpu_mem_map , AS_PROGRAM , 8 , hp85_state)
AM_RANGE(0xff18 , 0xff18) AM_WRITE(rselec_w)
ADDRESS_MAP_END
+static ADDRESS_MAP_START(rombank_mem_map , AS_PROGRAM , 8 , hp85_state)
+ ADDRESS_MAP_UNMAP_HIGH
+ // ROM in bank 0 is always present (it's part of system ROMs)
+ AM_RANGE(0x0000 , 0x1fff) AM_ROM
+ADDRESS_MAP_END
+
static MACHINE_CONFIG_START(hp85)
MCFG_CPU_ADD("cpu" , HP_CAPRICORN , MASTER_CLOCK / 16)
MCFG_CPU_PROGRAM_MAP(cpu_mem_map)
MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(hp85_state , irq_callback)
+ MCFG_DEVICE_ADD("rombank", ADDRESS_MAP_BANK, 0)
+ MCFG_DEVICE_PROGRAM_MAP(rombank_mem_map)
+ MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
+ MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8)
+ MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(21)
+ MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000)
+
MCFG_SCREEN_ADD("screen" , RASTER)
MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK / 2 , 312 , 0 , 256 , 256 , 0 , 192)
MCFG_SCREEN_UPDATE_DRIVER(hp85_state , screen_update)
@@ -1055,6 +1069,22 @@ static MACHINE_CONFIG_START(hp85)
// Tape drive
MCFG_DEVICE_ADD("tape" , HP_1MA6 , 0)
+
+ // Optional ROMs
+ MCFG_DEVICE_ADD("drawer1", HP80_OPTROM_SLOT, 0)
+ MCFG_DEVICE_SLOT_INTERFACE(hp80_optrom_slot_device, NULL, false)
+ MCFG_DEVICE_ADD("drawer2", HP80_OPTROM_SLOT, 0)
+ MCFG_DEVICE_SLOT_INTERFACE(hp80_optrom_slot_device, NULL, false)
+ MCFG_DEVICE_ADD("drawer3", HP80_OPTROM_SLOT, 0)
+ MCFG_DEVICE_SLOT_INTERFACE(hp80_optrom_slot_device, NULL, false)
+ MCFG_DEVICE_ADD("drawer4", HP80_OPTROM_SLOT, 0)
+ MCFG_DEVICE_SLOT_INTERFACE(hp80_optrom_slot_device, NULL, false)
+ MCFG_DEVICE_ADD("drawer5", HP80_OPTROM_SLOT, 0)
+ MCFG_DEVICE_SLOT_INTERFACE(hp80_optrom_slot_device, NULL, false)
+ MCFG_DEVICE_ADD("drawer6", HP80_OPTROM_SLOT, 0)
+ MCFG_DEVICE_SLOT_INTERFACE(hp80_optrom_slot_device, NULL, false)
+
+ MCFG_SOFTWARE_LIST_ADD("optrom_list" , "hp85_rom")
MACHINE_CONFIG_END
ROM_START(hp85)
@@ -1063,7 +1093,7 @@ ROM_START(hp85)
ROM_LOAD("romsys2.bin" , 0x2000 , 0x2000 , CRC(50a85263) SHA1(3cf1d08749103ee245d572550ba1b053ffc7ef57))
ROM_LOAD("romsys3.bin" , 0x4000 , 0x2000 , CRC(0df385f0) SHA1(4c5ce5afd28f6d776f16cabbbbcc09769ff306b7))
- ROM_REGION(0x2000 , "rom00" , 0)
+ ROM_REGION(0x2000 , "rombank" , 0)
ROM_LOAD("rom000.bin" , 0 , 0x2000 , CRC(e13b8ae3) SHA1(2374618d25d1a000ddb534ae4f55ebd98ce0fff3))
ROM_REGION(0x400 , "chargen" , 0)