diff --git a/hash/hp9845b_rom.xml b/hash/hp9845b_rom.xml index f5586960f2e..9f419f6dfd0 100644 --- a/hash/hp9845b_rom.xml +++ b/hash/hp9845b_rom.xml @@ -10,7 +10,8 @@ - + + @@ -24,7 +25,8 @@ - + + @@ -38,7 +40,8 @@ - + + @@ -53,7 +56,8 @@ - + + @@ -67,7 +71,9 @@ - + + + @@ -81,7 +87,8 @@ - + + @@ -95,7 +102,8 @@ - + + @@ -109,7 +117,8 @@ - + + @@ -123,7 +132,8 @@ - + + @@ -136,7 +146,8 @@ - + + @@ -150,7 +161,8 @@ - + + @@ -159,6 +171,7 @@ + IMAGE/45 Database Manager (Rev B) 198? @@ -179,6 +192,7 @@ + IMAGE/45 Database Manager (Rev C) 198? @@ -206,12 +220,14 @@ - + + + Resource Management 198? @@ -237,7 +253,8 @@ - + + @@ -251,7 +268,8 @@ - + + @@ -267,7 +285,8 @@ - + + @@ -281,7 +300,8 @@ - + + @@ -297,7 +317,8 @@ - + + @@ -314,7 +335,8 @@ - + + diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index cd9923ea1fc..e5545c46287 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -2673,3 +2673,14 @@ if (BUSES["SVI_SLOT"]~=null) then MAME_DIR .. "src/devices/bus/svi3x8/slot/sv807.h", } 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", + } +end diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 93039ee80bd..38f515ecffa 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -623,6 +623,7 @@ BUSES["INTV_CTRL"] = true BUSES["IQ151"] = true BUSES["ISA"] = true BUSES["ISBX"] = true +BUSES["HP_OPTROM"] = true BUSES["KC"] = true BUSES["LPCI"] = true BUSES["M5"] = true diff --git a/src/devices/bus/hp_optroms/hp_optrom.cpp b/src/devices/bus/hp_optroms/hp_optrom.cpp new file mode 100644 index 00000000000..74391e96838 --- /dev/null +++ b/src/devices/bus/hp_optroms/hp_optrom.cpp @@ -0,0 +1,151 @@ +// license:BSD-3-Clause +// copyright-holders: F. Ulivi +/********************************************************************* + + hp_optrom.cpp + + Optional ROMs for HP9845 systems + +*********************************************************************/ + +#include "hp_optrom.h" +#include "softlist.h" +#include "cpu/hphybrid/hphybrid.h" + +const device_type HP_OPTROM_CART = &device_creator; +const device_type HP_OPTROM_SLOT = &device_creator; + +// +---------------------+ +// |hp_optrom_cart_device| +// +---------------------+ +hp_optrom_cart_device::hp_optrom_cart_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) : + device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_slot_card_interface(mconfig, *this) +{ +} + +hp_optrom_cart_device::hp_optrom_cart_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, HP_OPTROM_CART, "HP9845 optional ROM cartridge", tag, owner, clock, "hp_optrom_cart", __FILE__), + device_slot_card_interface(mconfig, *this) +{ +} + +// +---------------------+ +// |hp_optrom_slot_device| +// +---------------------+ +hp_optrom_slot_device::hp_optrom_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, HP_OPTROM_SLOT, "HP9845 optional ROM Slot", tag, owner, clock, "hp_optrom_slot", __FILE__), + device_image_interface(mconfig, *this), + device_slot_interface(mconfig, *this), + m_cart(nullptr), + m_base_addr(0), + m_end_addr(0) +{ +} + +hp_optrom_slot_device::~hp_optrom_slot_device() +{ +} + +void hp_optrom_slot_device::device_start() +{ + m_cart = dynamic_cast(get_card_device()); +} + +void hp_optrom_slot_device::device_config_complete() +{ + update_names(HP_OPTROM_SLOT , "optional_rom" , "optrom"); +} + +bool hp_optrom_slot_device::call_load() +{ + logerror("hp_optrom: call_load\n"); + if (m_cart == nullptr || !m_from_swlist) { + logerror("hp_optrom: fail 1\n"); + return IMAGE_INIT_FAIL; + } + + const software_part *part_ptr = part_entry(); + if (part_ptr == nullptr) { + logerror("hp_optrom: fail 2\n"); + return IMAGE_INIT_FAIL; + } + + const char *base_feature = part_ptr->feature("base"); + if (base_feature == nullptr) { + logerror("hp_optrom: no 'base' feature\n"); + return IMAGE_INIT_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_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_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_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 *buffer = m_content.data(); + memcpy(buffer , get_software_region("rom") , length * 2); + + // Install ROM in address space of every CPU + device_interface_iterator iter(machine().root_device()); + for (hp_hybrid_cpu_device *cpu = iter.first(); cpu != nullptr; cpu = iter.next()) { + 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_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) { + device_interface_iterator iter(machine().root_device()); + for (hp_hybrid_cpu_device *cpu = iter.first(); cpu != nullptr; cpu = iter.next()) { + cpu->space(AS_PROGRAM).unmap_read(m_base_addr , m_end_addr); + } + m_content.resize(0); + m_base_addr = 0; + m_end_addr = 0; + } +} + +bool hp_optrom_slot_device::call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) +{ + logerror("hp_optrom: call_softlist_load\n"); + machine().rom_load().load_software_part_region(*this, swlist, swname, start_entry); + return TRUE; +} + +std::string hp_optrom_slot_device::get_default_card_software() +{ + return software_get_default_slot("rom"); +} + +SLOT_INTERFACE_START(hp_optrom_slot_device) + SLOT_INTERFACE_INTERNAL("rom", HP_OPTROM_CART) +SLOT_INTERFACE_END diff --git a/src/devices/bus/hp_optroms/hp_optrom.h b/src/devices/bus/hp_optroms/hp_optrom.h new file mode 100644 index 00000000000..a18fd5e4087 --- /dev/null +++ b/src/devices/bus/hp_optroms/hp_optrom.h @@ -0,0 +1,74 @@ +// license:BSD-3-Clause +// copyright-holders: F. Ulivi +/********************************************************************* + + hp_optrom.h + + Optional ROMs for HP9845 systems + +*********************************************************************/ + +#pragma once + +#ifndef _HP_OPTROM_H_ +#define _HP_OPTROM_H_ + +#include "emu.h" + +class hp_optrom_cart_device : public device_t, + public device_slot_card_interface +{ +public: + // construction/destruction + hp_optrom_cart_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + hp_optrom_cart_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start() override {} +}; + +class hp_optrom_slot_device : public device_t, + public device_image_interface, + public device_slot_interface +{ +public: + // construction/destruction + hp_optrom_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~hp_optrom_slot_device(); + + // device-level overrides + virtual void device_start() override; + virtual void device_config_complete() override; + + // image-level overrides + virtual bool call_load() override; + virtual void call_unload() override; + virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) override; + + virtual iodevice_t image_type() const override { return IO_CARTSLOT; } + 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 option_guide *create_option_guide() const override { return nullptr; } + 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() override; + +protected: + hp_optrom_cart_device *m_cart; + dynamic_buffer m_content; + offs_t m_base_addr; + offs_t m_end_addr; +}; + +// device type definition +extern const device_type HP_OPTROM_SLOT; +extern const device_type HP_OPTROM_CART; + +SLOT_INTERFACE_EXTERN(hp_optrom_slot_device); + +#endif /* _HP_OPTROM_H_ */ diff --git a/src/mame/drivers/hp9845.cpp b/src/mame/drivers/hp9845.cpp index 4890b0ad92e..9353ab4ed48 100644 --- a/src/mame/drivers/hp9845.cpp +++ b/src/mame/drivers/hp9845.cpp @@ -18,22 +18,22 @@ // - Text mode screen // - Keyboard // - T15 tape drive +// - Software list to load optional ROMs // What's not yet in: // - Beeper // - Graphic screen // - Better naming of tape drive image (it's now "magt", should be "t15") // - Better documentation of this file -// - Software list to load optional ROMs // What's wrong: // - I'm using character generator from HP64K (another driver of mine): no known dump of the original one // - Speed, as usual -// - There are a couple of undocumented opcodes that PPU executes at each keyboard interrupt: don't know if ignoring them is a Bad Thing (tm) or not #include "emu.h" #include "cpu/z80/z80.h" #include "softlist.h" #include "cpu/hphybrid/hphybrid.h" #include "machine/hp_taco.h" +#include "bus/hp_optroms/hp_optrom.h" #define BIT_MASK(n) (1U << (n)) @@ -674,7 +674,6 @@ static ADDRESS_MAP_START(global_mem_map , AS_PROGRAM , 16 , hp9845b_state) AM_RANGE(0x014000 , 0x017fff) AM_RAM AM_SHARE("ppu_ram") AM_RANGE(0x030000 , 0x037fff) AM_ROM AM_REGION("lpu" , 0) AM_RANGE(0x050000 , 0x057fff) AM_ROM AM_REGION("ppu" , 0) -//AM_RANGE(0x250000 , 0x251fff) AM_ROM AM_REGION("test_rom" , 0) ADDRESS_MAP_END static ADDRESS_MAP_START(ppu_io_map , AS_IO , 16 , hp9845b_state) @@ -719,6 +718,16 @@ static MACHINE_CONFIG_START( hp9845b, hp9845b_state ) MCFG_TACO_FLG_HANDLER(WRITELINE(hp9845b_state , t15_flg_w)) MCFG_TACO_STS_HANDLER(WRITELINE(hp9845b_state , t15_sts_w)) + // In real machine there were 8 slots for LPU ROMs and 8 slots for PPU ROMs in + // 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. + // For now we define just a couple of slots.. + MCFG_DEVICE_ADD("drawer1", HP_OPTROM_SLOT, 0) + MCFG_DEVICE_SLOT_INTERFACE(hp_optrom_slot_device, NULL, false) + MCFG_DEVICE_ADD("drawer2", HP_OPTROM_SLOT, 0) + MCFG_DEVICE_SLOT_INTERFACE(hp_optrom_slot_device, NULL, false) + MCFG_SOFTWARE_LIST_ADD("optrom_list", "hp9845b_rom") MACHINE_CONFIG_END @@ -755,10 +764,6 @@ ROM_END #define rom_hp9835b rom_hp9835a ROM_START( hp9845b ) - ROM_REGION(0x4000 , "test_rom" , ROMREGION_16BIT | ROMREGION_BE) - ROM_LOAD("09845-66520-45_00-Test_ROM.bin" , 0x0000 , 0x2000 , CRC(95a5b299)) - ROM_LOAD("09845-66520-45_10-Test_ROM.bin" , 0x2000 , 0x2000 , CRC(257e4c66)) - ROM_REGION(0x800 , "chargen" , 0) // Don't have the real character generator from HP9845, use the one from HP64000 for now ROM_LOAD("1818_2668.bin" , 0 , 0x800 , BAD_DUMP CRC(32a52664) SHA1(8b2a49a32510103ff424e8481d5ed9887f609f2f))