From 045f23d116e529110d45f052f8aed2b46f19444b Mon Sep 17 00:00:00 2001 From: fulivi Date: Sat, 24 Dec 2022 10:15:16 +0100 Subject: hp/hp9825.cpp: Added support for HP 9825A and HP 9831. (#10595) * bus/hp9845_io: Added HP9871 printer. New working machines ------------------ Hewlett-Packard HP 9825A Hewlett-Packard HP 9831A New working software list items ------------------ hp9825_rom: 9862 Plotter/Gen I/O ROM for 9825 hp9825_rom: General/extended I/O ROM for 9825 hp9825_rom: General/extended I/O/9862 plotter ROM for 9825 hp9825_rom: General/extended I/O/plotter ROM for 9825 hp9825_rom: Plotter/Gen I/O ROM for 9825 hp9825_rom: String/Advanced programming ROM for 9825 hp9831_rom: Mass storage ROM for 9831 New not working software list items ------------------ hp9831_rom: Matrix/plotter ROM for 9831 --- hash/hp9825_rom.xml | 161 +++++++++++ hash/hp9825b_rom.xml | 58 ---- hash/hp9831_rom.xml | 35 +++ scripts/src/bus.lua | 2 + src/devices/bus/hp9845_io/98032.cpp | 3 + src/devices/bus/hp9845_io/hp9871.cpp | 116 ++++++++ src/devices/bus/hp9845_io/hp9871.h | 54 ++++ src/mame/hp/hp9825.cpp | 545 ++++++++++++++++++++++++----------- src/mame/hp/hp9825_optrom.cpp | 20 +- src/mame/mame.lst | 2 + 10 files changed, 761 insertions(+), 235 deletions(-) create mode 100644 hash/hp9825_rom.xml delete mode 100644 hash/hp9825b_rom.xml create mode 100644 hash/hp9831_rom.xml create mode 100644 src/devices/bus/hp9845_io/hp9871.cpp create mode 100644 src/devices/bus/hp9845_io/hp9871.h diff --git a/hash/hp9825_rom.xml b/hash/hp9825_rom.xml new file mode 100644 index 00000000000..68dddcc7269 --- /dev/null +++ b/hash/hp9825_rom.xml @@ -0,0 +1,161 @@ + + + + + + + String/Advanced programming ROM for 9825 + 1976 + Hewlett-Packard + + + + + + + + + + + + + + Matrix ROM for 9825 + 1976 + Hewlett-Packard + + + + + + + + + + 9862 Plotter/Gen I/O ROM for 9825 + 1976 + Hewlett-Packard + + + + + + + + + + + + + + General/extended I/O ROM for 9825 + 1976 + Hewlett-Packard + + + + + + + + + + + + + + General/extended I/O/9862 plotter ROM for 9825 + 1976 + Hewlett-Packard + + + + + + + + + + + + + + + + + Plotter/Gen I/O ROM for 9825 + 1976 + Hewlett-Packard + + + + + + + + + + + + + + General/extended I/O/plotter ROM for 9825 + 1976 + Hewlett-Packard + + + + + + + + + + + + + + + + + 9885 ROM for 9825 + 1976 + Hewlett-Packard + + + + + + + + + + 9885/9895 ROM for 9825 + 1980 + Hewlett-Packard + + + + + + + + + + + SSS mass storage ROM + 1984 + Structured Software Systems + + + + + + + + diff --git a/hash/hp9825b_rom.xml b/hash/hp9825b_rom.xml deleted file mode 100644 index 61d3abe4537..00000000000 --- a/hash/hp9825b_rom.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - 9885 ROM for 9825 - 1976 - Hewlett-Packard - - - - - - - - - - 9885/9895 ROM for 9825 - 1980 - Hewlett-Packard - - - - - - - - - - SSS mass storage ROM - 1984 - Structured Software Systems - - - - - - - - - - Matrix ROM for 9825 - 1976 - Hewlett-Packard - - - - - - - - diff --git a/hash/hp9831_rom.xml b/hash/hp9831_rom.xml new file mode 100644 index 00000000000..a40a0b0819f --- /dev/null +++ b/hash/hp9831_rom.xml @@ -0,0 +1,35 @@ + + + + + + + Mass storage ROM for 9831 + 1977 + Hewlett-Packard + + + + + + + + + + Matrix/plotter ROM for 9831 + 1977 + Hewlett-Packard + + + + + + + + + diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 197b15c0f12..c8d387153e6 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -4771,6 +4771,8 @@ if (BUSES["HP9845_IO"]~=null) then MAME_DIR .. "src/devices/bus/hp9845_io/98036.h", MAME_DIR .. "src/devices/bus/hp9845_io/98046.cpp", MAME_DIR .. "src/devices/bus/hp9845_io/98046.h", + MAME_DIR .. "src/devices/bus/hp9845_io/hp9871.cpp", + MAME_DIR .. "src/devices/bus/hp9845_io/hp9871.h", MAME_DIR .. "src/devices/bus/hp9845_io/hp9885.cpp", MAME_DIR .. "src/devices/bus/hp9845_io/hp9885.h", } diff --git a/src/devices/bus/hp9845_io/98032.cpp b/src/devices/bus/hp9845_io/98032.cpp index ecfc92ba706..cb4ab45388c 100644 --- a/src/devices/bus/hp9845_io/98032.cpp +++ b/src/devices/bus/hp9845_io/98032.cpp @@ -13,6 +13,7 @@ #include "emu.h" #include "98032.h" +#include "hp9871.h" #include "hp9885.h" // Debugging @@ -94,6 +95,7 @@ void hp98032_io_card_device::device_reset() m_int_en = false; m_dma_en = false; m_busy = true; // Force reset + m_pready = false; m_auto_ah = false; set_busy(false); update_irq(); @@ -356,6 +358,7 @@ hp98032_gpio_slot_device::hp98032_gpio_slot_device(const machine_config &mconfig { option_reset(); option_add("loopback" , HP98032_GPIO_LOOPBACK); + option_add("hp9871" , HP9871); option_add("hp9885" , HP9885); set_default_option(nullptr); set_fixed(false); diff --git a/src/devices/bus/hp9845_io/hp9871.cpp b/src/devices/bus/hp9845_io/hp9871.cpp new file mode 100644 index 00000000000..cee0b5957cf --- /dev/null +++ b/src/devices/bus/hp9845_io/hp9871.cpp @@ -0,0 +1,116 @@ +// license:BSD-3-Clause +// copyright-holders: F. Ulivi +/********************************************************************* + + hp9871.cpp + + HP9871 daisy-wheel printer + +*********************************************************************/ + +#include "emu.h" +#include "hp9871.h" + +// device type definition +DEFINE_DEVICE_TYPE(HP9871, hp9871_device, "hp9871" , "HP9871 printer") + +hp9871_device::hp9871_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, HP9871, tag, owner, clock) + , device_hp98032_gpio_interface(mconfig, *this) + , m_printer(*this, "printer") +{ +} + +hp9871_device::~hp9871_device() +{ +} + +uint16_t hp9871_device::get_jumpers() const +{ + return hp98032_gpio_slot_device::JUMPER_3 | + hp98032_gpio_slot_device::JUMPER_5; +} + +uint16_t hp9871_device::input_r() const +{ + return 0; +} + +uint8_t hp9871_device::ext_status_r() const +{ + // Bit 0: Buffer space available (1) + // Bit 1: Ready (0) + uint8_t res = 0; + + if (m_printer->is_ready()) { + res |= 2; + } + + return res; +} + +void hp9871_device::output_w(uint16_t data) +{ + m_data = uint8_t(data); +} + +void hp9871_device::ext_control_w(uint8_t data) +{ + // N/U +} + +WRITE_LINE_MEMBER(hp9871_device::pctl_w) +{ + if (!state) { + m_ibf = true; + update_busy(); + } else { + output(m_printer->is_ready()); + } +} + +WRITE_LINE_MEMBER(hp9871_device::io_w) +{ + // N/U +} + +WRITE_LINE_MEMBER(hp9871_device::preset_w) +{ + // N/U +} + +void hp9871_device::device_add_mconfig(machine_config &config) +{ + PRINTER(config, m_printer, 0); + m_printer->online_callback().set(FUNC(hp9871_device::printer_online)); +} + +void hp9871_device::device_start() +{ +} + +void hp9871_device::device_reset() +{ + m_ibf = false; + update_busy(); + psts_w(1); +} + +WRITE_LINE_MEMBER(hp9871_device::printer_online) +{ + output(state); +} + +void hp9871_device::update_busy() +{ + pflg_w(!m_ibf); +} + +void hp9871_device::output(bool printer_ready) +{ + if (m_ibf && printer_ready) { + m_printer->output(m_data); + m_ibf = false; + update_busy(); + } +} diff --git a/src/devices/bus/hp9845_io/hp9871.h b/src/devices/bus/hp9845_io/hp9871.h new file mode 100644 index 00000000000..5b66b16d443 --- /dev/null +++ b/src/devices/bus/hp9845_io/hp9871.h @@ -0,0 +1,54 @@ +// license:BSD-3-Clause +// copyright-holders: F. Ulivi +/********************************************************************* + + hp9871.h + + HP9871 daisy-wheel printer + +*********************************************************************/ + +#ifndef MAME_BUS_HP9845_IO_HP9871_H +#define MAME_BUS_HP9845_IO_HP9871_H + +#pragma once + +#include "98032.h" +#include "imagedev/printer.h" + +class hp9871_device : public device_t, public device_hp98032_gpio_interface +{ +public: + hp9871_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual ~hp9871_device(); + + // hp98032_gpio_card_device overrides + virtual uint16_t get_jumpers() const override; + virtual uint16_t input_r() const override; + virtual uint8_t ext_status_r() const override; + virtual void output_w(uint16_t data) override; + virtual void ext_control_w(uint8_t data) override; + virtual DECLARE_WRITE_LINE_MEMBER(pctl_w) override; + virtual DECLARE_WRITE_LINE_MEMBER(io_w) override; + virtual DECLARE_WRITE_LINE_MEMBER(preset_w) override; + +protected: + // device-level overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + required_device m_printer; + + uint8_t m_data; + bool m_ibf; + + DECLARE_WRITE_LINE_MEMBER(printer_online); + void update_busy(); + void output(bool printer_ready); +}; + +DECLARE_DEVICE_TYPE(HP9871 , hp9871_device) + +#endif /* MAME_BUS_HP9845_IO_HP9871_H */ diff --git a/src/mame/hp/hp9825.cpp b/src/mame/hp/hp9825.cpp index a993c318981..808d0c6c07b 100644 --- a/src/mame/hp/hp9825.cpp +++ b/src/mame/hp/hp9825.cpp @@ -5,24 +5,21 @@ // Driver for HP 9825 systems // ************************** // -// **** Temporary header, will hopefully evolve into proper doc **** -// // What's in: -// - Emulation of 9825B and 9825T systems -// - 12 kw (9825B) or 31kw (9825T) of RAM +// - Emulation of 9825A, 9825B, 9825T and 9831A systems +// - 4,8,12 or 16 kw (9825A & 9831A), 12 kw (9825B) or 31kw (9825T) of RAM // - 12 kw of system ROM // - Keyboard // - Display & run light // - DC100 tape drive -// - Printer +// - Printer (N/A on 9831A) // - Beeper // - Internal expansion ROMs // - I/O expansion slots: 98032, 98034, 98035 & 98036 modules can be connected // - For 9825T: the so-called SKOAL mechanism that transparently overlays RAM & ROM // in the same address space // - External expansion ROMs -// What's not yet in: -// - Configurable RAM size +// - Configurable RAM size (9825A/9831A) // // Thanks to Dyke Shaffer for publishing (on https://groups.io/g/VintHPcom) // the source code of 98217 mass memory ROM. The 98217.bin image was reconstructed @@ -34,23 +31,23 @@ // content of SKOAL ROM from its printed & scanned dump. // I'd also like to thank Paul Berger for providing the images of the optional // mass storage ROMs (see http://www.hpmuseum.net). -// -// 9825A can also be emulated. At the moment I haven't all the necessary -// ROM dumps, though. #include "emu.h" -#include "cpu/hphybrid/hphybrid.h" -#include "machine/timer.h" + +#include "hp9825_optrom.h" #include "hp9825_tape.h" #include "hp98x5_io_sys.h" -#include "hp9825_optrom.h" + #include "bus/hp9845_io/hp9845_io.h" +#include "cpu/hphybrid/hphybrid.h" #include "imagedev/bitbngr.h" -#include "speaker.h" -#include "screen.h" +#include "machine/ram.h" +#include "machine/timer.h" #include "sound/beep.h" -#include "hp9825.lh" + +#include "screen.h" #include "softlist_dev.h" +#include "speaker.h" // Debugging #define VERBOSE 0 @@ -58,6 +55,10 @@ #define LOG_DBG_MASK (LOG_GENERAL << 1) #define LOG_DBG(...) LOGMASKED(LOG_DBG_MASK, __VA_ARGS__) +#include "hp9825.lh" + +namespace { + // CPU clock (generated by a trimmered RC oscillator) constexpr unsigned MAIN_CLOCK = 6000000; @@ -99,30 +100,41 @@ constexpr unsigned BEEPER_FREQ = 1400; constexpr unsigned BEEPER_MS = 22; // Bit manipulation -namespace { - template constexpr T BIT_MASK(unsigned n) - { - return (T)1U << n; - } +template constexpr T BIT_MASK(unsigned n) +{ + return (T)1U << n; +} - template void BIT_CLR(T& w , unsigned n) - { - w &= ~BIT_MASK(n); - } +template void BIT_CLR(T& w , unsigned n) +{ + w &= ~BIT_MASK(n); +} - template void BIT_SET(T& w , unsigned n) - { - w |= BIT_MASK(n); - } +template void BIT_SET(T& w , unsigned n) +{ + w |= BIT_MASK(n); } + // +--------------+ -// | hp9825_state | +// | hp98xx_state | // +--------------+ -class hp9825_state : public driver_device +// ↑ +// +-------------------+ +// ↑ ↑ +// +--------------+ +--------------+ +// | hp9825_state | | hp9831_state | +// +--------------+ +--------------+ +// ↑ +// +-------------------+------------------+ +// ↑ ↑ ↑ +// +---------------+ +---------------+ +---------------+ +// | hp9825a_state | | hp9825b_state | | hp9825t_state | +// +---------------+ +---------------+ +---------------+ +class hp98xx_state : public driver_device { public: - hp9825_state(const machine_config &mconfig, device_type type, const char *tag) + hp98xx_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_cpu(*this , "cpu") , m_rom_drawers(*this , "drawer%u" , 0U) @@ -131,52 +143,46 @@ public: , m_tape(*this , "tape") , m_io_key(*this , "KEY%u" , 0) , m_shift_key(*this , "KEY_SHIFT") - , m_scroll_key(*this , "KEY_SCROLL") - , m_prt_alpha_out(*this , "prt_alpha") - , m_prt_graph_out(*this , "prt_graph") , m_prt_timer(*this , "prt_timer") , m_beeper(*this , "beeper") , m_beep_timer(*this , "beep_timer") , m_io_slot(*this, "slot%u", 0U) - , m_prt_out(*this, "printer") , m_display(*this , "char_%u_%u" , 0U , 0U) , m_run_light(*this , "run_light") , m_shift_lock(*this , "shift_lock") , m_tape_led(*this , "tape_led") , m_cassette(*this , "cassette") - , m_printer_bitmap(PRINT_OUT_W , PRINT_OUT_H) { } - void hp9825_base(machine_config &config); - DECLARE_INPUT_CHANGED_MEMBER(kb_changed); - DECLARE_INPUT_CHANGED_MEMBER(scroll_changed); - - uint32_t printer_out_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); protected: + void hp98xx_base(machine_config &config); + virtual void machine_start() override; virtual void device_reset() override; virtual void machine_reset() override; + virtual void print_line(); required_device m_cpu; required_device_array m_rom_drawers; + // Printer + uint8_t m_printer_mem[ PRINT_COLUMNS ]; + uint8_t m_printer_idx; + unsigned m_printer_line; // 0: printer idle, 1..10: line being printed + private: required_device m_io_sys; required_device m_cursor_timer; required_device m_tape; required_ioport_array<4> m_io_key; required_ioport m_shift_key; - required_ioport m_scroll_key; - required_device m_prt_alpha_out; - required_device m_prt_graph_out; required_device m_prt_timer; required_device m_beeper; required_device m_beep_timer; required_device_array m_io_slot; - required_device m_prt_out; output_finder<32 , 7> m_display; output_finder<> m_run_light; output_finder<> m_shift_lock; @@ -193,12 +199,6 @@ private: bool m_key_pressed; bool m_autorepeating; unsigned m_autorepeat_cnt; - // Printer - uint8_t m_printer_mem[ PRINT_COLUMNS ]; - uint8_t m_printer_idx; - unsigned m_printer_line; // 0: printer idle, 1..10: line being printed - bitmap_rgb32 m_printer_bitmap; - unsigned m_printer_window; // 0 is bottom window (the one closer to printhead) // SC of slots int m_slot_sc[ 3 ]; @@ -226,7 +226,7 @@ private: void set_dmar_slot(unsigned slot , int state); }; -void hp9825_state::machine_start() +void hp98xx_state::machine_start() { m_display.resolve(); m_run_light.resolve(); @@ -234,16 +234,13 @@ void hp9825_state::machine_start() m_tape_led.resolve(); m_cassette.resolve(); - m_printer_bitmap.fill(PRINT_BG); - m_printer_window = 0; - save_item(NAME(m_display_on)); save_item(NAME(m_display_mem)); save_item(NAME(m_display_idx)); save_item(NAME(m_scancode)); } -void hp9825_state::device_reset() +void hp98xx_state::device_reset() { // First, unmap every r/w handler in 1..12 select codes for (unsigned sc = IO_SLOT_FIRST_PA; sc < (IO_SLOT_LAST_PA + 1); sc++) { @@ -263,7 +260,7 @@ void hp9825_state::device_reset() } } -void hp9825_state::machine_reset() +void hp98xx_state::machine_reset() { m_display_on = false; m_display_idx = 0; @@ -284,17 +281,20 @@ void hp9825_state::machine_reset() m_beep_timer->reset(); } -void hp9825_state::cpu_io_map(address_map &map) +void hp98xx_state::print_line() +{ +} + +void hp98xx_state::cpu_io_map(address_map &map) { map.unmap_value_low(); - map(HP_MAKE_IOADDR(KDP_PA , 0) , HP_MAKE_IOADDR(KDP_PA , 0)).rw(FUNC(hp9825_state::kb_scancode_r) , FUNC(hp9825_state::disp_w)); - map(HP_MAKE_IOADDR(KDP_PA , 1) , HP_MAKE_IOADDR(KDP_PA , 1)).rw(FUNC(hp9825_state::kdp_status_r) , FUNC(hp9825_state::kdp_control_w)); - map(HP_MAKE_IOADDR(KDP_PA , 2) , HP_MAKE_IOADDR(KDP_PA , 2)).w(FUNC(hp9825_state::printer_w)); + map(HP_MAKE_IOADDR(KDP_PA , 0) , HP_MAKE_IOADDR(KDP_PA , 0)).rw(FUNC(hp98xx_state::kb_scancode_r) , FUNC(hp98xx_state::disp_w)); + map(HP_MAKE_IOADDR(KDP_PA , 1) , HP_MAKE_IOADDR(KDP_PA , 1)).rw(FUNC(hp98xx_state::kdp_status_r) , FUNC(hp98xx_state::kdp_control_w)); + map(HP_MAKE_IOADDR(KDP_PA , 2) , HP_MAKE_IOADDR(KDP_PA , 2)).w(FUNC(hp98xx_state::printer_w)); map(HP_MAKE_IOADDR(TAPE_PA , 0) , HP_MAKE_IOADDR(TAPE_PA , 3)).rw(m_tape , FUNC(hp9825_tape_device::tape_r) , FUNC(hp9825_tape_device::tape_w)); - // TODO: } -uint16_t hp9825_state::kb_scancode_r() +uint16_t hp98xx_state::kb_scancode_r() { uint8_t res = m_scancode; if (BIT(m_shift_key->read() , 0) || m_shift_lock) { @@ -304,7 +304,7 @@ uint16_t hp9825_state::kb_scancode_r() return res; } -void hp9825_state::disp_w(uint16_t data) +void hp98xx_state::disp_w(uint16_t data) { if (m_display_on) { m_display_on = false; @@ -316,7 +316,7 @@ void hp9825_state::disp_w(uint16_t data) m_display_mem[ m_display_idx++ ] = uint8_t(data); } -uint16_t hp9825_state::kdp_status_r() +uint16_t hp98xx_state::kdp_status_r() { uint16_t res = 0; if (m_io_sys->is_irq_pending(KDP_PA)) { @@ -332,7 +332,7 @@ uint16_t hp9825_state::kdp_status_r() return res; } -void hp9825_state::kdp_control_w(uint16_t data) +void hp98xx_state::kdp_control_w(uint16_t data) { bool regen_display = false; if (BIT(data , 1) && !m_display_on) { @@ -361,11 +361,6 @@ void hp9825_state::kdp_control_w(uint16_t data) } if (BIT(data , 0) && m_printer_line == 0) { // Start printing - // Dump text line to alpha bitbanger - for (auto c : m_printer_mem) { - m_prt_alpha_out->output(c); - } - m_prt_alpha_out->output('\n'); m_printer_idx = 0; m_printer_line++; m_prt_timer->adjust(attotime::from_ticks(KDP_CLOCKS_PER_LINE , KDP_CLOCK)); @@ -380,7 +375,7 @@ void hp9825_state::kdp_control_w(uint16_t data) } } -void hp9825_state::printer_w(uint16_t data) +void hp98xx_state::printer_w(uint16_t data) { m_printer_mem[ m_printer_idx ] = uint8_t(data); m_printer_idx = (m_printer_idx + 1) % PRINT_COLUMNS; @@ -519,7 +514,7 @@ static const uint8_t chargen[ 128 ][ 5 ] = { { 0x7f,0x08,0x08,0x08,0x08 } // 7f }; -void hp9825_state::update_display() +void hp98xx_state::update_display() { m_any_cursor = false; for (unsigned i = 0; i < 32; ++i) { @@ -555,7 +550,7 @@ void hp9825_state::update_display() } } -TIMER_DEVICE_CALLBACK_MEMBER(hp9825_state::cursor_blink) +TIMER_DEVICE_CALLBACK_MEMBER(hp98xx_state::cursor_blink) { m_cursor_blink = !m_cursor_blink; if (m_any_cursor) { @@ -563,7 +558,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(hp9825_state::cursor_blink) } } -TIMER_DEVICE_CALLBACK_MEMBER(hp9825_state::kb_scan) +TIMER_DEVICE_CALLBACK_MEMBER(hp98xx_state::kb_scan) { ioport_value input[ 4 ] { m_io_key[ 0 ]->read(), @@ -606,7 +601,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(hp9825_state::kb_scan) } } -INPUT_CHANGED_MEMBER(hp9825_state::kb_changed) +INPUT_CHANGED_MEMBER(hp98xx_state::kb_changed) { switch (param) { case 0: @@ -634,27 +629,7 @@ INPUT_CHANGED_MEMBER(hp9825_state::kb_changed) } } -INPUT_CHANGED_MEMBER(hp9825_state::scroll_changed) -{ - LOG_DBG("scroll p=%d n=%d\n" , param , newval); - switch (param) { - case 0: - // Scroll up - if (newval && m_printer_window > 0) { - m_printer_window--; - } - break; - - case 1: - // Scroll down - if (newval && m_printer_window < (PRINT_WINDOWS - 1)) { - m_printer_window++; - } - break; - } -} - -void hp9825_state::kb_scan_ioport(ioport_value pressed , ioport_port &port , unsigned idx_base , int& max_seq_len , unsigned& max_seq_idx) +void hp98xx_state::kb_scan_ioport(ioport_value pressed , ioport_port &port , unsigned idx_base , int& max_seq_len , unsigned& max_seq_idx) { while (pressed) { unsigned bit_no = 31 - count_leading_zeros_32(pressed); @@ -668,39 +643,9 @@ void hp9825_state::kb_scan_ioport(ioport_value pressed , ioport_port &port , uns } } -TIMER_DEVICE_CALLBACK_MEMBER(hp9825_state::prt_timer) +TIMER_DEVICE_CALLBACK_MEMBER(hp98xx_state::prt_timer) { - // Shift printer bitmap one line up and clear bottom line - { - bitmap_rgb32 tmp{ m_printer_bitmap.width() , m_printer_bitmap.height() }; - s32 scroll = -1; - rectangle cliprect{ 0 , m_printer_bitmap.width() - 1 , 0 , m_printer_bitmap.height() - 2 }; - copyscrollbitmap(tmp , m_printer_bitmap , 0 , nullptr , 1 , &scroll , cliprect); - copybitmap(m_printer_bitmap , tmp , 0 , 0 , 0 , 0 , cliprect); - m_printer_bitmap.plot_box(0 , m_printer_bitmap.height() - 1 , m_printer_bitmap.width() , 1 , PRINT_BG); - } - - if ((m_printer_line > 0 && m_printer_line <= PRINT_EMPTY_TOP) || - (m_printer_line > (PRINT_EMPTY_TOP + PRINT_MATRIX_H) && m_printer_line <= PRINT_CELL_H)) { - // Empty lines - for (unsigned i = 0; i < PRINT_PIXELS_ROW; i++) { - m_prt_graph_out->output(' '); - } - } else { - for (unsigned i = 0; i < PRINT_COLUMNS; i++) { - for (unsigned col = 0; col < PRINT_MATRIX_W; col++) { - uint8_t pixels = chargen[ m_printer_mem[ i ] & 0x7f ][ col ]; - bool pixel = BIT(pixels , m_printer_line - PRINT_EMPTY_TOP - 1); - m_prt_graph_out->output(pixel ? '*' : ' '); - if (pixel) { - m_printer_bitmap.pix(m_printer_bitmap.height() - 1 , i * PRINT_CELL_W + col) = PRINT_FG; - } - } - m_prt_graph_out->output(' '); - m_prt_graph_out->output(' '); - } - } - m_prt_graph_out->output('\n'); + print_line(); m_printer_line++; if (m_printer_line <= PRINT_CELL_H) { m_prt_timer->adjust(attotime::from_ticks(KDP_CLOCKS_PER_LINE , KDP_CLOCK)); @@ -709,54 +654,46 @@ TIMER_DEVICE_CALLBACK_MEMBER(hp9825_state::prt_timer) } } -uint32_t hp9825_state::printer_out_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - s32 scroll = -s32((PRINT_WINDOWS - m_printer_window - 1) * PRINT_WIN_H); - copyscrollbitmap(bitmap , m_printer_bitmap , 0 , nullptr , 1 , &scroll , cliprect); - - return 0; -} - -TIMER_DEVICE_CALLBACK_MEMBER(hp9825_state::beep_timer) +TIMER_DEVICE_CALLBACK_MEMBER(hp98xx_state::beep_timer) { m_beeper->set_state(0); } -void hp9825_state::set_irq_slot(unsigned slot , int state) +void hp98xx_state::set_irq_slot(unsigned slot , int state) { int sc = m_slot_sc[ slot ]; assert(sc >= 0); m_io_sys->set_irq(uint8_t(sc) , state); } -void hp9825_state::set_sts_slot(unsigned slot , int state) +void hp98xx_state::set_sts_slot(unsigned slot , int state) { int sc = m_slot_sc[ slot ]; assert(sc >= 0); m_io_sys->set_sts(uint8_t(sc) , state); } -void hp9825_state::set_flg_slot(unsigned slot , int state) +void hp98xx_state::set_flg_slot(unsigned slot , int state) { int sc = m_slot_sc[ slot ]; assert(sc >= 0); m_io_sys->set_flg(uint8_t(sc) , state); } -void hp9825_state::set_dmar_slot(unsigned slot , int state) +void hp98xx_state::set_dmar_slot(unsigned slot , int state) { int sc = m_slot_sc[ slot ]; assert(sc >= 0); m_io_sys->set_dmar(uint8_t(sc) , state); } -void hp9825_state::hp9825_base(machine_config &config) +void hp98xx_state::hp98xx_base(machine_config &config) { HP_09825_67907(config , m_cpu , MAIN_CLOCK); // Just guessing... settings borrowed from hp9845 m_cpu->set_rw_cycles(6 , 6); m_cpu->set_relative_mode(false); - m_cpu->set_addrmap(AS_IO , &hp9825_state::cpu_io_map); + m_cpu->set_addrmap(AS_IO , &hp98xx_state::cpu_io_map); m_cpu->set_int_cb(m_io_sys , FUNC(hp98x5_io_sys_device::int_r)); m_cpu->pa_changed_cb().set(m_io_sys , FUNC(hp98x5_io_sys_device::pa_w)); @@ -770,10 +707,10 @@ void hp9825_state::hp9825_base(machine_config &config) m_io_sys->flg().set(m_cpu , FUNC(hp_09825_67907_cpu_device::flag_w)); m_io_sys->dmar().set(m_cpu , FUNC(hp_09825_67907_cpu_device::dmar_w)); - TIMER(config , m_cursor_timer , 0).configure_generic(FUNC(hp9825_state::cursor_blink)); + TIMER(config , m_cursor_timer , 0).configure_generic(FUNC(hp98xx_state::cursor_blink)); // Keyboard scan timer. A scan of the whole keyboard should take 2^14 KDP clocks. - TIMER(config , "kb_timer" , 0).configure_periodic(FUNC(hp9825_state::kb_scan), attotime::from_ticks(16384 , KDP_CLOCK)); + TIMER(config , "kb_timer" , 0).configure_periodic(FUNC(hp98xx_state::kb_scan), attotime::from_ticks(16384 , KDP_CLOCK)); // Tape drive HP9825_TAPE(config , m_tape , 0); @@ -784,19 +721,12 @@ void hp9825_state::hp9825_base(machine_config &config) m_tape->cart_in().set([this](int state) { if (started()) m_cassette = state; }); // Printer - BITBANGER(config , m_prt_alpha_out , 0); - BITBANGER(config , m_prt_graph_out , 0); - TIMER(config , m_prt_timer , 0).configure_generic(FUNC(hp9825_state::prt_timer)); - SCREEN(config , m_prt_out , SCREEN_TYPE_RASTER); - m_prt_out->set_screen_update(FUNC(hp9825_state::printer_out_update)); - m_prt_out->set_refresh_hz(60); - m_prt_out->set_size(PRINT_WIN_W, PRINT_WIN_H); - m_prt_out->set_visarea_full(); + TIMER(config , m_prt_timer , 0).configure_generic(FUNC(hp98xx_state::prt_timer)); // Beeper SPEAKER(config, "mono").front_center(); BEEP(config, m_beeper, BEEPER_FREQ).add_route(ALL_OUTPUTS, "mono", 1.00); - TIMER(config , m_beep_timer , 0).configure_generic(FUNC(hp9825_state::beep_timer)); + TIMER(config , m_beep_timer , 0).configure_generic(FUNC(hp98xx_state::beep_timer)); // I/O slots for (unsigned slot = 0; slot < 3; slot++) { @@ -818,7 +748,7 @@ void hp9825_state::hp9825_base(machine_config &config) #define IOP_MASK(x) BIT_MASK((x)) -static INPUT_PORTS_START(hp9825) +static INPUT_PORTS_START(hp98xx) // Keyboard is arranged in a 8 x 16 matrix. Of the 128 possible positions, 102 are used. // Keys are mapped on bit b of KEYn // where b = (row & 1) << 4 + column, n = row >> 1 @@ -965,15 +895,205 @@ static INPUT_PORTS_START(hp9825) PORT_BIT(IOP_MASK(31) , IP_ACTIVE_HIGH , IPT_UNUSED) // 7,15: N/U PORT_START("KEY_SHIFT") - PORT_BIT(IOP_MASK(0) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_CHANGED_MEMBER(DEVICE_SELF, hp9825_state, kb_changed, 0) // Left and right Shift - PORT_BIT(IOP_MASK(1) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("Shift lock") PORT_CHANGED_MEMBER(DEVICE_SELF, hp9825_state, kb_changed, 1) // Shift lock - PORT_BIT(IOP_MASK(2) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("Reset") PORT_CHANGED_MEMBER(DEVICE_SELF, hp9825_state, kb_changed, 2) // Reset + PORT_BIT(IOP_MASK(0) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_CHANGED_MEMBER(DEVICE_SELF, hp98xx_state, kb_changed, 0) // Left and right Shift + PORT_BIT(IOP_MASK(1) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("Shift lock") PORT_CHANGED_MEMBER(DEVICE_SELF, hp98xx_state, kb_changed, 1) // Shift lock + PORT_BIT(IOP_MASK(2) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("Reset") PORT_CHANGED_MEMBER(DEVICE_SELF, hp98xx_state, kb_changed, 2) // Reset +INPUT_PORTS_END + +// +--------------+ +// | hp9825_state | +// +--------------+ +class hp9825_state : public hp98xx_state +{ +public: + hp9825_state(const machine_config &mconfig, device_type type, const char *tag) + : hp98xx_state(mconfig, type, tag) + , m_scroll_key(*this , "KEY_SCROLL") + , m_prt_alpha_out(*this , "prt_alpha") + , m_prt_graph_out(*this , "prt_graph") + , m_prt_out(*this, "printer") + , m_printer_bitmap(PRINT_OUT_W , PRINT_OUT_H) + { + } + + DECLARE_INPUT_CHANGED_MEMBER(scroll_changed); + + uint32_t printer_out_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + +protected: + void hp9825_base(machine_config &config); + + virtual void machine_start() override; + + virtual void print_line() override; + +private: + required_ioport m_scroll_key; + required_device m_prt_alpha_out; + required_device m_prt_graph_out; + required_device m_prt_out; + + unsigned m_printer_window; // 0 is bottom window (the one closer to printhead) + bitmap_rgb32 m_printer_bitmap; +}; + +void hp9825_state::hp9825_base(machine_config &config) +{ + hp98xx_base(config); + + // Printer + BITBANGER(config , m_prt_alpha_out , 0); + BITBANGER(config , m_prt_graph_out , 0); + SCREEN(config , m_prt_out , SCREEN_TYPE_RASTER); + m_prt_out->set_screen_update(FUNC(hp9825_state::printer_out_update)); + m_prt_out->set_refresh_hz(60); + m_prt_out->set_size(PRINT_WIN_W, PRINT_WIN_H); + m_prt_out->set_visarea_full(); +} + +INPUT_CHANGED_MEMBER(hp9825_state::scroll_changed) +{ + LOG_DBG("scroll p=%d n=%d\n" , param , newval); + switch (param) { + case 0: + // Scroll up + if (newval && m_printer_window > 0) { + m_printer_window--; + } + break; + + case 1: + // Scroll down + if (newval && m_printer_window < (PRINT_WINDOWS - 1)) { + m_printer_window++; + } + break; + } +} + +void hp9825_state::machine_start() +{ + hp98xx_state::machine_start(); + + m_printer_bitmap.fill(PRINT_BG); + m_printer_window = 0; +} + +void hp9825_state::print_line() +{ + // Dump text line to alpha bitbanger at start of print + if (m_printer_line == 1) { + for (auto c : m_printer_mem) { + m_prt_alpha_out->output(c); + } + m_prt_alpha_out->output('\n'); + } + + // Shift printer bitmap one line up and clear bottom line + { + bitmap_rgb32 tmp{ m_printer_bitmap.width() , m_printer_bitmap.height() }; + s32 scroll = -1; + rectangle cliprect{ 0 , m_printer_bitmap.width() - 1 , 0 , m_printer_bitmap.height() - 2 }; + copyscrollbitmap(tmp , m_printer_bitmap , 0 , nullptr , 1 , &scroll , cliprect); + copybitmap(m_printer_bitmap , tmp , 0 , 0 , 0 , 0 , cliprect); + m_printer_bitmap.plot_box(0 , m_printer_bitmap.height() - 1 , m_printer_bitmap.width() , 1 , PRINT_BG); + } + + if ((m_printer_line > 0 && m_printer_line <= PRINT_EMPTY_TOP) || + (m_printer_line > (PRINT_EMPTY_TOP + PRINT_MATRIX_H) && m_printer_line <= PRINT_CELL_H)) { + // Empty lines + for (unsigned i = 0; i < PRINT_PIXELS_ROW; i++) { + m_prt_graph_out->output(' '); + } + } else { + for (unsigned i = 0; i < PRINT_COLUMNS; i++) { + for (unsigned col = 0; col < PRINT_MATRIX_W; col++) { + uint8_t pixels = chargen[ m_printer_mem[ i ] & 0x7f ][ col ]; + bool pixel = BIT(pixels , m_printer_line - PRINT_EMPTY_TOP - 1); + m_prt_graph_out->output(pixel ? '*' : ' '); + if (pixel) { + m_printer_bitmap.pix(m_printer_bitmap.height() - 1 , i * PRINT_CELL_W + col) = PRINT_FG; + } + } + m_prt_graph_out->output(' '); + m_prt_graph_out->output(' '); + } + } + m_prt_graph_out->output('\n'); +} + +uint32_t hp9825_state::printer_out_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + s32 scroll = -s32((PRINT_WINDOWS - m_printer_window - 1) * PRINT_WIN_H); + copyscrollbitmap(bitmap , m_printer_bitmap , 0 , nullptr , 1 , &scroll , cliprect); + + return 0; +} + +static INPUT_PORTS_START(hp9825) + PORT_INCLUDE(hp98xx) PORT_START("KEY_SCROLL") PORT_BIT(IOP_MASK(0) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("Scroll up") PORT_CHANGED_MEMBER(DEVICE_SELF, hp9825_state, scroll_changed, 0) PORT_BIT(IOP_MASK(1) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("Scroll down") PORT_CHANGED_MEMBER(DEVICE_SELF, hp9825_state, scroll_changed, 1) INPUT_PORTS_END +// +---------------+ +// | hp9825a_state | +// +---------------+ +class hp9825a_state : public hp9825_state +{ +public: + hp9825a_state(const machine_config &mconfig, device_type type, const char *tag) + : hp9825_state(mconfig , type , tag) + , m_ram(*this, RAM_TAG) + { + } + + void hp9825a(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + required_device m_ram; + + void cpu_mem_map(address_map &map); +}; + +void hp9825a_state::hp9825a(machine_config &config) +{ + hp9825_base(config); + m_cpu->set_addrmap(AS_PROGRAM , &hp9825a_state::cpu_mem_map); + + RAM(config, m_ram); + + m_ram->set_default_size("8K").set_extra_options("16K,24K,32K"); + + SOFTWARE_LIST(config, "optrom_list").set_original("hp9825_rom").set_filter("A"); +} + +void hp9825a_state::machine_start() +{ + hp9825_state::machine_start(); + + offs_t ram_start = 0x8000U - m_ram->size() / 2; + + auto space = &m_cpu->space(AS_PROGRAM); + space->install_ram(ram_start, 0x7fff, m_ram->pointer()); + + for (auto& finder : m_rom_drawers) { + finder->set_rom_limit(ram_start); + finder->install_rw_handlers(space , nullptr); + } +} + +void hp9825a_state::cpu_mem_map(address_map &map) +{ + map.unmap_value_low(); + map(0x0000 , 0x2fff).rom(); +} + // +---------------+ // | hp9825b_state | // +---------------+ @@ -988,7 +1108,7 @@ public: void hp9825b(machine_config &config); protected: - virtual void device_reset() override; + virtual void machine_start() override; private: void cpu_mem_map(address_map &map); @@ -1003,12 +1123,12 @@ void hp9825b_state::hp9825b(machine_config &config) finder->set_rom_limit(0x5000); } - SOFTWARE_LIST(config, "optrom_list").set_original("hp9825b_rom"); + SOFTWARE_LIST(config, "optrom_list").set_original("hp9825_rom").set_filter("B"); } -void hp9825b_state::device_reset() +void hp9825b_state::machine_start() { - hp9825_state::device_reset(); + hp9825_state::machine_start(); auto space = &m_cpu->space(AS_PROGRAM); @@ -1093,7 +1213,7 @@ void hp9825t_state::hp9825t(machine_config &config) finder->set_rom_limit(0x6000); } - SOFTWARE_LIST(config, "optrom_list").set_original("hp9825b_rom"); + SOFTWARE_LIST(config, "optrom_list").set_original("hp9825_rom").set_filter("T"); } void hp9825t_state::machine_start() @@ -1106,7 +1226,7 @@ void hp9825t_state::machine_start() void hp9825t_state::device_reset() { - hp9825_state::device_reset(); + hp98xx_state::device_reset(); for (auto& finder : m_rom_drawers) { finder->install_rw_handlers(m_rom_space , m_ram_space); @@ -1285,6 +1405,89 @@ bool hp9825t_state::is_rom(uint16_t addr , uint8_t cycle_type) const } } +// +--------------+ +// | hp9831_state | +// +--------------+ +class hp9831_state : public hp98xx_state +{ +public: + hp9831_state(const machine_config &mconfig, device_type type, const char *tag) + : hp98xx_state(mconfig , type , tag) + , m_ram(*this, RAM_TAG) + { + } + + void hp9831(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + required_device m_ram; + + void cpu_mem_map(address_map &map); +}; + +void hp9831_state::hp9831(machine_config &config) +{ + hp98xx_base(config); + m_cpu->set_addrmap(AS_PROGRAM , &hp9831_state::cpu_mem_map); + + RAM(config, m_ram); + + m_ram->set_default_size("8K").set_extra_options("16K,24K,32K"); + + SOFTWARE_LIST(config, "optrom_list").set_original("hp9831_rom"); +} + +void hp9831_state::machine_start() +{ + hp98xx_state::machine_start(); + + offs_t ram_start = 0x8000U - m_ram->size() / 2; + + auto space = &m_cpu->space(AS_PROGRAM); + space->install_ram(ram_start, 0x7fff, m_ram->pointer()); + + for (auto& finder : m_rom_drawers) { + finder->set_rom_limit(ram_start); + finder->install_rw_handlers(space , nullptr); + } +} + +void hp9831_state::cpu_mem_map(address_map &map) +{ + map.unmap_value_low(); + map(0x0000 , 0x2fff).rom(); +} + +static INPUT_PORTS_START(hp9831) + PORT_INCLUDE(hp98xx) + + PORT_MODIFY("KEY0") + PORT_BIT(IOP_MASK(7) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME(u8"\u2191") // 0,7: ↑ + PORT_BIT(IOP_MASK(8) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("Line delete") // 0,8: Line delete + PORT_BIT(IOP_MASK(9) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("Line step") // 0,9: Line step + PORT_BIT(IOP_MASK(22) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_INSERT) PORT_NAME("Char insert") // 1,6: Char insert + PORT_BIT(IOP_MASK(24) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("Init") // 1,8: Init + PORT_BIT(IOP_MASK(27) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("Trace") // 1,11: Trace + PORT_BIT(IOP_MASK(30) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("Store") // 1,14: Store + + PORT_MODIFY("KEY1") + PORT_BIT(IOP_MASK(27) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') // 3,11: ; + PORT_BIT(IOP_MASK(31) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') // 3,15: / + + PORT_MODIFY("KEY3") + PORT_BIT(IOP_MASK(27) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('|') // 7,11: - + PORT_BIT(IOP_MASK(29) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("Result") // 7,13: Result + +INPUT_PORTS_END + +ROM_START(hp9825a) + ROM_REGION(0x6000 , "cpu" , ROMREGION_16BIT | ROMREGION_BE) + ROM_LOAD("9825asys.bin", 0x0000, 0x6000, CRC(bda0ddfa) SHA1(890993889adf0e48b6011fcc92603b89cf9af4a3)) +ROM_END + ROM_START(hp9825b) ROM_REGION(0xa000 , "cpu" , ROMREGION_16BIT | ROMREGION_BE) ROM_LOAD("sysrom1.bin" , 0x0000 , 0x2000 , CRC(fe429268) SHA1(f2fe7c5abca92bd13f81b4385fc4fce0cafb0da0)) @@ -1313,6 +1516,16 @@ ROM_START(hp9825t) ROM_LOAD("skoalrom.bin" , 0 , 0x1000 , CRC(5e8124d5) SHA1(dedf7f8a10c62b444f04213956083089e97bf219)) ROM_END +ROM_START(hp9831) + ROM_REGION(0x6000 , "cpu" , ROMREGION_16BIT | ROMREGION_BE) + ROM_LOAD("9831sys.bin", 0x0000, 0x6000, CRC(2f92e685) SHA1(413aa65677ab0d6b5979af6c9da12c1368abcc82)) +ROM_END + +} // anonymous namespace + + // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP(1976, hp9825a, 0, 0, hp9825a, hp9825, hp9825a_state,empty_init, "Hewlett-Packard", "HP 9825A", 0) COMP(1980, hp9825b, 0, 0, hp9825b, hp9825, hp9825b_state,empty_init, "Hewlett-Packard", "HP 9825B", 0) COMP(1980, hp9825t, 0, 0, hp9825t, hp9825, hp9825t_state,empty_init, "Hewlett-Packard", "HP 9825T", 0) +COMP(1977, hp9831, 0, 0, hp9831, hp9831, hp9831_state, empty_init, "Hewlett-Packard", "HP 9831A", 0) diff --git a/src/mame/hp/hp9825_optrom.cpp b/src/mame/hp/hp9825_optrom.cpp index 1466bf25b83..b3ad2b115ed 100644 --- a/src/mame/hp/hp9825_optrom.cpp +++ b/src/mame/hp/hp9825_optrom.cpp @@ -24,7 +24,7 @@ struct optrom_region { const char *m_tag; }; -constexpr std::array region_tab = +constexpr std::array region_tab = {{ { 0x3000 , 0x400 , "rom3000" }, { 0x3400 , 0x400 , "rom3400" }, @@ -33,7 +33,8 @@ constexpr std::array region_tab = { 0x4000 , 0x400 , "rom4000" }, { 0x4400 , 0x800 , "rom4400" }, { 0x4c00 , 0x400 , "rom4c00" }, - { 0x5c00 ,0x2000 , "rom5c00" } + { 0x5c00 ,0x2000 , "rom5c00" }, + { 0x3000 ,0x1000 , "rom3000_3fff" } }}; // +--------------------+ @@ -70,6 +71,9 @@ void hp9825_optrom_device::install_rw_handlers(address_space *space_r , address_ uint8_t *ptr = get_software_region(reg.m_tag); if (ptr != nullptr) { LOG("%s loaded\n" , reg.m_tag); + if (reg.m_start >= m_rom_limit) { + throw emu_fatalerror(util::string_format("ROM @%04x is not compatible with current amount of RAM", reg.m_start)); + } if (reg.m_start == 0x5c00) { space_r->install_rom(0x3000 , 0x33ff , ptr); space_r->install_device(0x5c00 , 0x5fff , *m_bank , &address_map_bank_device::amap16); @@ -111,15 +115,9 @@ image_init_result hp9825_optrom_device::call_load() for (const struct optrom_region& reg : region_tab) { auto len = get_software_region_length(reg.m_tag) / 2; - if (len != 0) { - if (len != reg.m_size) { - LOG("Region %s: wrong size (%u should be %u)\n" , reg.m_tag , len , reg.m_size); - return image_init_result::FAIL; - } - if (reg.m_start >= m_rom_limit) { - LOG("Region %s beyond ROM limit (start=%04x , limit=%04x)\n" , reg.m_tag , reg.m_start , m_rom_limit); - return image_init_result::FAIL; - } + if (len != 0 && len != reg.m_size) { + LOG("Region %s: wrong size (%u should be %u)\n" , reg.m_tag , len , reg.m_size); + return image_init_result::FAIL; } } diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 0487102fc97..1a9f9212b2e 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -17262,8 +17262,10 @@ hp700_92 // hp95lx // @source:hp/hp9825.cpp +hp9825a // HP 9825A hp9825b // HP 9825B hp9825t // HP 9825T +hp9831 // HP 9831A @source:hp/hp9845.cpp hp9835a // -- cgit v1.2.3