From 05c792eee734173854895445b8c779c6caca0786 Mon Sep 17 00:00:00 2001 From: fulivi Date: Tue, 29 Aug 2017 13:45:36 +0200 Subject: 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 --- hash/hp85_rom.xml | 70 ++++++++++++++++ scripts/src/bus.lua | 11 +++ scripts/target/mame/mess.lua | 1 + src/devices/bus/hp80_optroms/hp80_optrom.cpp | 116 +++++++++++++++++++++++++++ src/devices/bus/hp80_optroms/hp80_optrom.h | 77 ++++++++++++++++++ src/mame/drivers/hp80.cpp | 68 +++++++++++----- 6 files changed, 324 insertions(+), 19 deletions(-) create mode 100644 hash/hp85_rom.xml create mode 100644 src/devices/bus/hp80_optroms/hp80_optrom.cpp create mode 100644 src/devices/bus/hp80_optroms/hp80_optrom.h 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 @@ + + + + + + Service ROM + 198? + Hewlett-Packard + + + + + + + + + + + Service ROM (fixed) + 198? + Hewlett-Packard + + + + + + + + + + + Assembler ROM + 1980 + Hewlett-Packard + + + + + + + + + + + Matrix ROM + 1979 + Hewlett-Packard + + + + + + + + + + + I/O ROM + 1979 + Hewlett-Packard + + + + + + + + + + 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 @@ -3088,6 +3088,17 @@ if (BUSES["HP_OPTROM"]~=null) then } 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(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 m_clk_busy_timer; required_device m_beep; required_device m_dac; - required_region_ptr 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 m_rom_drawers; + required_device m_rombank; // Character generator required_region_ptr 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) -- cgit v1.2.3