From 619a9ab92e36af5fd72ae90b093283285c803f72 Mon Sep 17 00:00:00 2001 From: Sergey Svishchev Date: Mon, 3 Sep 2018 02:16:16 +0300 Subject: hp95lx: new NOT_WORKING machine -- Hewlett-Packard 95LX palmtop --- scripts/target/mame/mess.lua | 1 + src/emu/xtal.cpp | 1 + src/mame/drivers/hp95lx.cpp | 771 +++++++++++++++++++++++++++++++++++++++++++ src/mame/mame.lst | 3 + src/mame/mess.flt | 1 + 5 files changed, 777 insertions(+) create mode 100644 src/mame/drivers/hp95lx.cpp diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 58c7e8fadda..8c60f81af4e 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -2260,6 +2260,7 @@ files { MAME_DIR .. "src/mame/drivers/hp2620.cpp", MAME_DIR .. "src/mame/drivers/hp700.cpp", MAME_DIR .. "src/mame/drivers/hp2640.cpp", + MAME_DIR .. "src/mame/drivers/hp95lx.cpp", MAME_DIR .. "src/mame/drivers/hp9825.cpp", } diff --git a/src/emu/xtal.cpp b/src/emu/xtal.cpp index f5944a6af8f..e687f09d74d 100644 --- a/src/emu/xtal.cpp +++ b/src/emu/xtal.cpp @@ -105,6 +105,7 @@ const double XTAL::known_xtals[] = { 5'000'000, /* 5_MHz_XTAL Mutant Night */ 5'068'800, /* 5.0688_MHz_XTAL Usually used as MC2661 or COM8116 baud rate clock */ 5'185'000, /* 5.185_MHz_XTAL Intel INTELLEC® 4 */ + 5'370'000, /* 5.37_MHz_XTAL HP 95LX */ 5'460'000, /* 5.46_MHz_XTAL ec1840 and ec1841 keyboard */ 5'529'600, /* 5.5296_MHz_XTAL Kontron PSI98 keyboard */ 5'626'000, /* 5.626_MHz_XTAL RCA CDP1869 PAL dot clock */ diff --git a/src/mame/drivers/hp95lx.cpp b/src/mame/drivers/hp95lx.cpp new file mode 100644 index 00000000000..5a9bf6ac2b5 --- /dev/null +++ b/src/mame/drivers/hp95lx.cpp @@ -0,0 +1,771 @@ +// license:BSD-3-Clause +// copyright-holders:Sergey Svishchev +/*************************************************************************** + + Hewlett-Packard 95LX palmtop, code name Jaguar. + + NEC V20 CPU @ 5.37 MHz + HP F1000-80054 "Hopper" ASIC + Display controller + Keyboard controler + UART + Interrupt controller (8259 core) + Interval timer (8254 core) + Real time clock + PCMCIA 1.0 controller + ADC (4 channels; used to measure battery voltages) + DAC (1 channel; can be used as tone generator) + 512KB or 1MB of RAM + 1MB of BIOS ROM (banked) + P/N 18-5301 ABD \\ HN62318BFC26 + LCD, 240x128 pixels (40x16 chars in MDA-compatible text mode) + + To do: + - blue on green LCD palette + - native keyboard + - 1MB model + - identify RTC core + - everything else + + Technical info: + - http://web.archive.org/web/20071012040320/http://www.daniel-hertrich.de/download/95lx_devguide.zip + - http://cd.textfiles.com/blackphilesii/PHILES/HP95/HP95DEV.ZIP + + Useful links: + - https://hermocom.com/hplx/view-all-hp-palmtop-articles/41-95lx + - ftp://netflora.demon.co.uk/main/TEXT/hp95lxfaq.txt + - https://www.finseth.com/hpdata/hp95lx.php + has keyboard layout + - http://cfile3.uf.tistory.com/attach/152BF03E50054B2925840F + Explorer's Guide to the HP 95LX + - http://www.palmtoppaper.com/ptphtml/12/pt120055.htm + Evolution of the HP Palmtops + - http://web.archive.org/web/20150423014908/http://www.sp.uconn.edu/~mchem1/HPLX.shtml + HPLX-L mailing list archive + + Software: + - http://www.retroisle.com/others/hp95lx/software.php + - http://www.mizj.com/ + - http://www.hp200lx.net/ + - http://www.nic.funet.fi/index/misc/hp95lx/Index + - http://cd.textfiles.com/blackphilesii/PHILES/HP95/ + +***************************************************************************/ + + +#include "emu.h" + +#include "machine/nvram.h" +#include "machine/pic8259.h" +#include "machine/pit8253.h" +#include "bus/isa/isa.h" +#include "bus/isa/isa_cards.h" +#include "bus/pc_kbd/keyboards.h" +#include "bus/pc_kbd/pc_kbdc.h" +#include "cpu/nec/nec.h" +#include "machine/bankdev.h" +#include "machine/ram.h" + +#include "screen.h" +#include "emupal.h" +#include "softlist.h" + + +//#define LOG_GENERAL (1U << 0) //defined in logmacro.h already +#define LOG_KEYBOARD (1U << 1) +#define LOG_DEBUG (1U << 2) + +#define VERBOSE (LOG_DEBUG) +//#define LOG_OUTPUT_FUNC printf +#include "logmacro.h" + +#define LOGKBD(...) LOGMASKED(LOG_KEYBOARD, __VA_ARGS__) +#define LOGDBG(...) LOGMASKED(LOG_DEBUG, __VA_ARGS__) + +#define KBDC_TAG "pc_kbdc" + + +class hp95lx_state : public driver_device +{ +public: + hp95lx_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_bankdev_c000(*this, "bankdev_c000") + , m_bankdev_d000(*this, "bankdev_d000") + , m_bankdev_e000(*this, "bankdev_e000") + , m_bankdev_e400(*this, "bankdev_e400") + , m_bankdev_e800(*this, "bankdev_e800") + , m_bankdev_ec00(*this, "bankdev_ec00") + , m_ram(*this, RAM_TAG) + , m_nvram2(*this, "nvram2") + , m_nvram3(*this, "nvram3") + , m_isabus(*this, "isa") + , m_pic8259(*this, "pic8259") + , m_pit8254(*this, "pit8254") + , m_screen(*this, "screen") + , m_p_videoram(*this, "video") + , m_p_chargen(*this, "gfx1") + { } + + DECLARE_MACHINE_START(hp95lx); + DECLARE_MACHINE_RESET(hp95lx); + + DECLARE_WRITE8_MEMBER(d300_w); + DECLARE_READ8_MEMBER(d300_r); + DECLARE_WRITE8_MEMBER(e300_w); + DECLARE_READ8_MEMBER(e300_r); + DECLARE_WRITE8_MEMBER(f300_w); + DECLARE_READ8_MEMBER(f300_r); + + DECLARE_PALETTE_INIT(hp95lx); + void hp95lx(machine_config &config); + void hp95lx_io(address_map &map); + void hp95lx_map(address_map &map); + void hp95lx_romdos(address_map &map); + +protected: + required_device m_maincpu; + required_device m_bankdev_c000; + required_device m_bankdev_d000; + required_device m_bankdev_e000; + required_device m_bankdev_e400; + required_device m_bankdev_e800; + required_device m_bankdev_ec00; + required_device m_ram; + required_device m_nvram2; + optional_device m_nvram3; + required_device m_isabus; + required_device m_pic8259; + required_device m_pit8254; + required_device m_screen; + +private: + DECLARE_WRITE_LINE_MEMBER(keyboard_clock_w); + DECLARE_WRITE_LINE_MEMBER(keyboard_data_w); + DECLARE_READ8_MEMBER(keyboard_r); + DECLARE_WRITE8_MEMBER(keyboard_w); + DECLARE_READ8_MEMBER(video_r); + DECLARE_WRITE8_MEMBER(video_w); + DECLARE_WRITE8_MEMBER(video_address_w); + DECLARE_READ8_MEMBER(video_register_r); + DECLARE_WRITE8_MEMBER(video_register_w); + DECLARE_WRITE8_MEMBER(debug_w); + + required_shared_ptr m_p_videoram; + required_region_ptr m_p_chargen; + + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + u8 m_mapper[32], m_rtcram[2]; + + // crtc + u8 m_crtc[64], m_cursor_start_ras; + u16 m_disp_start_addr, m_cursor_addr, m_window_start_addr; + int m_register_address_latch; + bool m_graphics_mode; + + // from pt68k4.cpp + bool m_kclk; + uint8_t m_kdata; + uint8_t m_scancode; + uint8_t m_kbdflag; + int m_kbit; +}; + + +PALETTE_INIT_MEMBER(hp95lx_state, hp95lx) +{ + palette.set_pen_color(0, 0xa0, 0xa8, 0xa0); + palette.set_pen_color(1, 0x30, 0x38, 0x10); +} + +uint32_t hp95lx_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + int x, y, offset; + uint16_t gfx, *p; + uint8_t chr, attr; + + if (m_graphics_mode) + { + for (y = 0; y < 128; y++) + { + p = &bitmap.pix16(y); + offset = y * (240 / 8); + + for (x = offset; x < offset + (240 / 8); x++) + { + gfx = m_p_videoram[x]; + + for (int i = 7; i >= 0; i--) + { + *p++ = BIT(gfx, i); + } + } + } + } + else + { + bool blink((m_screen->frame_number() % 10) > 4); + + // screen memory is normal MDA 80x25, but only a scrollable 40x16 window is displayed + for (y = 0; y < 128; y++) + { + p = &bitmap.pix16(y); + offset = (y / 8) * 160 + m_window_start_addr; + + for (x = offset; x < offset + 80; x += 2) + { + chr = m_p_videoram[x]; + attr = m_p_videoram[x + 1]; + + gfx = m_p_chargen[(chr)*8 + (y % 8)]; + + if ((x >> 1) == m_cursor_addr && blink && (y % 8) >= m_cursor_start_ras) + { + gfx = 0xff; + } + + switch (attr) + { + case 0x00: + gfx = 0; + break; + + case 0x01: + if (y % 8 == 7) gfx = 0xff; + break; + + case 0x70: + gfx ^= 0xff; + break; + } + + for (int i = 5; i >= 0; i--) + { + *p++ = BIT(gfx, i); + } + } + } + } + + return 0; +} + + +MACHINE_START_MEMBER(hp95lx_state, hp95lx) +{ + save_item(NAME(m_mapper)); + save_item(NAME(m_rtcram)); + save_item(NAME(m_crtc)); + save_item(NAME(m_graphics_mode)); + + // + save_item(NAME(m_kclk)); + save_item(NAME(m_kdata)); + save_item(NAME(m_scancode)); + save_item(NAME(m_kbdflag)); + save_item(NAME(m_kbit)); + + memcpy(m_p_chargen, memregion("romdos")->base() + 0xffa6e, 0x0400); + memcpy(m_p_chargen + 0x0400, memregion("romdos")->base() + 0xfb200, 0x0400); +} + +MACHINE_RESET_MEMBER(hp95lx_state, hp95lx) +{ + std::fill(std::begin(m_mapper), std::end(m_mapper), 0); + std::fill(std::begin(m_rtcram), std::end(m_rtcram), 0); + + std::fill(std::begin(m_crtc), std::end(m_crtc), 0); + m_graphics_mode = false; + m_cursor_start_ras = 7; + m_disp_start_addr = 0; + m_cursor_addr = 0; + + m_kclk = true; + m_kbit = 0; + m_scancode = 0; + m_kbdflag = 0; +} + + +WRITE8_MEMBER(hp95lx_state::d300_w) +{ + LOG("%s: IO %04x <- %02x\n", machine().describe_context(), 0xd300 + offset, data); + + switch (offset) + { + case 0: + m_window_start_addr = ((data & 0xff) << 0) | (m_window_start_addr & 0xff00); + break; + case 1: + m_window_start_addr = ((data & 0x3f) << 8) | (m_window_start_addr & 0x00ff); + break; + + case 2: + m_graphics_mode = !BIT(data, 4); + break; + + case 6: + case 7: + m_rtcram[offset - 6] = data; + break; + } +} + +READ8_MEMBER(hp95lx_state::d300_r) +{ + uint8_t data = 0; + + switch (offset) + { + case 0: + data = m_window_start_addr; + break; + + case 1: + data = m_window_start_addr >> 8; + break; + + case 5: + data = 0x2; + break; + + case 6: + case 7: + data = m_rtcram[offset - 6]; + break; + } + + LOG("%s: IO %04x == %02x\n", machine().describe_context(), 0xd300 + offset, data); + + return data; +} + +WRITE8_MEMBER(hp95lx_state::e300_w) +{ + LOG("%s: IO %04x <- %02x\n", machine().describe_context(), 0xe300 + offset, data); + + switch (offset) + { + case 1: // b1 = 'IR interrupt enable' (per IR.DOC) + break; + + case 2: // interrupt control (per snd.c), 0: disable all, 127: enable all + break; + + case 5: // DAC out (per snd.c) + break; + + case 9: // b1 = 'a2d power' (per snd.c) + break; + + case 10: // IRFMAT register (per IR.DOC) + break; + + case 11: // IR transmit/receive register (per IR.DOC) + break; + + case 13: // reset? + break; + + case 14: // keyboard output? + case 15: + break; + } +} + +READ8_MEMBER(hp95lx_state::e300_r) +{ + uint8_t data = 0; + + switch (offset) + { + case 2: // b6 = low battery? (FD97Eh) + break; + + case 4: // Card Detect Register (per chap5.txt) + data = 0x50; // memory card inserted + break; + + case 7: + data = 0x20; + break; + + case 9: // FF889h. b0 = ADC ready? (per snd2.c) + break; + + case 10: // IRFMAT register (per IR.DOC) + break; + + case 11: // IR transmit/receive register (per IR.DOC) + break; + + case 14: // keyboard status? + case 15: + return data; + break; + } + + LOG("%s: IO %04x == %02x\n", machine().describe_context(), 0xe300 + offset, data); + + return data; +} + +WRITE8_MEMBER(hp95lx_state::f300_w) +{ + address_map_bank_device *mapper; + const char *mapname; + + LOG("%s: IO %04x <- %02x\n", machine().describe_context(), 0xf300 + offset, data); + + if (offset >= sizeof(m_mapper)) return; + + m_mapper[offset] = data; + + switch (offset) + { + case 0x11: // E0000 16K + mapper = m_bankdev_e000; + mapname = "E0000"; + break; + + case 0x13: // E4000 16K + mapper = m_bankdev_e400; + mapname = "E4000"; + break; + + case 0x15: // E8000 16K + mapper = m_bankdev_e800; + mapname = "E8000"; + break; + + case 0x17: // EC000 16K + mapper = m_bankdev_ec00; + mapname = "EC000"; + break; + + case 0x18: // C0000 64K + mapper = m_bankdev_c000; + mapname = "C0000"; + break; + + case 0x19: // D0000 64K + mapper = m_bankdev_d000; + mapname = "D0000"; + break; + } + + switch (offset) + { + case 0x11: case 0x13: case 0x15: case 0x17: + switch (data) + { + case 0: // internal + if (m_mapper[offset - 1]) + { + LOG("MAPPER %s <- %05X\n", mapname, (m_mapper[offset - 1] & 127) * 0x2000); + mapper->set_bank((m_mapper[offset - 1] >> 1) & 63); + } + break; + + case 1: // unknown + case 2: + break; + + case 4: // card slot + LOG("MAPPER %s <- %06X (card)\n", mapname, (m_mapper[offset - 1]) * 0x2000); + mapper->set_bank(0x1000 + (m_mapper[offset - 1] >> 1)); + break; + + case 7: // XXX unmap + LOG("MAPPER %s <- unmap\n", mapname); + mapper->set_bank(0x400); + break; + } + break; + + case 0x18: case 0x19: + switch (data & 7) + { + case 0: + if ((data & 0x87) == 0x80) + { + LOG("MAPPER %s <- %X0000\n", mapname, (data >> 3) & 15); + mapper->set_bank((data >> 3) & 15); + } + break; + + case 4: // XXX + break; + + case 7: // XXX unmap + LOG("MAPPER %s <- unmap\n", mapname); + mapper->set_bank(0x40); + break; + } + } +} + +READ8_MEMBER(hp95lx_state::f300_r) +{ + uint8_t data = 0; + + LOG("%s: IO %04x == %02x\n", machine().describe_context(), 0xf300 + offset, data); + + return data; +} + +/* keyboard HLE -- adapted from pt68k4.cpp */ + +READ8_MEMBER(hp95lx_state::keyboard_r) +{ + if (offset == 0) + { + LOGKBD("kbd: read %02X == %02X\n", offset + 0x60, m_scancode); + m_pic8259->ir1_w(CLEAR_LINE); + return m_scancode; + } + else + return 0; +} + +WRITE8_MEMBER(hp95lx_state::keyboard_w) +{ + LOGKBD("kbd: write %02X <= %02X\n", offset + 0x60, data); + m_pic8259->ir1_w(CLEAR_LINE); +} + +WRITE_LINE_MEMBER(hp95lx_state::keyboard_clock_w) +{ + LOGKBD("kbd: KCLK: %d kbit: %d\n", state ? 1 : 0, m_kbit); + + if ((state == ASSERT_LINE) && (!m_kclk)) + { + if (m_kbit >= 1 && m_kbit <= 8) + { + m_scancode >>= 1; + m_scancode |= m_kdata; + } + + // stop bit? + if (m_kbit == 9) + { + m_scancode >>= 1; + m_scancode |= m_kdata; + // XXX map F2..F10 to blue function keys + if (m_scancode > 0x3B && m_scancode < 0x45) m_scancode += 0x36; + LOGKBD("kbd: scancode %02x\n", m_scancode); + m_kbit = 0; + m_pic8259->ir1_w(ASSERT_LINE); + } + else + { + m_kbit++; + } + } + + m_kclk = (state == ASSERT_LINE) ? true : false; +} + +WRITE_LINE_MEMBER(hp95lx_state::keyboard_data_w) +{ + LOGKBD("kbd: KDATA: %d\n", state ? 1 : 0); + m_kdata = (state == ASSERT_LINE) ? 0x80 : 0x00; +} + +/* video HLE */ + +READ8_MEMBER(hp95lx_state::video_register_r) +{ + uint8_t ret = 0; + + switch (m_register_address_latch) + { + case 0x0e: + ret = (m_cursor_addr >> 8) & 0xff; + break; + + case 0x0f: + ret = (m_cursor_addr >> 0) & 0xff; + break; + + /* all other registers are write only and return 0 */ + default: + break; + } + + return ret; +} + +WRITE8_MEMBER(hp95lx_state::video_register_w) +{ + switch (m_register_address_latch) + { + case 0x0a: + m_cursor_start_ras = data & 0x7f; + break; + + case 0x0c: + m_disp_start_addr = ((data & 0x3f) << 8) | (m_disp_start_addr & 0x00ff); + break; + + case 0x0d: + m_disp_start_addr = ((data & 0xff) << 0) | (m_disp_start_addr & 0xff00); + break; + + case 0x0e: + m_cursor_addr = ((data & 0x3f) << 8) | (m_cursor_addr & 0x00ff); + break; + + case 0x0f: + m_cursor_addr = ((data & 0xff) << 0) | (m_cursor_addr & 0xff00); + m_pic8259->ir2_w(ASSERT_LINE); + break; + } +} + +WRITE8_MEMBER(hp95lx_state::video_address_w) +{ + m_register_address_latch = data & 0x3f; +} + +READ8_MEMBER(hp95lx_state::video_r) +{ + int data = 0xff; + + switch (offset) + { + case 1: case 3: case 5: case 7: + data = video_register_r(space, offset); + break; + + case 10: + data = 0xf0; // video_status_r(offset): + break; + } + + return data; +} + +WRITE8_MEMBER(hp95lx_state::video_w) +{ + switch (offset) + { + case 0: case 2: case 4: case 6: + video_address_w(space, offset, data); + break; + + case 1: case 3: case 5: case 7: + video_register_w(space, offset, data); + break; + } +} + +WRITE8_MEMBER(hp95lx_state::debug_w) +{ + LOGDBG("%11.6f %s debug: port %02X <= %02X\n", machine().time().as_double(), machine().describe_context(), offset + 0x90, data); +} + + +void hp95lx_state::hp95lx_romdos(address_map &map) +{ + map(0x0000000, 0x00fffff).rom().region("romdos", 0); + map(0x4000000, 0x41fffff).ram().share("nvram3"); +} + +void hp95lx_state::hp95lx_map(address_map &map) +{ + map.unmap_value_high(); + map(0x00000, 0x7ffff).ram().share("nvram2"); + map(0xa0000, 0xaffff).rom().region("romdos", 0xe0000); // OS functions (DOS, COMMAND.COM) + map(0xb0000, 0xb0fff).ram().share("video"); + map(0xc0000, 0xcffff).rw(m_bankdev_c000, FUNC(address_map_bank_device::read8), FUNC(address_map_bank_device::write8)); + map(0xd0000, 0xdffff).rw(m_bankdev_d000, FUNC(address_map_bank_device::read8), FUNC(address_map_bank_device::write8)); + map(0xe0000, 0xe3fff).rw(m_bankdev_e000, FUNC(address_map_bank_device::read8), FUNC(address_map_bank_device::write8)); + map(0xe4000, 0xe7fff).rw(m_bankdev_e400, FUNC(address_map_bank_device::read8), FUNC(address_map_bank_device::write8)); + map(0xe8000, 0xebfff).rw(m_bankdev_e800, FUNC(address_map_bank_device::read8), FUNC(address_map_bank_device::write8)); + map(0xec000, 0xeffff).rw(m_bankdev_ec00, FUNC(address_map_bank_device::read8), FUNC(address_map_bank_device::write8)); + map(0xf0000, 0xfffff).rom().region("romdos", 0xf0000); // BIOS ROM and SysMgr +} + +void hp95lx_state::hp95lx_io(address_map &map) +{ + map.unmap_value_low(); + map(0x0020, 0x002f).rw("pic8259", FUNC(pic8259_device::read), FUNC(pic8259_device::write)); + map(0x0040, 0x004f).rw("pit8254", FUNC(pit8254_device::read), FUNC(pit8254_device::write)); + map(0x0060, 0x0063).rw(FUNC(hp95lx_state::keyboard_r), FUNC(hp95lx_state::keyboard_w)); +// map(0x0090, 0x009f).w(FUNC(hp95lx_state::debug_w)); + map(0x03b0, 0x03bf).rw(FUNC(hp95lx_state::video_r), FUNC(hp95lx_state::video_w)); +// map(0x0070, 0x007f) RTC + map(0xd300, 0xd30f).rw(FUNC(hp95lx_state::d300_r), FUNC(hp95lx_state::d300_w)); + map(0xe300, 0xe30f).rw(FUNC(hp95lx_state::e300_r), FUNC(hp95lx_state::e300_w)); + map(0xf300, 0xf31f).rw(FUNC(hp95lx_state::f300_r), FUNC(hp95lx_state::f300_w)); +} + + +MACHINE_CONFIG_START(hp95lx_state::hp95lx) + MCFG_DEVICE_ADD("maincpu", V20, XTAL(5'370'000)) + MCFG_DEVICE_PROGRAM_MAP(hp95lx_map) + MCFG_DEVICE_IO_MAP(hp95lx_io) + MCFG_DEVICE_IRQ_ACKNOWLEDGE_DEVICE("pic8259", pic8259_device, inta_cb) + + MCFG_MACHINE_START_OVERRIDE(hp95lx_state, hp95lx) + MCFG_MACHINE_RESET_OVERRIDE(hp95lx_state, hp95lx) + + ADDRESS_MAP_BANK(config, "bankdev_c000").set_map(&hp95lx_state::hp95lx_romdos).set_options(ENDIANNESS_LITTLE, 8, 32, 0x10000); + ADDRESS_MAP_BANK(config, "bankdev_d000").set_map(&hp95lx_state::hp95lx_romdos).set_options(ENDIANNESS_LITTLE, 8, 32, 0x10000); + ADDRESS_MAP_BANK(config, "bankdev_e000").set_map(&hp95lx_state::hp95lx_romdos).set_options(ENDIANNESS_LITTLE, 8, 32, 0x4000); + ADDRESS_MAP_BANK(config, "bankdev_e400").set_map(&hp95lx_state::hp95lx_romdos).set_options(ENDIANNESS_LITTLE, 8, 32, 0x4000); + ADDRESS_MAP_BANK(config, "bankdev_e800").set_map(&hp95lx_state::hp95lx_romdos).set_options(ENDIANNESS_LITTLE, 8, 32, 0x4000); + ADDRESS_MAP_BANK(config, "bankdev_ec00").set_map(&hp95lx_state::hp95lx_romdos).set_options(ENDIANNESS_LITTLE, 8, 32, 0x4000); + + PIT8254(config, m_pit8254, 0); + m_pit8254->set_clk<0>(XTAL(14'318'181)/12); /* heartbeat IRQ */ + m_pit8254->out_handler<0>().set(m_pic8259, FUNC(pic8259_device::ir0_w)); + m_pit8254->set_clk<1>(XTAL(14'318'181)/12); /* misc IRQ */ + m_pit8254->out_handler<1>().set(m_pic8259, FUNC(pic8259_device::ir2_w)); + + PIC8259(config, m_pic8259, 0); + m_pic8259->out_int_callback().set_inputline(m_maincpu, 0); + + MCFG_MACHINE_RESET_OVERRIDE(hp95lx_state, hp95lx) + + ISA8(config, m_isabus, 0); + m_isabus->set_cputag("maincpu"); + + MCFG_DEVICE_ADD("board0", ISA8_SLOT, 0, "isa", pc_isa8_cards, "com", true) + + MCFG_DEVICE_ADD(KBDC_TAG, PC_KBDC, 0) + MCFG_PC_KBDC_OUT_CLOCK_CB(WRITELINE(*this, hp95lx_state, keyboard_clock_w)) + MCFG_PC_KBDC_OUT_DATA_CB(WRITELINE(*this, hp95lx_state, keyboard_data_w)) + MCFG_PC_KBDC_SLOT_ADD(KBDC_TAG, "kbd", pc_xt_keyboards, STR_KBD_KEYTRONIC_PC3270) + + NVRAM(config, "nvram2", nvram_device::DEFAULT_ALL_0); // RAM + NVRAM(config, "nvram3", nvram_device::DEFAULT_ALL_0); // card slot + + // XXX When the AC adapter is plugged in, the LCD refresh rate is 73.14 Hz. + // XXX When the AC adapter is not plugged in (ie, running off of batteries) the refresh rate is 56.8 Hz. + MCFG_SCREEN_ADD_MONOCHROME("screen", LCD, rgb_t::white()) + MCFG_SCREEN_UPDATE_DRIVER(hp95lx_state, screen_update) + MCFG_SCREEN_RAW_PARAMS(XTAL(5'370'000) / 2, 300, 0, 240, 180, 0, 128) + + MCFG_SCREEN_PALETTE("palette") + MCFG_PALETTE_ADD("palette", 2) + MCFG_PALETTE_INIT_OWNER(hp95lx_state, hp95lx) + + RAM(config, RAM_TAG).set_default_size("512K"); +MACHINE_CONFIG_END + + +ROM_START( hp95lx ) + ROM_REGION16_LE(0x100000, "romdos", 0) + // Version A ... ROM BIOS Ver 2.14 ... 04/02/91 + ROM_LOAD("18-5301.abd.bin", 0, 0x100000, CRC(18121c48) SHA1(c3bfb45cbbf4f57ae67fb5659da40f371d8e5c54)) + + ROM_REGION(0x800,"gfx1", ROMREGION_ERASE00) +ROM_END + + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1991, hp95lx, 0, 0, hp95lx, 0, hp95lx_state, empty_init, "Hewlett-Packard", "HP 95LX", MACHINE_NOT_WORKING|MACHINE_NO_SOUND ) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index c456efe20da..329fcc07029 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -15343,6 +15343,9 @@ hp64k // hp700_70 // hp700_92 // +@source:hp95lx.cpp +hp95lx // + @source:hp9825.cpp hp9825b // HP 9825B diff --git a/src/mame/mess.flt b/src/mame/mess.flt index bff6c2a0f4f..e46bd83d48c 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -297,6 +297,7 @@ hp48.cpp hp49gp.cpp hp64k.cpp hp700.cpp +hp95lx.cpp hp9825.cpp hp9845.cpp hp9k.cpp -- cgit v1.2.3