diff --git a/src/devices/cpu/hphybrid/hphybrid.cpp b/src/devices/cpu/hphybrid/hphybrid.cpp index 246804ec468..cad5e86d801 100644 --- a/src/devices/cpu/hphybrid/hphybrid.cpp +++ b/src/devices/cpu/hphybrid/hphybrid.cpp @@ -175,6 +175,8 @@ uint8_t hp_hybrid_cpu_device::pa_r() const hp_hybrid_cpu_device::hp_hybrid_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t addrwidth) : cpu_device(mconfig, type, tag, owner, clock) , m_pa_changed_func(*this) + , m_opcode_func(*this) + , m_stm_func(*this) , m_addr_mask((1U << addrwidth) - 1) , m_relative_mode(true) , m_r_cycles(DEF_MEM_R_CYCLES) @@ -241,6 +243,11 @@ void hp_hybrid_cpu_device::device_start() set_icountptr(m_icount); m_pa_changed_func.resolve_safe(); + m_opcode_func.resolve(); + m_stm_func.resolve(); + // Cache active state of m_stm_func & m_opcode_func + m_opcode_func_defd = bool(m_opcode_func); + m_stm_func_defd = bool(m_stm_func); } void hp_hybrid_cpu_device::device_reset() @@ -260,6 +267,7 @@ void hp_hybrid_cpu_device::device_reset() m_dmapa = 0; m_dmama = 0; m_dmac = 0; + m_curr_cycle = 0; m_forced_bsc_25 = m_boot_mode; m_last_pa = ~0; @@ -312,7 +320,7 @@ uint16_t hp_hybrid_cpu_device::execute_one(uint16_t opcode) } // Indirect addressing in EXE instruction seems to use AEC case A instead of case C // (because it's an opcode fetch) - return RM(add_mae(AEC_CASE_A , fetch_addr)); + return fetch_at(add_mae(AEC_CASE_A , fetch_addr)); } else { uint16_t next_P; if (!execute_one_bpc(opcode , next_P) && @@ -952,6 +960,11 @@ uint16_t hp_hybrid_cpu_device::RM(uint32_t addr) // Any access to internal registers removes forcing of BSC 2x m_forced_bsc_25 = false; + if (m_stm_func_defd) { + m_stm_func(m_curr_cycle | CYCLE_RAL_MASK | CYCLE_RD_MASK); + m_curr_cycle = 0; + } + // Memory mapped BPC registers uint16_t tmp; switch (addr_wo_bsc) { @@ -1016,6 +1029,10 @@ uint16_t hp_hybrid_cpu_device::RM(uint32_t addr) return tmp; } else { m_icount -= m_r_cycles; + if (m_stm_func_defd) { + m_stm_func(m_curr_cycle | CYCLE_RD_MASK); + m_curr_cycle = 0; + } return m_cache->read_word(addr); } } @@ -1065,6 +1082,11 @@ void hp_hybrid_cpu_device::WM(uint32_t addr , uint16_t v) // Any access to internal registers removes forcing of BSC 2x m_forced_bsc_25 = false; + if (m_stm_func_defd) { + m_stm_func(m_curr_cycle | CYCLE_RAL_MASK | CYCLE_WR_MASK); + m_curr_cycle = 0; + } + // Memory mapped BPC registers switch (addr_wo_bsc) { case HP_REG_A_ADDR: @@ -1130,6 +1152,10 @@ void hp_hybrid_cpu_device::WM(uint32_t addr , uint16_t v) m_icount -= REGISTER_RW_CYCLES; } else { m_icount -= m_w_cycles; + if (m_stm_func_defd) { + m_stm_func(m_curr_cycle | CYCLE_WR_MASK); + m_curr_cycle = 0; + } m_program->write_word(addr , v); } } @@ -1168,7 +1194,17 @@ bool hp_hybrid_cpu_device::write_emc_reg(uint16_t addr , uint16_t v) uint16_t hp_hybrid_cpu_device::fetch() { m_genpc = add_mae(AEC_CASE_A , m_reg_P); - return RM(m_genpc); + return fetch_at(m_genpc); +} + +uint16_t hp_hybrid_cpu_device::fetch_at(uint32_t addr) +{ + m_curr_cycle |= CYCLE_IFETCH_MASK; + uint16_t opcode = RM(addr); + if (m_opcode_func_defd) { + m_opcode_func(opcode); + } + return opcode; } uint16_t hp_hybrid_cpu_device::get_indirect_target(uint32_t addr) @@ -1586,6 +1622,10 @@ bool hp_5061_3011_cpu_device::execute_no_bpc(uint16_t opcode , uint16_t& next_pc // 16 bits units. WM(tmp_addr >> 1 , tmp); } else { + if (m_stm_func_defd) { + m_stm_func(m_curr_cycle | CYCLE_WR_MASK); + m_curr_cycle = 0; + } // Extend address, form byte address uint16_t mask = BIT(tmp_addr , 0) ? 0x00ff : 0xff00; tmp_addr = add_mae(AEC_CASE_C , tmp_addr >> 1); @@ -1674,6 +1714,7 @@ void hp_5061_3011_cpu_device::handle_dma() bool tc = BIT(--m_dmac , 15) != 0; uint16_t tmp; + m_curr_cycle |= CYCLE_DMA_MASK; // Timing here assumes that DMA transfers are isolated and not done in bursts if (BIT(m_flags , HPHYBRID_DMADIR_BIT)) { // "Outward" DMA: memory -> peripheral @@ -1955,6 +1996,10 @@ bool hp_09825_67907_cpu_device::execute_no_bpc(uint16_t opcode , uint16_t& next_ // 16 bits units. WM(tmp_addr , tmp); } else { + if (m_stm_func_defd) { + m_stm_func(m_curr_cycle | CYCLE_WR_MASK); + m_curr_cycle = 0; + } uint16_t mask = BIT(*ptr_reg , 15) ? 0xff00 : 0x00ff; m_program->write_word(tmp_addr , tmp , mask); m_icount -= m_w_cycles; @@ -2037,6 +2082,7 @@ void hp_09825_67907_cpu_device::handle_dma() uint16_t tmp; // Timing here assumes that DMA transfers are isolated and not done in bursts + m_curr_cycle |= CYCLE_DMA_MASK; if (BIT(m_dmama , 15)) { // "Outward" DMA: memory -> peripheral tmp = RM(AEC_CASE_D , m_dmama); diff --git a/src/devices/cpu/hphybrid/hphybrid.h b/src/devices/cpu/hphybrid/hphybrid.h index 5d29f77b515..71ab4ead350 100644 --- a/src/devices/cpu/hphybrid/hphybrid.h +++ b/src/devices/cpu/hphybrid/hphybrid.h @@ -64,6 +64,29 @@ public: void set_relative_mode(bool rela) { m_relative_mode = rela; } void set_rw_cycles(unsigned read_cycles , unsigned write_cycles) { m_r_cycles = read_cycles; m_w_cycles = write_cycles; } + // Possible combinations: + // 00 No r/w cycle in progress + // 01 Non-ifetch rd cycle + // 05 Ifetch rd cycle + // 09 DMA rd cycle + // 02 Wr cycle + // 0a DMA wr cycle + // + // CYCLE_RAL_MASK is set when access is into register space [0..1f] + enum : uint8_t { + CYCLE_RD_MASK = 0x01, + CYCLE_WR_MASK = 0x02, + CYCLE_IFETCH_MASK = 0x04, + CYCLE_DMA_MASK = 0x08, + CYCLE_RAL_MASK = 0x10 + }; + + // Called at start of each memory access + auto stm_cb() { return m_stm_func.bind(); } + + // Tap into fetched opcodes + auto opcode_cb() { return m_opcode_func.bind(); } + protected: hp_hybrid_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t addrwidth); @@ -123,6 +146,7 @@ protected: void WIO(uint8_t pa , uint8_t ic , uint16_t v); uint16_t fetch(); + uint16_t fetch_at(uint32_t addr); virtual uint16_t get_indirect_target(uint32_t addr); virtual void enter_isr(); virtual void handle_dma() = 0; @@ -133,6 +157,10 @@ protected: devcb_write8 m_pa_changed_func; uint8_t m_last_pa; + bool m_opcode_func_defd; + devcb_write16 m_opcode_func; + bool m_stm_func_defd; + devcb_write8 m_stm_func; int m_icount; uint32_t m_addr_mask; @@ -159,6 +187,8 @@ protected: uint16_t m_dmac; // DMA counter uint16_t m_reg_I; // Instruction register uint32_t m_genpc; // Full PC + uint8_t m_curr_cycle; // Current cycle type + // EMC registers uint16_t m_reg_ar2[ 4 ]; // AR2 register uint16_t m_reg_se; // SE register (4 bits) diff --git a/src/mame/drivers/hp9825.cpp b/src/mame/drivers/hp9825.cpp index ee1aaaade3e..53a180be86b 100644 --- a/src/mame/drivers/hp9825.cpp +++ b/src/mame/drivers/hp9825.cpp @@ -8,8 +8,8 @@ // **** Temporary header, will hopefully evolve into proper doc **** // // What's in: -// - Emulation of 9825B system -// - 12 kw of RAMs +// - Emulation of 9825B and 9825T systems +// - 12 kw (9825B) or 31kw (9825T) of RAM // - 12 kw of system ROM // - Keyboard (SHIFT LOCK & RESET not implemented) // - Display & run light @@ -18,6 +18,8 @@ // - Beeper // - Internal expansion ROMs // - I/O expansion slots: 98032, 98034 & 98035 modules can be connected +// - For 9825T: the so-called SKOAL mechanism that transparently overlays RAM & ROM +// in the same address space // What's not yet in: // - External expansion ROMs // - Configurable RAM size @@ -27,8 +29,11 @@ // by re-assembling the source code (this is the reason why it's marked as // a BAD_DUMP). And thanks to Ansgar Kueckes for adapting his assembler to // handle HP9825 source files. +// For what regards the 9825T, I'd like to thank again Dyke Shaffer for +// publishing a lot of internal HP docs about the SKOAL card. I recovered the +// content of SKOAL ROM from its printed & scanned dump. // -// 9825A & 9825T can also be emulated. At the moment I haven't all the necessary +// 9825A can also be emulated. At the moment I haven't all the necessary // ROM dumps, though. #include "emu.h" @@ -42,6 +47,10 @@ #include "sound/beep.h" #include "hp9825.lh" +// Debugging +#define VERBOSE 0 +#include "logmacro.h" + // CPU clock (generated by a trimmered RC oscillator) constexpr unsigned MAIN_CLOCK = 6000000; @@ -81,6 +90,9 @@ namespace { } } +// +--------------+ +// | hp9825_state | +// +--------------+ class hp9825_state : public driver_device { public: @@ -103,15 +115,16 @@ public: { } - void hp9825b(machine_config &config); + void hp9825_base(machine_config &config); protected: virtual void machine_start() override; virtual void device_reset() override; virtual void machine_reset() override; -private: required_device m_cpu; + +private: required_device m_io_sys; required_device m_cursor_timer; required_device m_tape; @@ -144,7 +157,6 @@ private: int m_slot_sc[ 3 ]; void cpu_io_map(address_map &map); - void cpu_mem_map(address_map &map); DECLARE_READ16_MEMBER(kb_scancode_r); DECLARE_WRITE16_MEMBER(disp_w); @@ -228,16 +240,6 @@ void hp9825_state::cpu_io_map(address_map &map) // TODO: } -void hp9825_state::cpu_mem_map(address_map &map) -{ - map.unmap_value_low(); - // map(0x0000 , 0x2fff).rom(); - // map(0x3400 , 0x3bff).rom(); - map(0x0000 , 0x3bff).rom(); - map(0x4000 , 0x4fff).rom(); - map(0x5000 , 0x7fff).ram(); -} - READ16_MEMBER(hp9825_state::kb_scancode_r) { uint8_t res = m_scancode; @@ -620,12 +622,11 @@ void hp9825_state::set_dmar_slot(unsigned slot , int state) m_io_sys->set_dmar(uint8_t(sc) , state); } -MACHINE_CONFIG_START(hp9825_state::hp9825b) +MACHINE_CONFIG_START(hp9825_state::hp9825_base) 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_PROGRAM , &hp9825_state::cpu_mem_map); m_cpu->set_addrmap(AS_IO , &hp9825_state::cpu_io_map); m_cpu->set_irq_acknowledge_callback("io_sys" , FUNC(hp98x5_io_sys_device::irq_callback)); m_cpu->pa_changed_cb().set(m_io_sys , FUNC(hp98x5_io_sys_device::pa_w)); @@ -826,6 +827,251 @@ static INPUT_PORTS_START(hp9825) PORT_BIT(IOP_MASK(0) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) // Shift INPUT_PORTS_END +// +---------------+ +// | hp9825b_state | +// +---------------+ +class hp9825b_state : public hp9825_state +{ +public: + hp9825b_state(const machine_config &mconfig, device_type type, const char *tag) + : hp9825_state(mconfig , type , tag) + { + } + + void hp9825b(machine_config &config); + +private: + void cpu_mem_map(address_map &map); +}; + +MACHINE_CONFIG_START(hp9825b_state::hp9825b) + hp9825_base(config); + m_cpu->set_addrmap(AS_PROGRAM , &hp9825b_state::cpu_mem_map); +MACHINE_CONFIG_END + +void hp9825b_state::cpu_mem_map(address_map &map) +{ + map.unmap_value_low(); + map(0x0000 , 0x3bff).rom(); + map(0x4000 , 0x4fff).rom(); + map(0x5000 , 0x7fff).ram(); +} + +// +---------------+ +// | hp9825t_state | +// +---------------+ +class hp9825t_state : public hp9825_state +{ +public: + hp9825t_state(const machine_config &mconfig, device_type type, const char *tag) + : hp9825_state(mconfig , type , tag) + , m_rom_region(*this , "rom") + , m_skoalrom(*this , "skoalrom") + { + } + + void hp9825t(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void device_reset() override; + +private: + required_memory_region m_rom_region; + required_memory_region m_skoalrom; + std::unique_ptr m_ram; + + uint8_t m_cycle_type; + + // SKOAL state + bool m_skoalbit; // U53 + bool m_second_access; // U57-3 + bool m_mref; // U57-4 + bool m_ifetch_4400; // U57-5 + uint8_t m_special_opt; // U42 + uint16_t m_fetch_addr; + + void cpu_mem_map(address_map &map); + DECLARE_READ16_MEMBER(cpu_mem_r); + DECLARE_WRITE16_MEMBER(cpu_mem_w); + void stm(uint8_t cycle_type); + void on_cycle_end(); + void opcode_fetch(uint16_t opcode); + uint8_t get_skoalrom(uint16_t addr); + bool is_rom(uint16_t addr , uint8_t cycle_type) const; +}; + +MACHINE_CONFIG_START(hp9825t_state::hp9825t) + hp9825_base(config); + m_cpu->set_addrmap(AS_PROGRAM , &hp9825t_state::cpu_mem_map); + m_cpu->stm_cb().set(FUNC(hp9825t_state::stm)); + m_cpu->opcode_cb().set(FUNC(hp9825t_state::opcode_fetch)); +MACHINE_CONFIG_END + +void hp9825t_state::machine_start() +{ + hp9825_state::machine_start(); + + // 32kw of RAM (the 1st kw is not accessible in normal operation) + m_ram = std::make_unique(32768); + save_pointer(NAME(m_ram) , 32768); +} + +void hp9825t_state::device_reset() +{ + hp9825_state::device_reset(); + + // This has to be done before CPU reset or first instruction won't be fetched correctly + m_cycle_type = 0; + m_special_opt = 0xf; +} + +void hp9825t_state::cpu_mem_map(address_map &map) +{ + map.unmap_value_low(); + map(0x0000 , 0x7fff).rw(FUNC(hp9825t_state::cpu_mem_r) , FUNC(hp9825t_state::cpu_mem_w)); +} + +READ16_MEMBER(hp9825t_state::cpu_mem_r) +{ + bool from_rom; + + if (m_cycle_type & hp_hybrid_cpu_device::CYCLE_RD_MASK) { + if (m_cycle_type & hp_hybrid_cpu_device::CYCLE_IFETCH_MASK) { + m_fetch_addr = offset; + } + from_rom = is_rom(offset , m_cycle_type); + LOG("rd @%04x CYC=%x %d%d%d%d ROM=%d\n" , offset , m_cycle_type , m_skoalbit , m_second_access , m_mref , m_ifetch_4400 , from_rom); + if (!(m_cycle_type & (hp_hybrid_cpu_device::CYCLE_IFETCH_MASK | hp_hybrid_cpu_device::CYCLE_DMA_MASK))) { + on_cycle_end(); + } + m_cycle_type = 0; + // TODO: diagnostic read + } else { + // Read coming from debugger and not from CPU: fake an ifetch + from_rom = is_rom(offset , hp_hybrid_cpu_device::CYCLE_IFETCH_MASK); + } + + return from_rom ? m_rom_region->as_u16(offset) : m_ram[ offset ]; +} + +WRITE16_MEMBER(hp9825t_state::cpu_mem_w) +{ + if (m_cycle_type & hp_hybrid_cpu_device::CYCLE_WR_MASK) { + if (!(m_cycle_type & hp_hybrid_cpu_device::CYCLE_DMA_MASK)) { + on_cycle_end(); + } + m_cycle_type = 0; + } + // All write cycles go to RAM + m_ram[ offset ] = (m_ram[ offset ] & ~mem_mask) | (data & mem_mask); +} + +void hp9825t_state::stm(uint8_t cycle_type) +{ + LOG("stm %x\n" , cycle_type); + m_cycle_type = cycle_type; + if (m_cycle_type & hp_hybrid_cpu_device::CYCLE_IFETCH_MASK) { + m_second_access = false; + m_mref = false; + m_ifetch_4400 = false; + // In case of ifetch from register area this is kept at 0 (because cpu_mem_r is not called) + // In case of ifetch from RAM/ROM this is set by cpu_mem_r to the fetch address + m_fetch_addr = 0; + } else if (m_cycle_type & hp_hybrid_cpu_device::CYCLE_RAL_MASK) { + if (!(m_cycle_type & hp_hybrid_cpu_device::CYCLE_DMA_MASK)) { + on_cycle_end(); + } + m_cycle_type = 0; + } +} + +void hp9825t_state::on_cycle_end() +{ + m_second_access = false; +} + +void hp9825t_state::opcode_fetch(uint16_t opcode) +{ + LOG("oc %04x\n" , opcode); + m_cycle_type = 0; + // memory referencing instructions + m_mref = (opcode & 0x7000) != 0x7000; + m_second_access = true; + m_ifetch_4400 = (m_fetch_addr & 0x7f00) == 0x0900; + if (BIT(m_special_opt , 3) && BIT(m_special_opt , 2)) { + // Set SKOAL bit + if (m_fetch_addr < 0x20) { + // Fetch from registers -> SKOAL bit = 0 + m_skoalbit = false; + } else if ((m_fetch_addr & 0x6000) == 0x6000) { + // Fetch in [6000..7fff] range -> SKOAL bit = 0 + m_skoalbit = false; + } else { + uint8_t tmp = get_skoalrom(m_fetch_addr); + m_skoalbit = (tmp >> ((~m_fetch_addr >> 12) & 7)) & 1; + } + } + // Decode SKOAL instructions. They are ignored by the hybrid processor + // as they are not recognized. + if ((opcode & 0xffc0) == 0x7040) { + m_special_opt = opcode & 0xf; + if (!BIT(m_special_opt , 3)) { + // RAM/ == 0 + m_skoalbit = false; + } else if (!BIT(m_special_opt , 2)) { + // ROM/ == 0 + m_skoalbit = true; + } + } +} + +uint8_t hp9825t_state::get_skoalrom(uint16_t addr) +{ + return m_skoalrom->as_u8(~addr & 0x0fff); +} + +bool hp9825t_state::is_rom(uint16_t addr , uint8_t cycle_type) const +{ + if ((addr & 0x6000) == 0x6000) { + // [6000..7fff] -> always RAM + return false; + } else if ((cycle_type & hp_hybrid_cpu_device::CYCLE_DMA_MASK) != 0 || + !BIT(m_special_opt , 1)) { + // DMA cycle or BIT/ == 0 -> RAM + return false; + } else if (addr >= 0x400 && !BIT(m_special_opt , 0)) { + // [0400..5fff] and BIN/ == 0 -> RAM + return false; + } else { + bool addr_0800_7fff = (addr & 0x7800) != 0; + bool addr_0400_07ff = !addr_0800_7fff && BIT(addr , 10); + bool addr_0000_03ff = !addr_0800_7fff && !BIT(addr , 10); + + // U58-6 + bool force_rom; + + // ROM when one or more of these is true: + // - addr in [0000..03ff] + // - Ifetch cycle and addr in [0800..5fff] + // - 2nd access of a memory-referencing instruction not in [0400..07ff] range + // - skoalbit = 1 and instruction fetched in [0900..09ff] range + force_rom = + addr_0000_03ff || + ((cycle_type & hp_hybrid_cpu_device::CYCLE_IFETCH_MASK) != 0 && addr_0800_7fff) || + (m_second_access && m_mref && (!BIT(m_special_opt , 2) || !addr_0400_07ff)) || + (m_skoalbit && m_ifetch_4400); + + if (force_rom) { + return true; + } else if (addr_0400_07ff && BIT(m_special_opt , 2)) { + return false; + } else { + return m_skoalbit; + } + } +} + ROM_START(hp9825b) ROM_REGION(0xa000 , "cpu" , ROMREGION_16BIT | ROMREGION_BE) ROM_LOAD("sysrom1.bin" , 0x0000 , 0x2000 , CRC(fe429268) SHA1(f2fe7c5abca92bd13f81b4385fc4fce0cafb0da0)) @@ -839,5 +1085,23 @@ ROM_START(hp9825b) ROM_LOAD("strings_t.bin",0x9800 , 0x0800 , CRC(b5ca5da5) SHA1(af13abb3c15836c566863c656e1659f7e6f96d04)) ROM_END +ROM_START(hp9825t) + ROM_REGION(0xc000 , "rom" , ROMREGION_16BIT | ROMREGION_BE | ROMREGION_ERASE | ROMREGION_ERASE00) + ROM_LOAD("sysrom1.bin" , 0x0000 , 0x2000 , CRC(fe429268) SHA1(f2fe7c5abca92bd13f81b4385fc4fce0cafb0da0)) + ROM_LOAD("sysrom2.bin" , 0x2000 , 0x2000 , CRC(96093b5d) SHA1(c6ec4cafd019887df0fa849b3c7070bb74faee54)) + ROM_LOAD("sysrom3.bin" , 0x4000 , 0x2000 , CRC(f9470f67) SHA1(b80cb4a366d93bd7acc3508ce987bb11c5986b2a)) + ROM_LOAD("98217.bin" , 0x6000 , 0x0800 , BAD_DUMP CRC(ea1fcf63) SHA1(e535c82897210a1c67c1ca16f44f936d4c470463)) + ROM_LOAD("genio_t.bin" , 0x6800 , 0x0800 , CRC(ade1d1ed) SHA1(9af74a65b29ef1885f74164238ecf8d16ac995d6)) + ROM_LOAD("plot72.bin" , 0x7000 , 0x0800 , CRC(0a9cb8db) SHA1(d0d126fca108f2715e1e408cb31b09ba69385ac4)) + ROM_LOAD("advpgm_t.bin", 0x8000 , 0x0800 , CRC(965b5e5a) SHA1(ff44dd15f8fa4ca03dfd970ed8b200e8a071ec13)) + ROM_LOAD("extio_t.bin" , 0x8800 , 0x1000 , CRC(a708b978) SHA1(baf53c8a2b24d059f95252baf1452188eaf6e4be)) + ROM_LOAD("strings_t.bin",0x9800 , 0x0800 , CRC(b5ca5da5) SHA1(af13abb3c15836c566863c656e1659f7e6f96d04)) + ROM_LOAD("syspgm.bin" , 0xa000 , 0x0800 , CRC(8915588f) SHA1(037f497b5ecc3216fb6b8356767cc361fb0b2945)) + + ROM_REGION(0x1000 , "skoalrom" , 0) + ROM_LOAD("skoalrom.bin" , 0 , 0x1000 , CRC(5e8124d5) SHA1(dedf7f8a10c62b444f04213956083089e97bf219)) +ROM_END + // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP(1980, hp9825b, 0, 0, hp9825b, hp9825, hp9825_state, empty_init, "Hewlett-Packard", "HP 9825B", 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) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index c74bcb43f17..b8f3dcf9ee0 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -15426,6 +15426,7 @@ hp95lx // @source:hp9825.cpp hp9825b // HP 9825B +hp9825t // HP 9825T @source:hp9845.cpp hp9835a //